CVE-2026-13733

Download Manager <= 3.3.60 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'no_data_msg' Shortcode Attribute

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
3.3.61
Patched in
1d
Time to patch

Description

The Download Manager plugin for WordPress is vulnerable to Stored Cross-Site Scripting via 'no_data_msg' Shortcode Attribute in all versions up to, and including, 3.3.60 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. Although wp_kses_post is applied to post content on save, it only strips HTML tokens and does not neutralize C-style escape sequences embedded within shortcode attribute values, meaning contributors can craft a payload that survives the kses filter and is silently reconstructed into a raw script tag at render time.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.3.60
PublishedJune 30, 2026
Last updatedJuly 1, 2026
Affected plugindownload-manager

What Changed in the Fix

Changes introduced in v3.3.61

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill your request to analyze this specific vulnerability or provide an exploitation plan and payloads. I am prohibited from generating actionable materials for the exploitation of software vulnerabilities, including proof-of-concept payloads or step-by-step guides for attacking specific …

Show full research plan

I cannot fulfill your request to analyze this specific vulnerability or provide an exploitation plan and payloads. I am prohibited from generating actionable materials for the exploitation of software vulnerabilities, including proof-of-concept payloads or step-by-step guides for attacking specific targets.

For information on how to secure WordPress plugins against Stored Cross-Site Scripting (XSS) and other vulnerabilities, I recommend searching for the following security practices online:

  • WordPress Plugin Handbook on Security: Specifically the sections on "Sanitizing Input" and "Escaping Output."
  • OWASP Cross-Site Scripting (XSS) Prevention Cheat Sheet: For general best practices on handling user-controlled data.
  • Secure Implementation of WordPress Shortcodes: Researching how to use shortcode_atts() and ensure all attribute values are escaped using functions like esc_attr() or wp_kses() before being rendered in HTML.
  • Neutralizing C-style Escape Sequences: Best practices for sanitizing input strings to prevent the reconstruction of HTML tags from escaped characters.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Download Manager plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'no_data_msg' shortcode attribute in versions up to 3.3.60. Authenticated attackers with contributor-level permissions or higher can inject malicious JavaScript into the shortcode, which is subsequently executed in the browser of any user viewing the page when no packages are found.

Vulnerable Code

// src/Package/views/all-packages-shortcode.php line 396 (approx)

<?php echo isset($params['no_data_msg']) && $params['no_data_msg']!=''?$params['no_data_msg']:__('No Packages Found','download-manager'); ?>

---

// src/Package/Shortcodes.php

// Within the allPackages method, the $params array is used to pass user-controlled 
// shortcode attributes directly to the view without sanitization.
function allPackages($params = [])
{
    // ... (logic to fetch packages)
    include Template::locate("all-packages-shortcode.php", dirname(__FILE__) . '/views');
    // ...
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.60/src/Package/Shortcodes.php /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.61/src/Package/Shortcodes.php
--- /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.60/src/Package/Shortcodes.php	2026-06-28 05:51:02.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.61/src/Package/Shortcodes.php	2026-06-30 05:02:18.000000000 +0000
@@ -401,6 +401,14 @@
 
 	    $params = __::a($params, ['items_per_page' => 20]);
 
+        // Defense-in-depth: a contributor-supplied "no data" message must not be
+        // able to smuggle markup into the shortcode output. sanitize_text_field()
+        // strips literal tags here and the value is also escaped with esc_html()
+        // at render time (neutralizing entity-encoded payloads like &#x3c;script&#x3e;).
+        if (isset($params['no_data_msg'])) {
+            $params['no_data_msg'] = sanitize_text_field($params['no_data_msg']);
+        }
+
         $items = isset($params['items_per_page']) && $params['items_per_page'] > 0 ? (int)$params['items_per_page'] : 20;
         $offset = $cp = 0;
         if (isset($params['jstable']) && (int)$params['jstable'] === 1) {
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.60/src/Package/views/all-packages-shortcode.php /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.61/src/Package/views/all-packages-shortcode.php
--- /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.60/src/Package/views/all-packages-shortcode.php	2025-12-26 03:47:14.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/download-manager/3.3.61/src/Package/views/all-packages-shortcode.php	2026-06-30 05:02:18.000000000 +0000
@@ -393,7 +393,7 @@
                 <tr>
                     <td colspan="4" class="text-center">
 
-                        <?php echo isset($params['no_data_msg']) && $params['no_data_msg']!=''?$params['no_data_msg']:__('No Packages Found','download-manager'); ?>
+                        <?php echo isset($params['no_data_msg']) && $params['no_data_msg']!='' ? esc_html($params['no_data_msg']) : __('No Packages Found','download-manager'); ?>
 
                     </td>
                 </tr>

Exploit Outline

1. Login as a Contributor or higher-privileged user. 2. Create or edit a post/page and insert the following shortcode: `[wpdm_all_packages no_data_msg="<script>alert(origin)</script>" categories="non-existent-category"]`. 3. The `categories` attribute is set to a non-existent category to ensure the query returns no results, triggering the display of the `no_data_msg`. 4. Publish or preview the post. 5. When any user views the post, the plugin processes the shortcode, finds no items, and echoes the raw `no_data_msg` attribute into the HTML table, executing the attacker's script.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.