The security team at pwn.ai just published XSS2Shell, a pre-authentication XSS to remote code execution chain in WordPress Core tracked as CVE-2026-64638. WordPress shipped an emergency patch in 7.0.3 on August 6, and backported it to every maintained branch going back to 4.7.

The full write-up goes deep into DOM clobbering, JSONP, and cross-window scripting, but the part worth knowing as a PHP developer is where it starts: two sanitizers in the same request disagree about what a tag is.

You can watch the full exploit chain here:

The Parser Disagreement

A failed login goes through sanitize_user(), which calls wp_strip_all_tags(), which wraps PHP's strip_tags(). That function only treats < as the start of a tag when a letter follows it immediately. Add a space after the < and PHP no longer sees a tag at all:

strip_tags('< area id=test>');   // '< area id=test>'  survived
strip_tags('<area id=test>');    // ''                 stripped

The resulting error message then travels up to wp-login.php and gets run through wp_kses_post(). KSES has its own tokenizer, and it does handle whitespace after the <, so it reads < area as a valid <area> element. <area> is on the KSES post allowlist along with attributes like id and class, so the string that one sanitizer called plain text comes out the other side as live DOM nodes the attacker picked.

From there the researchers chained the injected elements into WordPress's own user-profile.js handlers, then into an Application Password grant, then into a plugin upload that returned {"rce":true,"user":"www-data"}.

What You Should Do

Update WordPress now. Every version under active maintenance before 7.0.3 is affected, and the bug has been in the code since the earliest releases. If you were already planning to test against WordPress 7.1 RC1, patch production first.

The broader takeaway holds outside WordPress: if you sanitize the same value twice with two different parsers, you inherit the gaps between them. Read the full technical breakdown on pwn.ai for the whole chain.