CVE-2026-6203

User Registration & Membership <= 5.1.4 - Unauthenticated Open Redirect via 'redirect_to_on_logout' Parameter

mediumURL Redirection to Untrusted Site ('Open Redirect')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
5.1.5
Patched in
1d
Time to patch

Description

The User Registration & Membership plugin for WordPress is vulnerable to Open Redirect in versions up to and including 5.1.4. This is due to insufficient validation of user-supplied URLs passed via the 'redirect_to_on_logout' GET parameter before redirecting users. The `redirect_to_on_logout` GET parameter is passed directly to WordPress's `wp_redirect()` function instead of the domain-restricted `wp_safe_redirect()`. While `esc_url_raw()` is applied to sanitize malformed URLs, it does not restrict the redirect destination to the local domain, allowing an attacker to craft a specially formed link that redirects users to potentially malicious external URLs after logout, which could be used to facilitate phishing attacks.

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<=5.1.4
PublishedApril 13, 2026
Last updatedApril 13, 2026
Affected pluginuser-registration

What Changed in the Fix

Changes introduced in v5.1.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets CVE-2026-6203, an Open Redirect vulnerability in the "User Registration & Membership" plugin (<= 5.1.4). ### 1. Vulnerability Summary The vulnerability exists because the plugin handles logout redirections using the `wp_redirect()` function instead of `wp_safe_redirect()`…

Show full research plan

This research plan targets CVE-2026-6203, an Open Redirect vulnerability in the "User Registration & Membership" plugin (<= 5.1.4).

1. Vulnerability Summary

The vulnerability exists because the plugin handles logout redirections using the wp_redirect() function instead of wp_safe_redirect(). While the plugin sanitizes the redirect_to_on_logout parameter with esc_url_raw(), this function only removes dangerous characters and malformed URL structures; it does not validate that the destination belongs to the local domain. Consequently, an attacker can provide an external URL (e.g., https://malicious-site.com), and the plugin will redirect the user there upon logout.

2. Attack Vector Analysis

  • Endpoint: The logout handler, typically triggered via a GET request to the "My Account" page or the site root with specific logout query parameters.
  • Vulnerable Parameter: redirect_to_on_logout (GET).
  • Authentication: Not strictly required for the redirect to trigger in some configurations, but primarily exploited by tricking a logged-in user into clicking the link to log them out and redirect them to a phishing site.
  • Preconditions: The plugin must be active. A "My Account" page or a page containing the User Registration logout link facilitates finding the correct logout trigger.

3. Code Flow (Inferred)

Since the full PHP source is not provided, the flow is grounded in the vulnerability description and standard plugin architecture:

  1. Entry Point: The plugin listens for a logout action, likely via the template_redirect or init hook.
  2. Parameter Extraction: The code checks for the existence of $_GET['redirect_to_on_logout'].
  3. Sanitization: The value is passed through esc_url_raw() (e.g., $url = esc_url_raw( $_GET['redirect_to_on_logout'] );).
  4. Vulnerable Sink: The code calls wp_redirect( $url ) directly.
  5. Execution: The server sends a 302 Found response with a Location header pointing to the external site.

4. Nonce Acquisition Strategy

WordPress logout logic usually requires a _wpnonce to prevent CSRF-based logout. However, Open Redirects are often found in custom logout implementations that may bypass or have already validated the nonce before processing the redirect.

Strategy:

  1. Identify the Logout Trigger: Use the "My Account" shortcode.
  2. Create Test Page:
    wp post create --post_type=page --post_title="Account" --post_status=publish --post_content='[user_registration_my_account]'
  3. Navigate and Extract:
    • Navigate to the newly created /account/ page using browser_navigate.
    • If logged in, look for the "Logout" link.
    • Use browser_eval to extract the link: browser_eval("document.querySelector('a[href*=\"logout\"]').href").
  4. Analyze Link: The link will likely look like [URL]?ur_logout=true&_wpnonce=[NONCE] or [URL]/user-logout/?_wpnonce=[NONCE].

5. Exploitation Strategy

The goal is to demonstrate that the Location header in the response points to an external domain.

Step-by-Step:

  1. Setup User: Create a subscriber user and log in to obtain session cookies.
  2. Obtain Logout URL: Access the "My Account" page to get the valid logout link (including the required nonce).
  3. Craft Payload: Append &redirect_to_on_logout=https://example.com to the valid logout URL.
  4. Request: Use the http_request tool to perform a GET request to the crafted URL, ensuring the subscriber cookies are included.
  5. Analysis: Check the response status (should be 302) and the Location header.

HTTP Request Template:

GET /[MY_ACCOUNT_PAGE]/?ur_logout=true&_wpnonce=[NONCE]&redirect_to_on_logout=https://example.com HTTP/1.1
Host: [TARGET_HOST]
Cookie: [SUBSCRIBER_COOKIES]

6. Test Data Setup

  1. Plugin Installation: Ensure user-registration version 5.1.4 is installed.
  2. Account Page:
    wp post create --post_type=page --post_title="My Account" --post_status=publish --post_content='[user_registration_my_account]' --post_name=my-account
  3. User Creation:
    wp user create victim victim@example.com --role=subscriber --user_pass=password123
  4. Login: Use http_request or the browser tool to log in as victim.

7. Expected Results

  • Status Code: 302 Found.
  • Header: Location: https://example.com.
  • Behavior: The user session is terminated (logged out), and the browser is redirected to a non-local domain.

8. Verification Steps

  1. Intercept Response: Use the http_request output to verify the Location header contains https://example.com.
  2. Verify Logout: After the request, try to access /wp-admin/ or the "My Account" page with the same cookies. It should prompt for login or show the logged-out view, confirming the logout action was processed.

9. Alternative Approaches

If the redirect_to_on_logout parameter is not processed on the logout URL itself, check the plugin settings:

  • Some versions of this plugin allow setting a global "Logout Redirect URL" in the settings. Check if this setting is vulnerable to being overridden by the GET parameter on any page where the plugin is active.
  • Test if the redirect works even without a valid logout nonce. If it does, the vulnerability is a pure Open Redirect that doesn't even require a successful logout.
  • Try common parameter variations: redirect_to, redirect_url, or return_to if redirect_to_on_logout fails. (Note: The CVE specifically names redirect_to_on_logout).
Research Findings
Static analysis — not yet PoC-verified

Summary

The User Registration & Membership plugin for WordPress is vulnerable to an unauthenticated Open Redirect due to insufficient validation of the 'redirect_to_on_logout' parameter. Attackers can craft malicious logout links that redirect users to external phishing sites, leveraging the plugin's use of wp_redirect() instead of wp_safe_redirect().

Vulnerable Code

// The plugin likely processes logout redirection in a hook similar to template_redirect or init

if ( isset( $_GET['redirect_to_on_logout'] ) ) {
    $redirect_url = esc_url_raw( $_GET['redirect_to_on_logout'] );
    wp_redirect( $redirect_url );
    exit;
}

Security Fix

--- a/includes/class-ur-account-handler.php
+++ b/includes/class-ur-account-handler.php
@@ -102,7 +102,7 @@
 			if ( isset( $_GET['redirect_to_on_logout'] ) ) {
 				$redirect_url = esc_url_raw( wp_unslash( $_GET['redirect_to_on_logout'] ) );
-				wp_redirect( $redirect_url );
+				wp_safe_redirect( $redirect_url );
 				exit;
 			}

Exploit Outline

1. Identify the logout URL: Navigate to the 'My Account' page (generated by the [user_registration_my_account] shortcode) and extract the 'Logout' link, which typically contains a valid WordPress security nonce (e.g., /?ur_logout=true&_wpnonce=abcdef123). 2. Craft the payload: Append the vulnerable parameter 'redirect_to_on_logout' to this URL, setting its value to an external malicious domain (e.g., &redirect_to_on_logout=https://evil-phishing-site.com). 3. Trigger the redirect: Trick a logged-in user into clicking the crafted link. The plugin will terminate the user's session and, because it uses the non-restricted wp_redirect() function, it will redirect the user to the specified external URL. 4. Authentication Requirement: The attacker requires no authentication, but the victim must be logged in for the logout action (and subsequent redirect) to process normally.

Check if your site is affected.

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