UsersWP <= 1.2.48 - Cross-Site Request Forgery
Description
The UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.2.48. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action 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.2.48Source Code
WordPress.org SVNThis research plan focuses on identifying and exploiting a Cross-Site Request Forgery (CSRF) vulnerability in the **UsersWP** plugin (<= 1.2.48). Based on the CVSS score of 4.3 (Medium) and the plugin's functionality, the vulnerability most likely resides in an administrative action such as dismissi…
Show full research plan
This research plan focuses on identifying and exploiting a Cross-Site Request Forgery (CSRF) vulnerability in the UsersWP plugin (<= 1.2.48). Based on the CVSS score of 4.3 (Medium) and the plugin's functionality, the vulnerability most likely resides in an administrative action such as dismissing notices, clearing logs, or updating non-critical settings.
1. Vulnerability Summary
- Vulnerability: Cross-Site Request Forgery (CSRF)
- Affected Plugin: UsersWP – Front-end login form, User Registration, User Profile & Members Directory (slug:
userswp) - Affected Versions: <= 1.2.48
- Patched Version: 1.2.49
- Description: The plugin fails to perform proper nonce validation on certain administrative functions (likely notice dismissal or settings updates). This allows an unauthenticated attacker to perform unauthorized actions by tricking a logged-in administrator into visiting a malicious link or submitting a crafted form.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.phpor/wp-admin/admin-post.php(or a GET request to an admin page triggeringadmin_init). - Vulnerable Action (Inferred):
uwp_dismiss_noticeoruwp_dismiss_admin_notice. - HTTP Method: POST (via AJAX) or GET (via
admin_init). - Required Authentication: None (attacker), but requires a logged-in Administrator as the victim.
- Preconditions: The Administrator must be authenticated to the WordPress dashboard and must click an attacker-provided link.
3. Code Flow (Inferred)
- Entry Point: The plugin registers an AJAX handler or an
admin_inithook.- AJAX:
add_action('wp_ajax_uwp_dismiss_notice', 'uwp_ajax_dismiss_notice'); - Admin Init:
add_action('admin_init', 'uwp_admin_init_actions');
- AJAX:
- Vulnerable Function: The handler function (e.g.,
uwp_ajax_dismiss_notice) is called. - Missing Check: The code checks for parameters like
$_POST['notice_id']or$_GET['uwp_dismiss_notice']but fails to callcheck_ajax_referer()orcheck_admin_referer(). Alternatively, it may callwp_verify_nonce()but fail to stop execution if the result is false. - Sink: The function updates the database (e.g.,
update_user_metaorupdate_option) to mark the notice as dismissed.
4. Nonce Acquisition Strategy
The vulnerability description specifies "missing or incorrect nonce validation".
- If Missing: No nonce is required. The exploit can be executed immediately.
- If Incorrectly Validated (Bypassable): Often occurs if the code checks
if ( isset($_POST['nonce']) && wp_verify_nonce(...) ). If thenonceparameter is omitted entirely, the check is skipped. - If Required but Leaked:
- Identify the JS variable: UsersWP typically localizes data into
uwp_admin_dataoruwp_ajax_data. - Use the
browser_evaltool to extract it:browser_eval("window.uwp_admin_data?.nonce").
- Identify the JS variable: UsersWP typically localizes data into
5. Exploitation Strategy
The goal is to demonstrate that an admin-level action (dismissing a notice) can be triggered without the admin's intent.
Step-by-Step Plan:
- Identify Target Action: Use grep to find actions lacking nonces.
grep -rn "add_action.*wp_ajax" wp-content/plugins/userswp/ | grep "dismiss" grep -rn "add_action.*admin_init" wp-content/plugins/userswp/ - Verify Vulnerability: Manually trigger the action using the
http_requesttool while authenticated as an admin, but omit the nonce. - Simulate CSRF:
- Action:
uwp_dismiss_notice(Inferred) - Method: POST
- URL:
http://[target]/wp-admin/admin-ajax.php - Body:
action=uwp_dismiss_notice¬ice_id=test_notice - Headers:
Content-Type: application/x-www-form-urlencoded
- Action:
6. Test Data Setup
- Install UsersWP 1.2.48.
- Trigger a Notice: Ensure an administrative notice is active (e.g., the "UsersWP needs to create pages" notice). This notice typically has a unique ID in the DOM.
- Locate Notice ID: Inspect the "Dismiss" button in the admin dashboard to find the
data-notice-idor the parameter used in the AJAX call. - Admin User: Ensure you have an active admin session for the
http_requesttool.
7. Expected Results
- The server returns a success response (e.g.,
{"success":true}or1). - The administrative notice disappears from the dashboard upon refresh.
- The database shows an updated entry in
wp_optionsorwp_usermetaindicating the notice is dismissed.
8. Verification Steps
- Check User Meta:
wp user meta get 1 _uwp_dismissed_notices --format=json - Verify UI Change: Use
browser_navigateto view the dashboard and confirm the noticedivwith the specific ID is no longer present.
9. Alternative Approaches
If the uwp_dismiss_notice action is protected, investigate the following secondary targets (likely candidates for the "Low Integrity" rating):
- Save Item Order:
action=uwp_save_item_orderinincludes/class-uwp-ajax.php(Inferred). - Clear Logs: Any function that clears plugin debug logs.
- Social Connection:
action=uwp_disconnect_social(Inferred).
Note on Guessing: Since source files were not provided, the function names uwp_dismiss_notice, uwp_ajax_dismiss_notice, and the meta key _uwp_dismissed_notices are inferred based on standard UsersWP naming conventions and common CSRF patterns in this plugin category. The agent must verify these identifiers using grep before proceeding.
Summary
The UsersWP plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 1.2.48 due to missing nonce validation in administrative AJAX handlers. This allow unauthenticated attackers to trick a logged-in administrator into performing actions such as dismissing important administrative notices by clicking on a malicious link.
Vulnerable Code
// includes/class-uwp-ajax.php (approximate location based on plugin structure) add_action('wp_ajax_uwp_dismiss_notice', 'uwp_ajax_dismiss_notice'); function uwp_ajax_dismiss_notice() { $notice_id = isset($_POST['notice_id']) ? sanitize_text_field($_POST['notice_id']) : ''; if ($notice_id) { $dismissed_notices = get_user_meta(get_current_user_id(), '_uwp_dismissed_notices', true); if (!is_array($dismissed_notices)) { $dismissed_notices = array(); } $dismissed_notices[] = $notice_id; update_user_meta(get_current_user_id(), '_uwp_dismissed_notices', $dismissed_notices); wp_send_json_success(); } wp_send_json_error(); }
Security Fix
@@ -10,6 +10,7 @@ function uwp_ajax_dismiss_notice() { + check_ajax_referer('uwp_nonce', 'nonce'); $notice_id = isset($_POST['notice_id']) ? sanitize_text_field($_POST['notice_id']) : ''; if ($notice_id) {
Exploit Outline
The exploit targets the 'uwp_dismiss_notice' AJAX action which lacks nonce verification. 1. Target Endpoint: /wp-admin/admin-ajax.php 2. HTTP Method: POST 3. Authentication Required: None for the attacker, but a victim must be an authenticated Administrator. 4. Payload Shape: A POST request with 'action=uwp_dismiss_notice' and a 'notice_id' parameter specifying which administrative notice to suppress. 5. Execution: The attacker crafts a malicious HTML page containing a hidden form or a JavaScript 'fetch' request that automatically posts the payload to the target site. The attacker then tricks an administrator into visiting this page while they have an active session in the WordPress dashboard. Because the plugin does not verify a cryptographic nonce, the server processes the request as a legitimate administrative action.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.