Key Takeaways
- WordPress versions prior to 7.0.3 contain a pre‑authentication reflected XSS (CVE‑2026-64638, CVSS 8.9) on the login screen that can be triggered without any credentials.
- The XSS can be chained to remote PHP code execution when an already‑logged‑in administrator visits an attacker‑controlled page and performs a single click.
- Researchers at pwn.ai named the exploit chain XSS2Shell; they reproduced it using open‑source AI models and a multi‑agent workflow in under four days.
- The flaw stems from a bypass of WordPress’s username sanitization, allowing attacker‑controlled HTML to survive through
sanitize_user(),wp_strip_all_tags(), andwp_kses_post(). - The injected DOM elements interact with the
user-profile.jsscript loaded on the login page, hijacking a same‑origin REST request via a clobberedajaxurlvariable and JSONP support. - One demonstrated path abuses the Application Passwords feature to obtain an API credential, upload a malicious ZIP via the plugin‑upload nonce, and execute PHP without needing the admin’s primary password.
- WordPress patched the issue in version 7.0.3 (released August 6) and back‑ported fixes to the 4.7 branch; older versions remain vulnerable and should be upgraded immediately.
- Hardening measures such as strict‑dynamic CSP nonces do not block the exploit; applying the security update is the only reliable mitigation.
Overview of the Vulnerability
WordPress 7.0.2 and all earlier releases contain a reflected cross‑site scripting flaw on the login form that does not require authentication. When a user submits an invalid login, the supplied username is echoed back in the error message. If the username contains a specially crafted string, the script executes in the victim’s browser as soon as the error page loads. Tracked as CVE‑2026-64638 with a CVSS score of 8.9, the bug is classified as high severity because it can be triggered by anyone who can lure a victim to the login page.
How the XSS Bypasses Sanitization
The username first passes through sanitize_user() and then wp_strip_all_tags(), which relies on PHP’s strip_tags(). A payload such as < svg onload=alert(1)> (note the space after the opening <) survives this stage because the parser treats the whitespace‑separated token as plain text. Later, WordPress runs the value through wp_kses_post(), whose separate HTML parser interprets the same token as an allowed element, resulting in live DOM nodes being injected into the failed‑login page. This discrepancy between the two sanitizers is the root cause of the bypass.
Interaction with WordPress‑Loaded JavaScript
The login page also loads user-profile.js, a script intended for profile‑management pages but present because the login screen handles password resets. That script expects two hidden inputs (_wpnonce and _wp_http_referer) and a global ajaxurl variable. On the login page those inputs are missing, causing them to evaluate to undefined. An attacker‑controlled DOM element can therefore satisfy an equality check in the script and overwrite ajaxurl with a pointer to an attacker‑chosen endpoint. Consequently, the script’s subsequent AJAX request is redirected to a URL under the attacker’s control while still appearing same‑origin to the browser.
Exploiting JSONP for Script Execution
WordPress enables JSONP support on its REST API via the _jsonp parameter. By pointing the hijacked ajaxurl to a REST endpoint and appending _jsonp=callback, the response is wrapped in a JavaScript function call, turning a data fetch into script execution in the victim’s origin. If the endpoint returns HTTP 401 for unauthenticated requests, adding _envelope=1 converts the error into an HTTP 200 envelope, allowing jQuery to treat the payload as executable code. This step converts the initial XSS into a foothold for arbitrary JavaScript running with the privileges of the logged‑in user.
From JavaScript to PHP Execution via Application Passwords
pwn.ai demonstrated several routes from the JavaScript foothold to full server‑side code execution. One reliable path abuses the Application Passwords feature, which lets administrators generate revocable API tokens without revealing their main password. The injected script triggers the native Application Password approval UI inside the administrator’s session, causing WordPress to create a new token and redirect it to an attacker‑supplied success_url. The attacker captures the token, then uses it to make authenticated REST calls.
With the token, the script publishes a new post containing a small JavaScript snippet. When the administrator’s session later views that post, the snippet reads the plugin‑upload nonce from the page, uploads an attacker‑provided ZIP file via the standard plugin‑install endpoint, and extracts its contents. Because the upload endpoint does not require the plugin to be activated, the extracted PHP file can be requested directly, achieving arbitrary PHP code execution on the server.
Alternative Chains and Research Methodology
The researchers also showed variants that install a malicious plugin through the REST API or upload an arbitrary ZIP to the media library, both leading to PHP execution. Their discovery process leveraged a multi‑agent AI workflow: starting from Paulos Yibelo’s 2022 Same‑Origin Method Execution (SOME) research, the system iteratively probed WordPress’s codebase, identified the sanitizer bypass, and stitched together the JavaScript‑to‑PHP chain. The entire effort took under four days, and the exploit was reproduced on a clean local WordPress 7.0.2 installation before being reported to the WordPress security team on July 26.
Impact of Successful Exploitation
If an attacker achieves PHP execution, they can read wp-config.php and obtain database credentials, create persistent administrator accounts, modify or delete any content, read files accessible to the PHP process, and execute operating‑system commands with the web‑server’s privileges. Essentially, the whole site—and potentially the hosting environment—becomes under the attacker’s control. The vulnerability therefore poses a severe risk to any WordPress site that has not applied the patch.
Patch Availability and Mitigation Guidance
WordPress addressed the flaw in version 7.0.3, released on August 6, and back‑ported the fix to all maintained branches down to 4.7. Sites running versions older than 4.7 remain exposed and are no longer receiving official back‑ports; upgrading to a supported release is mandatory. While WordPress notes that exploiting the XSS to reach RCE requires social engineering and a logged‑in administrator, the researchers stress that the underlying XSS is unmitigated by common hardening tactics such as strict‑dynamic CSP nonces. Consequently, applying the security update is the only reliable defense. Automatic background updates will deliver the patch to sites that have them enabled; administrators should verify that their installations are running at least 7.0.3 or a newer release.
Conclusion
The CVE‑2026-64638 flaw demonstrates how a seemingly minor reflected XSS, when combined with nuanced JavaScript interactions and legitimate WordPress features, can escalate to full server compromise. The rapid discovery by pwn.ai using AI‑assisted analysis highlights the evolving nature of vulnerability research. Organizations running WordPress must prioritize updating to the patched version, review administrator activity for anomalous behavior, and maintain defense‑in‑depth measures—though patches remain the essential line of defense against this specific attack chain.

