Download Manager <= 3.3.32 - Missing Authorization to Authenticated (Subscriber+) Media Attachment Password Disclosure
Description
The Download Manager plugin for WordPress is vulnerable to unauthorized access of sensitive information in all versions up to, and including, 3.3.32. This is due to missing authorization and capability checks on the `wpdm_media_access` AJAX action. This makes it possible for authenticated attackers, with Subscriber-level access and above, to retrieve passwords and access control settings for protected media attachments, which can then be used to bypass the intended media protection and download restricted files.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=3.3.32Source Code
WordPress.org SVNThis research plan outlines the technical steps to exploit **CVE-2025-13498** in the **Download Manager** plugin. ### 1. Vulnerability Summary The **Download Manager** plugin (versions <= 3.3.32) fails to implement proper authorization and capability checks in its AJAX handler for the `wpdm_media_a…
Show full research plan
This research plan outlines the technical steps to exploit CVE-2025-13498 in the Download Manager plugin.
1. Vulnerability Summary
The Download Manager plugin (versions <= 3.3.32) fails to implement proper authorization and capability checks in its AJAX handler for the wpdm_media_access action. While the action is registered via wp_ajax_ (restricting it to authenticated users), it does not verify if the requesting user (even a low-privileged Subscriber) has the authority to view the access control settings or passwords for a specific media attachment. This allows an attacker to query the metadata of protected files and retrieve passwords intended to restrict downloads.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
wpdm_media_access - HTTP Method:
POST - Parameters:
action:wpdm_media_accessID: The ID of the WordPress attachment or WPDM package file.__wpdm_media_access: The nonce for the action (required).
- Authentication: Required (Subscriber level or higher).
- Precondition: At least one media attachment or WPDM package must exist and be "protected" (e.g., password-protected).
3. Code Flow (Inferred)
- Registration: The plugin registers the action:
add_action('wp_ajax_wpdm_media_access', 'wpdm_media_access_callback_function'); - Entry Point: A Subscriber sends a POST request to
admin-ajax.phpwithaction=wpdm_media_access. - Nonce Check: The handler likely calls
check_ajax_referer('wpdm_media_access', '__wpdm_media_access');. This validates that the request is from an authenticated user but does not validate who that user is or their permissions. - Data Retrieval: The handler takes the
IDparameter, fetches the post metadata for that ID (likely usingget_post_meta($id, '__wpdm_access_settings', true)or similar), and prepares a response. - Vulnerable Sink: The handler returns the metadata via
wp_send_json()without checking if the current user is the owner of the file or an administrator. - Leaked Information: The JSON response includes fields like
password,lock, oraccess_roles.
4. Nonce Acquisition Strategy
Download Manager typically localizes nonces for its media management features. To obtain a valid nonce for wpdm_media_access:
- Identify Trigger: The nonce is likely generated for users who can view the Media Library or WPDM file browser.
- Setup Page: Create a post containing the WPDM file browser shortcode or a standard package link.
- Command:
wp post create --post_type=page --post_status=publish --post_content='[wpdm_category slug="test"]'(or similar WPDM shortcode).
- Command:
- Browser Navigation: Navigate to the newly created page as a Subscriber.
- JS Variable Extraction: Use
browser_evalto find the localized data. Download Manager often uses the objectwpdm_paramsorWPDM.- Target Variable:
window.wpdm_params?.__wpdm_media_accessorwindow.WPDM?.__wpdm_media_access. - Alternative: Check the global
wpdm_ajaxobject if it exists.
- Target Variable:
5. Exploitation Strategy
- Target Identification: Find the ID of a protected media attachment. (For the PoC, we will create one).
- Authenticated Request: Using the Subscriber's session, send the following request:
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body:
action=wpdm_media_access&ID=<TARGET_ATTACHMENT_ID>&__wpdm_media_access=<EXTRACTED_NONCE>
- URL:
- Response Parsing: Analyze the JSON response for a
passwordkey or anaccessobject containing the plaintext password.
6. Test Data Setup
To verify the vulnerability, the environment must be configured as follows:
- Install Plugin: Ensure
download-managerv3.3.32 is installed and active. - Create Protected File:
- Use WP-CLI to upload a file:
wp media import /path/to/test.txt. - Use WP-CLI to create a WPDM Package (
wpdmpropost type) or simply set meta on a standard attachment. - Set Password: Set the meta key used by WPDM for passwords:
wp post meta set <ID> __wpdm_password "Secret123!"wp post meta set <ID> __wpdm_lock "password"
- Use WP-CLI to upload a file:
- Create Attacker User:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Shortcode Page:
wp post create --post_type=page --post_status=publish --post_title="Files" --post_content="[wpdm_all_packages]"(to ensure JS localizes properly).
7. Expected Results
A successful exploit will return a JSON object similar to:
{
"status": "success",
"data": {
"password": "Secret123!",
"lock": "password",
"access_roles": ["administrator"]
}
}
The presence of the password field in a response accessible to a Subscriber confirms the disclosure.
8. Verification Steps
- Log Output: Use
http_requestto capture the JSON response. - Database Comparison: Confirm the password in the JSON matches the one set via CLI:
wp post meta get <ID> __wpdm_password
- Bypass Confirmation: Attempt to download the file using the disclosed password to prove it allows unauthorized access to the restricted file.
9. Alternative Approaches
- ID Brute Forcing: If a specific ID isn't known, iterate through recent attachment IDs (e.g., decrementing from the current max ID).
- Frontend Leakage: Check if the nonce is leaked via
wpdm_setupon any page where a single package is displayed, even if that package itself isn't the target. - REST API: Check if
wp-json/wpdm/v1/...endpoints mirror this logic, though the CVE specifically mentions thewpdm_media_accessAJAX action.
Summary
The Download Manager plugin for WordPress (<= 3.3.32) fails to perform authorization checks in its 'wpdm_media_access' AJAX handler. This allows authenticated users with Subscriber-level permissions to retrieve sensitive metadata, including plain-text passwords for protected media files, by providing a valid nonce and the target attachment ID.
Vulnerable Code
// File: wpdm-functions.php (inferred from research plan code flow) add_action('wp_ajax_wpdm_media_access', 'wpdm_media_access_callback'); function wpdm_media_access_callback() { // Validates nonce but fails to verify user capability check_ajax_referer('wpdm_media_access', '__wpdm_media_access'); $id = intval($_POST['ID']); $password = get_post_meta($id, '__wpdm_password', true); $lock = get_post_meta($id, '__wpdm_lock', true); $access_roles = get_post_meta($id, '__wpdm_access_settings', true); // Vulnerable sink: returns sensitive meta directly to any authenticated user wp_send_json(array( 'status' => 'success', 'password' => $password, 'lock' => $lock, 'access_roles' => $access_roles )); }
Security Fix
@@ -10,6 +10,11 @@ function wpdm_media_access_callback() { check_ajax_referer('wpdm_media_access', '__wpdm_media_access'); + if (!current_user_can('manage_options') && !current_user_can('edit_posts')) { + wp_send_json_error(array('message' => 'Unauthorized access')); + return; + } + $id = intval($_POST['ID']); $password = get_post_meta($id, '__wpdm_password', true);
Exploit Outline
The exploit involves an authenticated Subscriber making a direct request to the WordPress AJAX endpoint. First, the attacker identifies a target protected media attachment ID and retrieves a valid 'wpdm_media_access' nonce, typically found in localized JavaScript objects (like window.wpdm_params) on pages rendering WPDM shortcodes. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'wpdm_media_access', the target 'ID', and the valid nonce. Because the server-side handler lacks capability checks, it responds with a JSON object containing the file's protection settings and plain-text password, allowing the attacker to bypass access restrictions and download the file.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.