User Registration & Membership <= 5.1.4 - Unauthenticated Open Redirect via 'redirect_to_on_logout' Parameter
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:NTechnical Details
<=5.1.4What Changed in the Fix
Changes introduced in v5.1.5
Source Code
WordPress.org SVNThis 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:
- Entry Point: The plugin listens for a logout action, likely via the
template_redirectorinithook. - Parameter Extraction: The code checks for the existence of
$_GET['redirect_to_on_logout']. - Sanitization: The value is passed through
esc_url_raw()(e.g.,$url = esc_url_raw( $_GET['redirect_to_on_logout'] );). - Vulnerable Sink: The code calls
wp_redirect( $url )directly. - Execution: The server sends a
302 Foundresponse with aLocationheader 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:
- Identify the Logout Trigger: Use the "My Account" shortcode.
- Create Test Page:
wp post create --post_type=page --post_title="Account" --post_status=publish --post_content='[user_registration_my_account]' - Navigate and Extract:
- Navigate to the newly created
/account/page usingbrowser_navigate. - If logged in, look for the "Logout" link.
- Use
browser_evalto extract the link:browser_eval("document.querySelector('a[href*=\"logout\"]').href").
- Navigate to the newly created
- 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:
- Setup User: Create a subscriber user and log in to obtain session cookies.
- Obtain Logout URL: Access the "My Account" page to get the valid logout link (including the required nonce).
- Craft Payload: Append
&redirect_to_on_logout=https://example.comto the valid logout URL. - Request: Use the
http_requesttool to perform a GET request to the crafted URL, ensuring the subscriber cookies are included. - Analysis: Check the response status (should be 302) and the
Locationheader.
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
- Plugin Installation: Ensure
user-registrationversion 5.1.4 is installed. - 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 - User Creation:
wp user create victim victim@example.com --role=subscriber --user_pass=password123 - Login: Use
http_requestor the browser tool to log in asvictim.
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
- Intercept Response: Use the
http_requestoutput to verify theLocationheader containshttps://example.com. - 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, orreturn_toifredirect_to_on_logoutfails. (Note: The CVE specifically namesredirect_to_on_logout).
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
@@ -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.