Executive Summary
A critical authentication bypass vulnerability (CVE-2026-7458) has been discovered in the User Verification by PickPlugins plugin for WordPress, affecting all versions up to and including 2.0.46. The flaw carries a CVSS score of 9.8 and requires no authentication to exploit.
The vulnerability stems from a loose PHP type comparison when validating one-time passwords (OTP) in the user_verification_form_wrap_process_otpLogin function. An unauthenticated attacker can bypass the OTP verification step and authenticate as any registered user, including administrators, without knowledge of the actual OTP code.
WordPress site owners running the affected versions should update immediately or disable the plugin until patched.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-7458 |
| CVSS Score | 9.8 (Critical) |
| CWE | CWE-287 — Improper Authentication |
| Type | Authentication Bypass / Account Takeover |
| Attack Vector | Network |
| Privileges Required | None (unauthenticated) |
| User Interaction | None |
| Patch Available | Update beyond 2.0.46 |
Affected Versions
| Plugin | Affected Versions | Status |
|---|---|---|
| User Verification by PickPlugins | <= 2.0.46 | Patch available — update immediately |
Technical Analysis
Root Cause
The User Verification by PickPlugins plugin provides OTP-based two-factor authentication for WordPress login forms. When a user completes the first authentication step (username/password), they receive an OTP code that must be entered to complete login.
The critical flaw lies in the OTP comparison logic inside user_verification_form_wrap_process_otpLogin. The function uses PHP's loose equality operator (==) instead of the strict equality operator (===) when comparing the user-supplied OTP to the stored code.
In PHP, loose comparison creates dangerous type-juggling behavior:
// Vulnerable comparison (loose ==)
if ($user_otp == $stored_otp) {
// authentication succeeds
}
// PHP type juggling examples:
// "0" == false → true
// "0" == null → true
// "" == false → true
// "" == 0 → true (in older PHP)
// "abc" == 0 → true (in PHP < 8.0)An attacker can exploit this by supplying a specially crafted OTP value that evaluates as equal to the stored OTP under PHP's loose comparison rules — without knowing the actual code.
Attack Flow
1. Attacker identifies a WordPress account to target (e.g., admin username)
2. Attacker submits valid credentials (username + password) for the target account
(Or if credentials are unknown, this may still allow bypass at OTP step via AJAX)
3. Site prompts for OTP verification via user_verification_form_wrap_process_otpLogin
4. Attacker submits crafted OTP value designed to match via loose PHP comparison
(e.g., boolean false, integer 0, or type-juggling payload depending on stored value format)
5. Plugin's loose == comparison evaluates crafted value as equal to stored OTP
6. Authentication is approved — attacker is logged in as target user
7. Full account access achieved, including admin capabilities if admin was targetedExploitation Conditions
- User Verification by PickPlugins version 2.0.46 or earlier must be installed and active
- The OTP verification feature must be enabled (default behavior of the plugin)
- The attacker may need valid first-factor credentials depending on how the OTP endpoint is exposed
- No privileges required — unauthenticated exploitation possible via the AJAX OTP endpoint
Impact Assessment
| Impact Area | Description |
|---|---|
| Account Takeover | Attacker can bypass OTP and authenticate as any user |
| Admin Access | Full WordPress admin control if admin account is targeted |
| Data Exfiltration | Access to all user data, PII, and site content |
| Site Defacement | Admin access enables theme, plugin, and content modification |
| Persistent Backdoor | Attacker can create new admin accounts |
| Plugin/Theme Injection | Malicious code injection into WordPress installation |
Immediate Remediation
Step 1: Update the Plugin
Update User Verification by PickPlugins beyond version 2.0.46:
# Via WP-CLI
wp plugin update user-verification
# Verify installed version
wp plugin get user-verification --field=versionOr navigate to WordPress Admin > Plugins > Installed Plugins and update the plugin.
Step 2: Disable the Plugin if Update Is Not Immediately Possible
# Deactivate via WP-CLI
wp plugin deactivate user-verificationStep 3: Audit for Compromise
# Check for recently created administrator accounts
wp user list --role=administrator --fields=user_login,user_email,user_registered
# Review recent logins from the last 7 days
wp db query "SELECT user_login, user_email, user_registered FROM wp_users WHERE user_registered > DATE_SUB(NOW(), INTERVAL 7 DAY);"
# Regenerate WordPress secret keys to invalidate all sessions
wp config shuffle-salts
# Invalidate all active sessions
wp db query "DELETE FROM wp_usermeta WHERE meta_key = 'session_tokens';"Step 4: Harden OTP Implementation (Post-Update)
After updating, verify that your PHP code uses strict comparisons. For custom code:
// Insecure — avoid
if ($user_otp == $stored_otp) { ... }
// Secure — use strict comparison
if ($user_otp === $stored_otp) { ... }
// Even better — use hash_equals() to prevent timing attacks
if (hash_equals((string)$stored_otp, (string)$user_otp)) { ... }Detection Indicators
| Indicator | Description |
|---|---|
| Login events bypassing OTP step | Exploitation attempt in audit logs |
| New admin accounts created recently | Post-exploitation persistence |
| Unexpected plugin or theme modifications | Active admin session abuse |
| Login from unusual IP addresses | Account takeover in use |
| OTP verification POST requests with unusual values | Type-juggling exploit payloads |
Post-Remediation Checklist
- Update User Verification by PickPlugins beyond version 2.0.46
- Invalidate all active WordPress sessions to force re-authentication
- Audit all administrator accounts — remove any unauthorized entries
- Reset all admin and high-privilege user passwords
- Review WordPress access logs for signs of prior exploitation
- Regenerate WordPress secret keys and salts
- Enable a WAF with WordPress protection rules (Wordfence, Sucuri, Cloudflare)
- Monitor for recurring exploitation attempts after remediation