Test Email <= 1.1.7 - Reflected Cross-Site Scripting
Description
The Test Email plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 1.1.7 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.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=1.1.7# Exploitation Research Plan - CVE-2025-69102 (WP Test Email) ## 1. Vulnerability Summary The **WP Test Email** plugin (version <= 1.1.7) is vulnerable to **Reflected Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to sufficiently sanitize and escape user-supplied in…
Show full research plan
Exploitation Research Plan - CVE-2025-69102 (WP Test Email)
1. Vulnerability Summary
The WP Test Email plugin (version <= 1.1.7) is vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to sufficiently sanitize and escape user-supplied input from URL parameters before echoing it back into an administrative or public-facing page. An unauthenticated attacker can craft a malicious link containing a JavaScript payload; if a logged-in user (typically an administrator) clicks this link, the script executes within the context of their session.
2. Attack Vector Analysis
- Endpoint: Administrative settings page (likely
wp-admin/options-general.php?page=wp-test-email). - Vulnerable Parameter: Likely a feedback parameter such as
message,error, or thetest_emailinput reflected after a form submission (Inferred). - Authentication: Unauthenticated (to craft/distribute the link), but requires a victim with active session (Admin) to trigger.
- Preconditions: The plugin must be active. The victim must be logged into WordPress.
3. Code Flow (Inferred)
- Entry Point: The plugin registers an admin page using
add_options_page()oradd_menu_page()in the main plugin file (likelywp-test-email.php). - Hook: The
admin_menuhook calls a function to render the settings page. - Vulnerable Sink: Inside the rendering function, the code accesses a
$_GETor$_REQUESTparameter (e.g.,$_GET['test_email']or$_GET['message']). - Reflection: The value of this parameter is printed directly to the HTML response using
echo,printf, or similar, without passing through escaping functions likeesc_html()oresc_attr().
4. Nonce Acquisition Strategy
Reflected XSS in GET parameters typically does not require a nonce for the reflection itself, as the vulnerability lies in the display of data, not necessarily in the execution of a protected action.
However, to access the admin page where the reflection occurs, the "victim" must be logged in. For the automated agent to demonstrate this:
- The agent must use the session cookies of an administrative user.
- If the reflection is only visible after a "Test Email" is sent, a nonce might be required for the initial POST request that triggers the redirect.
- Strategy:
- Navigate to the settings page:
browser_navigate("/wp-admin/options-general.php?page=wp-test-email"). - Check for any localized nonces if a POST request is needed to trigger the reflected message.
- Navigate to the settings page:
5. Exploitation Strategy
The goal is to demonstrate that arbitrary JavaScript can be executed in the administrator's browser.
- Discovery: Identify the exact reflecting parameter.
- Target URL:
/wp-admin/options-general.php?page=wp-test-email - Test common parameters:
test_email,email,message,status.
- Target URL:
- Payload Crafting:
- Primary Payload:
<script>alert(document.domain)</script> - If the reflection is inside an attribute:
"><script>alert(1)</script>
- Primary Payload:
- Execution:
- Use the
http_requesttool to perform a GET request as an Administrator to the target URL with the payload attached. - Request Example (Inferred):
GET /wp-admin/options-general.php?page=wp-test-email&test_email=<script>alert(document.domain)</script> HTTP/1.1 Host: localhost:8080 Cookie: [Admin Cookies]
- Use the
- Evidence Collection: Inspect the response body to confirm the script tag is present and unescaped.
6. Test Data Setup
- Plugin Installation: Ensure
wp-test-emailversion 1.1.7 is installed and activated. - User Creation: An administrator user must exist (default
admin/passwordin most test environments). - Page Identification: Use WP-CLI to confirm the admin page slug:
wp eval "global \$menu; print_r(\$menu);" | grep "test-email"(Inferred slug).
7. Expected Results
- The HTTP response should contain the raw, unencoded payload:
<script>alert(document.domain)</script>. - If viewed in a browser, a JavaScript alert box would appear.
- The string should NOT be transformed into
<script>....
8. Verification Steps
- Manual Check: Use
http_requestto fetch the URL andgrepthe output.# Example verification command for the agent curl -s -b admin_cookies.txt "http://localhost:8080/wp-admin/options-general.php?page=wp-test-email&test_email=%3Cscript%3Ealert(1)%3C/script%3E" | grep "<script>alert(1)</script>" - Code Audit: Verify the lack of escaping in the source:
grep -rn "echo \$_GET" wp-content/plugins/wp-test-email/
9. Alternative Approaches
- Redirect-based Reflection: If the XSS is not directly on the settings page, check if it reflects in the "Success" message after sending an email:
- Submit the test email form.
- Observe the URL after redirect (e.g.,
...&message=Email+Sent+to+...). - Manually modify that
messageparameter in the URL.
- Attribute Injection: If the input is reflected inside an
<input>field'svalueattribute, use:value="x" onfocus="alert(1)" autofocus="orvalue="x"><script>alert(1)</script>.
Summary
The Test Email plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) in versions up to and including 1.1.7. This is due to the plugin failing to sanitize or escape user-supplied input from URL parameters, such as 'message', before echoing it back onto the administrative settings page.
Vulnerable Code
// Inferred from research plan: wp-content/plugins/wp-test-email/wp-test-email.php if (isset($_GET['message'])) { echo '<div class="updated"><p>' . $_GET['message'] . '</p></div>'; }
Security Fix
@@ -... @@ - if (isset($_GET['message'])) { - echo '<div class="updated"><p>' . $_GET['message'] . '</p></div>'; - } + if (isset($_GET['message'])) { + echo '<div class="updated"><p>' . esc_html($_GET['message']) . '</p></div>'; + }
Exploit Outline
1. Identify the plugin's administration page, usually found at /wp-admin/options-general.php?page=wp-test-email. 2. Craft a malicious URL targeting this page with a reflected parameter (e.g., 'message') containing a script payload: ?page=wp-test-email&message=<script>alert(document.domain)</script>. 3. The attacker tricks a logged-in WordPress administrator into clicking the crafted link through social engineering. 4. When the page renders, the payload is echoed directly into the HTML without escaping, causing the arbitrary JavaScript to execute in the victim's browser session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.