Your deadbolt only works if the burglar doesn't know the secret knock on the side door
CVE-2026-8293 is a two-factor authentication bypass in the Really Simple Security WordPress plugin (formerly Really Simple SSL) affecting all versions before 9.5.10.1. The plugin exposes two REST endpoints — /wp-json/really-simple-security/v1/two-fa/v2/do_not_ask_again and .../skip_onboarding — whose permission callbacks validate only the login_nonce (proof the password step succeeded) without checking whether the email OTP challenge was actually answered. An attacker who already holds valid credentials can POST that nonce to either endpoint and receive a fully authenticated WordPress session cookie, completely skipping the one-time-password step. Worse, the do_not_ask_again endpoint silently disables every 2FA provider on the victim account, ensuring persistence. The plugin has 3+ million active installations and the fixed version 9.5.10.1 shipped on April 29, 2026.
The vendor rates this HIGH / 7.5 with AC:H/PR:L, and that is broadly fair. The PR:L correctly captures the requirement for valid credentials — this is *not* an unauthenticated auth bypass like the earlier CVE-2024-10924 (CVSS 9.8). The AC:H accounts for the need to extract the login_nonce from the challenge-page response, though in practice the PoC shows this is trivially automatable with two sequential HTTP requests. The score might slightly overstate real-world risk given the very low EPSS (0.39%), no KEV listing, and no confirmed in-the-wild exploitation — but it correctly reflects the full C:H/I:H/A:H impact once the chain succeeds, since WordPress admin access routinely leads to RCE via plugin/theme file upload.
4 steps from start to impact.
Obtain valid WordPress credentials
- Valid username and password for the target WordPress site
- Target account has email-based 2FA enabled via Really Simple Security
- Requires prior credential compromise — the vuln does NOT bypass password authentication
- WordPress login pages can be protected by rate limiting, CAPTCHA, or IP allowlisting
- Strong unique passwords eliminate this step entirely
Submit credentials and capture login_nonce
/wp-login.php. Because 2FA is enabled, WordPress returns a challenge page containing a login_nonce value rather than an authenticated session. The attacker parses this nonce from the HTML response. This is fully automatable — the PoC by John Umoru demonstrates it with a single curl command.- Network access to the WordPress login endpoint
- Plugin version < 9.5.10.1 installed and active
- WAF rules or geo-blocking may restrict access to wp-login.php
- Some hosting providers block automated login attempts
POST nonce to vulnerable REST endpoint
/wp-json/really-simple-security/v1/two-fa/v2/do_not_ask_again (or skip_onboarding) with the user_id and login_nonce. The endpoint's permission callback validates only the nonce — not whether OTP was answered — and calls wp_set_auth_cookie(), returning a fully authenticated session cookie. The do_not_ask_again variant also disables all 2FA providers on the account.- Valid login_nonce from step 2 (time-limited)
- REST API accessible (enabled by default in WordPress)
- Nonce has a time-to-live window, but the PoC handles this in a single automated flow
- Disabling the REST API or restricting it via plugin/WAF would block this step
Escalate to RCE via admin panel
- Compromised account must have administrator role
- File editing or plugin upload not disabled via
DISALLOW_FILE_EDIT/DISALLOW_FILE_MODS
- Hardened WordPress installations disable file editing in wp-config.php
- Managed hosting platforms often restrict filesystem writes from the admin panel
- EDR or file-integrity monitoring on the web server would flag new PHP files
has_configured_provider() validation that returns HTTP 403 before wp_set_auth_cookie() if an active 2FA provider exists. Current version is 9.8.3. WordPress auto-updates may have already applied this for sites with auto-updates enabled. Per the noisgate mitigation SLA for HIGH, deploy within 30 days; per the noisgate remediation SLA, complete across all instances within 180 days./wp-json/really-simple-security/v1/two-fa/v2/do_not_ask_again and .../skip_onboarding. This directly breaks step 3 of the attack chain. Apply within 30 days per noisgate mitigation SLA for HIGH if patching is delayed.define('DISALLOW_FILE_EDIT', true); and define('DISALLOW_FILE_MODS', true); to wp-config.php prevents admin-panel RCE via theme/plugin editing. This does not prevent the 2FA bypass itself but eliminates the most dangerous post-exploitation escalation path (step 4). Deploy within 30 days.- Disabling 2FA in Really Simple Security — While this technically removes the vulnerable endpoints from being exploitable (the nonce is only generated when 2FA is active), it also removes your second authentication factor entirely, leaving accounts with only password protection. This trades one risk for a worse one.
- WordPress application-level rate limiting alone — Rate limiting on wp-login.php slows credential brute-forcing but does not prevent exploitation when the attacker already has valid credentials from a prior breach. The 2FA bypass itself is a single-request exploit after login.
- Changing the WordPress admin username — Security-through-obscurity for the username does not help because the attacker already needs valid credentials (including the username) as a prerequisite for this vulnerability.
The supporting signals.
| In-the-Wild Status | No confirmed exploitation. Not listed in CISA KEV. No GreyNoise tags or Shadowserver reports observed as of September 2026. The prerequisite of valid credentials makes opportunistic mass exploitation unlikely. |
|---|---|
| Proof of Concept | Public and weaponized. John Umoru published a full Python exploit and manual curl walkthrough at github.com/johnumorujo/published-cves. The PoC automates credential submission, nonce extraction, and 2FA bypass in a single script. No nuclei template confirmed yet; not indexed on pocindex.io as of this assessment. |
| EPSS | 0.00394 (~96th percentile). Very low exploitation probability, consistent with the credential prerequisite reducing mass-exploitation viability. |
| KEV Status | Not listed. No CISA KEV entry. No BOD 22-01 deadline applies. |
| CVSS Vector | CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H — Network-accessible, high complexity (nonce extraction), low privileges required (valid creds), no user interaction. Full CIA impact on the WordPress instance. The AC:H is debatable given the trivial automation shown in the PoC. |
| Affected Versions | Really Simple Security (free, Pro, and Pro Multisite) all versions < 9.5.10.1. The 2FA feature was introduced in version 9.0 (September 2024 rebrand). Versions before 9.0 are not affected because they lack 2FA entirely. |
| Fixed Version | 9.5.10.1 (released April 29, 2026). Current latest is 9.8.3 (September 15, 2026). The vendor changelog described the fix as *"Updated 2FA login flow to address inconsistent verification behavior"* — a deliberately vague silent patch. |
| Install Base & Exposure | 3+ million active WordPress installations. WordPress sites are overwhelmingly internet-facing. However, exploitation requires valid credentials, not just network reachability, which sharply limits the attackable surface. |
| Disclosure Timeline | CVE reserved May 11, 2026. WPScan publication May 12, 2026. NVD/MITRE publication June 2, 2026. Patch shipped April 29, 2026 — fix preceded public disclosure by ~2 weeks. |
| Researcher | John Umoru (finder). Coordinated through WPScan (coordinator). Full writeup and PoC on GitHub. |
Sources.
Why this verdict
- Credential prerequisite is real friction: The attack chain begins with the attacker already possessing valid credentials. This is not an unauthenticated bypass (contrast CVE-2024-10924 at CVSS 9.8). The vulnerability degrades 2FA to single-factor auth — serious, but the hardest step (credential theft) is outside the vuln's scope.
- Public PoC lowers the skill bar: John Umoru's GitHub repo provides a turnkey Python exploit. Once credentials are in hand, exploitation is two HTTP requests. This eliminates any complexity friction for motivated attackers and keeps the score in HIGH territory.
- 3M+ installs but low exploitation probability: The large install base means many potentially vulnerable sites, but EPSS at 0.00394 and zero KEV/GreyNoise/exploitation signals after 5 months of disclosure indicate this is not being weaponized at scale. The credential prerequisite makes spray-and-pray impractical.
- Role multiplier: WordPress is typically deployed as a *web content platform* — not in identity, hypervisor, CI/CD, or domain-controller roles. Blast radius is site-level (content manipulation, defacement, potential RCE on the web server) and host-level at worst. It does not meet the high-value-role floor for CRITICAL. In enterprise environments managing 10,000 hosts, WordPress instances are a small fraction of the fleet (typically single-digit servers), and admin compromise does not cascade to domain or fleet-level impact.
- Silent patch shipped early: The fix landed April 29, 2026 — two weeks before WPScan disclosure. Organizations on auto-update (WordPress default for minor plugin releases) may already be patched. Current version is 9.8.3, four major releases ahead of the fix.
Why not higher?
This is not CRITICAL because the vulnerability requires valid credentials as a prerequisite — it is a 2FA bypass, not an authentication bypass. The blast radius is confined to the individual WordPress site and its underlying host, not fleet-scale or identity-scale. WordPress is not a canonically high-value-role component in enterprise architecture. There is no evidence of active exploitation, no KEV listing, and EPSS is very low. The earlier CVE-2024-10924 in the same plugin *was* CRITICAL (9.8) precisely because it required no credentials.
Why not lower?
Despite the credential prerequisite, this remains HIGH because credentials are routinely compromised via phishing, breaches, and stuffing — 2FA exists precisely to mitigate that scenario. A public, trivially weaponizable PoC is available. The do_not_ask_again endpoint silently disables all 2FA providers, granting persistence. WordPress admin access commonly leads to RCE via file upload. With 3M+ installations, even a small percentage of vulnerable sites represents tens of thousands of targets.
Crowdsourced verification payload.
Run this script on the WordPress host with read access to the wp-content/plugins directory. Invoke as: bash check_cve_2026_8293.sh /var/www/html (pass the WordPress root path as the first argument). No elevated privileges required beyond filesystem read access to the plugin directory.
#!/usr/bin/env bash
# CVE-2026-8293 Checker - Really Simple Security 2FA Bypass
# Checks whether the installed plugin version is vulnerable.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -uo pipefail
WP_ROOT="${1:-/var/www/html}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/really-simple-ssl"
FIXED="9.5.10.1"
if [ ! -d "$PLUGIN_DIR" ]; then
echo "UNKNOWN - Really Simple Security plugin not found at $PLUGIN_DIR"
exit 2
fi
# Extract version from main plugin header
VER=$(grep -iP '^\s*\*?\s*Version:\s*' "$PLUGIN_DIR/really-simple-ssl.php" 2>/dev/null \
| head -1 | sed 's/.*[Vv]ersion:[[:space:]]*//' | tr -d '[:space:]')
# Fallback to readme.txt stable tag
if [ -z "$VER" ]; then
VER=$(grep -iP '^Stable tag:' "$PLUGIN_DIR/readme.txt" 2>/dev/null \
| head -1 | sed 's/.*[Tt]ag:[[:space:]]*//' | tr -d '[:space:]')
fi
if [ -z "$VER" ]; then
echo "UNKNOWN - Could not determine plugin version"
exit 2
fi
# Compare versions using sort -V
lowest=$(printf '%s\n%s\n' "$VER" "$FIXED" | sort -V | head -1)
echo "Detected version: $VER"
echo "Fixed version: $FIXED"
if [ "$VER" = "$FIXED" ] || [ "$lowest" = "$FIXED" ]; then
echo "PATCHED - Version $VER >= $FIXED"
exit 0
else
echo "VULNERABLE - Version $VER < $FIXED (CVE-2026-8293)"
exit 1
fi