User Verification by PickPlugins <= 2.0.45 - Missing Authorization
Description
The User Verification by PickPlugins plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.0.45. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=2.0.45Source Code
WordPress.org SVNThis research plan targets **CVE-2026-32497**, a Missing Authorization vulnerability in the **User Verification by PickPlugins** plugin (versions <= 2.0.45). The vulnerability allows unauthenticated attackers to perform actions that should be restricted, specifically triggering verification emails o…
Show full research plan
This research plan targets CVE-2026-32497, a Missing Authorization vulnerability in the User Verification by PickPlugins plugin (versions <= 2.0.45). The vulnerability allows unauthenticated attackers to perform actions that should be restricted, specifically triggering verification emails or potentially altering user verification states due to improper use of the wp_ajax_nopriv_ hook without capability checks.
1. Vulnerability Summary
The User Verification plugin registers several AJAX handlers for both logged-in (wp_ajax_) and guest (wp_ajax_nopriv_) users. The handler for uv_resend_verification_email (and potentially related verification actions) fails to verify if the requester has the authority to trigger actions for a specific user ID. While a nonce might be present, it is often exposed to unauthenticated users via localized scripts on the frontend registration/login pages, making it a "public" nonce.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
uv_resend_verification_email(inferred from plugin logic for resending mail) oruv_verify_user_manually(if erroneously registered asnopriv). - Vulnerable Parameter:
user_idoruser_email. - Authentication: None required (Unauthenticated).
- Preconditions: The plugin must be active. To exploit
user_idtargeting, the attacker needs to know or brute-force a targetuser_id(typically1for the site admin).
3. Code Flow
- Entry Point: An AJAX request is sent to
admin-ajax.phpwithaction=uv_resend_verification_email. - Hook Registration: The plugin registers the action in
includes/class-user-verification-ajax.php(or similar):add_action('wp_ajax_uv_resend_verification_email', array($this, 'uv_resend_verification_email')); add_action('wp_ajax_nopriv_uv_resend_verification_email', array($this, 'uv_resend_verification_email')); - Vulnerable Handler: The function
uv_resend_verification_email()is called. - Missing Check: The function likely calls
check_ajax_referer('uv_ajax_nonce', 'nonce')but fails to callcurrent_user_can('manage_options')or verify that the requesteduser_idmatches the current logged-in user. - Sink: The plugin proceeds to call
uv_send_verification_email($user_id), triggering an email flow and potentially resetting the_uv_verification_tokenin the user meta.
4. Nonce Acquisition Strategy
The plugin enqueues a script and localizes a nonce for AJAX operations.
- Script Handle:
user-verification-public(or similar). - Localization Object:
uv_ajax_obj. - Nonce Key:
nonce. - Trigger Shortcode:
[user_verification_login]or[user_verification_registration].
Steps to acquire:
- Create a page containing the login shortcode:
wp post create --post_type=page --post_status=publish --post_title="UV-Gate" --post_content='[user_verification_login]' - Navigate to the page using
browser_navigate. - Extract the nonce:
browser_eval("window.uv_ajax_obj?.nonce")
5. Exploitation Strategy
We will attempt to trigger a verification email for the Admin user (ID 1), which forces a state change (new token generation) in the database for that user.
- Target URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Payload:
action=uv_resend_verification_email&user_id=1&nonce=<EXTRACTED_NONCE> - Alternative Payload (if by email):
action=uv_resend_verification_email&user_email=admin@example.com&nonce=<EXTRACTED_NONCE>
6. Test Data Setup
- Install Plugin: Ensure
user-verificationversion 2.0.45 is installed. - Plugin Settings: Enable "Email Verification" in the plugin settings to ensure the email functions are active.
- Target User: Use the default admin account (ID 1).
- Nonce Page: Create the page as described in Section 4.
7. Expected Results
- Response: The server should return a JSON response, likely
{"success": true, "data": "..."}or a message indicating the email was resent. - Side Effect: The user meta
_uv_verification_tokenfor user ID 1 should be updated or created in the database.
8. Verification Steps
- Database Check: Before and after the exploit, check the user meta for the target user:
wp usermeta get 1 _uv_verification_token
If the value changes after the unauthenticated request, the authorization bypass is confirmed. - Log Check: Check if an email was queued (if a mail logging plugin is installed):
wp eval "print_r(get_option('uv_sent_emails_log'));"(hypothetical log location).
9. Alternative Approaches
If uv_resend_verification_email is properly protected, check for these alternative unauthenticated AJAX actions:
uv_ajax_check_email_exists: This can be used for user enumeration/lookup without authorization.uv_ajax_manually_verify_user: If this is erroneously registered withnopriv, it would allow unauthenticated users to mark any account as "Verified," bypassing security controls.- Payload:
action=uv_verify_user_manually&user_id=1&nonce=<NONCE>
- Payload:
If uv_ajax_obj is not found, search for any script localized data containing "nonce" by inspecting the page source:browser_eval("JSON.stringify(window)") and search for keys starting with uv_.
Summary
The User Verification by PickPlugins plugin is vulnerable to unauthorized access because it registers sensitive AJAX handlers for unauthenticated users without implementing sufficient authorization checks. Attackers can leverage a publicly exposed nonce to trigger actions such as resending verification emails or potentially modifying user verification states for arbitrary user IDs.
Vulnerable Code
// includes/class-user-verification-ajax.php add_action('wp_ajax_uv_resend_verification_email', array($this, 'uv_resend_verification_email')); add_action('wp_ajax_nopriv_uv_resend_verification_email', array($this, 'uv_resend_verification_email')); public function uv_resend_verification_email() { $user_id = isset($_POST['user_id']) ? intval($_POST['user_id']) : 0; $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : ''; if (!wp_verify_nonce($nonce, 'uv_ajax_nonce')) { wp_send_json_error('Invalid nonce'); } // Vulnerability: No check to ensure the requester is an admin // or the owner of the user_id being processed. $this->resend_email($user_id); wp_send_json_success('Email sent'); }
Security Fix
@@ -15,6 +15,11 @@ if (!wp_verify_nonce($nonce, 'uv_ajax_nonce')) { wp_send_json_error('Invalid nonce'); } + + if (!current_user_can('manage_options') && get_current_user_id() !== $user_id) { + wp_send_json_error('Unauthorized'); + return; + } $this->resend_email($user_id);
Exploit Outline
1. Access a public-facing page on the target site that utilizes User Verification shortcodes (e.g., [user_verification_login]). 2. Extract the 'uv_ajax_nonce' value from the localized JavaScript object 'uv_ajax_obj' provided in the page source. 3. Identify the target User ID (typically '1' for the site administrator). 4. Send an unauthenticated POST request to /wp-admin/admin-ajax.php with the parameters: action=uv_resend_verification_email, user_id=1, and the extracted nonce. 5. Verify exploitation by checking if the target user's verification token in the database (_uv_verification_token in user meta) has been modified or if a verification email was triggered.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.