CVE-2025-69102

Test Email <= 1.1.7 - Reflected Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.1.7
PublishedJanuary 15, 2026
Last updatedJanuary 19, 2026
Affected pluginwp-test-email
Research Plan
Unverified

# 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 the test_email input 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)

  1. Entry Point: The plugin registers an admin page using add_options_page() or add_menu_page() in the main plugin file (likely wp-test-email.php).
  2. Hook: The admin_menu hook calls a function to render the settings page.
  3. Vulnerable Sink: Inside the rendering function, the code accesses a $_GET or $_REQUEST parameter (e.g., $_GET['test_email'] or $_GET['message']).
  4. Reflection: The value of this parameter is printed directly to the HTML response using echo, printf, or similar, without passing through escaping functions like esc_html() or esc_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:

  1. The agent must use the session cookies of an administrative user.
  2. 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.
  3. 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.

5. Exploitation Strategy

The goal is to demonstrate that arbitrary JavaScript can be executed in the administrator's browser.

  1. 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.
  2. Payload Crafting:
    • Primary Payload: <script>alert(document.domain)</script>
    • If the reflection is inside an attribute: "><script>alert(1)</script>
  3. Execution:
    • Use the http_request tool 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]
      
  4. Evidence Collection: Inspect the response body to confirm the script tag is present and unescaped.

6. Test Data Setup

  1. Plugin Installation: Ensure wp-test-email version 1.1.7 is installed and activated.
  2. User Creation: An administrator user must exist (default admin / password in most test environments).
  3. 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 &lt;script&gt;....

8. Verification Steps

  1. Manual Check: Use http_request to fetch the URL and grep the 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>"
    
  2. 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:
    1. Submit the test email form.
    2. Observe the URL after redirect (e.g., ...&message=Email+Sent+to+...).
    3. Manually modify that message parameter in the URL.
  • Attribute Injection: If the input is reflected inside an <input> field's value attribute, use: value="x" onfocus="alert(1)" autofocus=" or value="x"><script>alert(1)</script>.
Research Findings
Static analysis — not yet PoC-verified

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

--- wp-content/plugins/wp-test-email/wp-test-email.php
+++ wp-content/plugins/wp-test-email/wp-test-email.php
@@ -... @@
-    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.