CVE-2026-64638: WordPress 7.0.3 Login Page Pre-Auth XSS2Shell, One-Click Admin Compromise
WordPress 7.0.3 (6 Aug) patches CVE-2026-64638, a CVSS 8.9 pre-auth reflected XSS on the login-failure page affecting all versions. pwn.ai demonstrated an XSS2Shell chain to admin session theft and PHP RCE.
WordPress 7.0.3, released 6 Aug 2026, patches a pre-auth reflected XSS on the login page. CVE-2026-64638, CVSS v3.1 8.9. Found by pwn.ai, who publicly demonstrated an XSS2Shell chain from XSS through to PHP code execution. Affects all WordPress versions. Patch is backported to the 4.7 branch. Sites without automatic background updates must upgrade immediately.
Incident overview
CVE-2026-64638 triggers on the login-failure error page that echoes the failed username. WordPress runs the submitted failed username through `sanitize_user()` and `wp_strip_all_tags()` before echo. Both depend on PHP `strip_tags()`, which does not strip pseudo-tag strings with whitespace after the angle bracket, e.g. `< img src=x >`. `wp_kses_post()` then re-parses the content as valid HTML, injecting attacker-controlled DOM nodes into the failed-login page. Same-origin method execution (SOME) + JSONP reflection + Application Password approval chain lets the attacker upload a WebShell and execute arbitrary PHP after one admin click on a malicious link.
Technical details and attack vector
- Reflection injection point: login error page `wp-login.php?error=` and the failed-username echo path.
- Dual-parse bypass: first-pass `strip_tags` misses forged HTML nodes introduced by whitespace; second-pass `wp_kses_post` reinterprets them as valid HTML, causing DOM injection.
- Same-origin function call: attacker overrides the `ajaxurl` variable and bypasses an `undefined` comparison from missing input, then drives WordPress `user-profile.js` to send same-origin REST requests.
- JSONP reflection: anonymous REST requests still return 401, but REST `_envelope=1` wraps the error body as HTTP 200; jQuery continues to parse it as script.
- Session upgrade: SOME chain invokes the logged-in admin's native Application Password approval control in another window, minting revocable API credentials. Those credentials publish a new page to obtain the plugin-upload nonce, then upload an arbitrary ZIP without activation. Direct `require` of the extracted PHP triggers code execution.
- CSP ineffective: researchers note nonce-based `strict-dynamic` does not block this chain.
Impact
- CVSS 3.1: 8.9 (High), vector `AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L`.
- Exploit prerequisite: unauthenticated remote attacker runs targeted phishing. One click by a logged-in admin on a malicious link yields session privileges in the victim browser context and eventually PHP execution.
- Practical impact: read database passwords from `wp-config.php`, create admin accounts, upload arbitrary PHP WebShells, then RCE on the WordPress host. Does not require stealing the admin password.
- Scope: all WordPress sites not upgraded to 7.0.3 and not on a backported 4.7+ branch. Hundreds of millions of blogs, corporate sites, stores, and media portals worldwide.
Remediation
- Upgrade immediately: WordPress core to 7.0.3. If on an older branch, confirm backport coverage (≥4.7).
- Temporary mitigation: at the reverse proxy, block URL-parameter injection on `wp-login.php` for untrusted clients. Enable WAF rules that validate `Origin/Referer` and intercept payloads combining `<` with whitespace.
- Session audit: check `wp_users` for unknown admin accounts; review Application Password lists and revoke unauthorized credentials; inspect `wp-content/plugins` and `uploads` for newly appeared suspicious ZIP and PHP files.
- Detection: monitor access logs for the failed-login error page; flag anomalous `User-Agent` and source IPs on failure responses.
Sources
- WordPress 7.0.3 official security release notes
- The Hacker News: CVE-2026-64638 chain-exploit analysis
- Patchstack: WordPress 7.0.3 12-vulnerability details
- NVD CVE-2026-64638