Skip to main content
saaswp2shellcve-2026-63030 +5

wp2shell: Why a Public WordPress Patch Is Now a Race Against the Clock

wp2shell chains two WordPress core CVEs into unauthenticated RCE. Understand which versions 6.8–7.0 carry the full exploit chain and what agencies must do now.

A single anonymous HTTP request can pop code execution on a stock WordPress install with zero plugins — no login, no misconfiguration, no exotic setup. That’s the reality of wp2shell, the two-CVE chain disclosed against WordPress 6.9 and 7.0, and in open-source security, the patch itself is the exploit roadmap. WordPress shipped 6.9.5 and 7.0.2 on Friday and turned on forced updates. A working proof-of-concept hit GitHub within a day.

How Two Small Bugs Became Unauthenticated RCE

The wp2shell chain is two distinct flaws with two distinct CVE IDs: CVE-2026-63030, a REST API batch-route confusion in WordPress core, and CVE-2026-60137, a SQL injection in WP_Query’s author__not_in parameter. Adam Kues at Assetnote (Searchlight Cyber’s attack surface arm) reported the batch bug via WordPress’s HackerOne program; the injection was reported separately by TF1T, dtro, and haongo.

The mechanism, per the Searchlight writeup, is almost embarrassingly simple. Hand author__not_in a string instead of an array, and the array-shaped validation gets skipped, dropping raw input into the SQL query. Reaching that parameter without a login is where the /wp-JSON/batch/v1 endpoint comes in: it runs multiple sub-requests and tracks them in two parallel arrays. If one sub-request errors, the arrays desync by one, and a request executes under another handler’s allow-list. Nested correctly, an anonymous caller walks right past the endpoint’s guardrails and into the vulnerable query.

This isn’t a plugin ecosystem problem or a misconfiguration story — it’s a bare-metal core RCE that reaches any default install in the vulnerable range. If you’re a hosting provider or an agency running a fleet of WordPress sites, you’re not filtering this by “which customers installed sketchy plugins” — you’re filtering by version string. The chain requires no preconditions.

Our take: expect the next round of core-hardening proposals to target the batch endpoint’s error handling specifically. Parallel-array bookkeeping in a security boundary was a footgun waiting for a foot.

Which Versions Actually Ship the RCE Path

The two bugs don’t line up on the same version range, and confusing that is how teams end up patching the wrong thing. The SQL injection goes back to 6.8; the batch-route confusion only exists from 6.9 onward — the piece that upgrades a bounded injection into unauthenticated RCE. So the exposure splits three ways: 6.8.0–6.8.5 gets the injection only (fixed in 6.8.6), while 6.9.0–6.9.4 and 7.0.0–7.0.1 carry the full RCE chain (fixed in 6.9.5 and 7.0.2 respectively).

Searchlight’s post cites the familiar “over 500 million websites run WordPress” figure, but that’s the total install base, not the exposed set. The RCE chain only exists from 6.9, which shipped December 2, 2025. Every site vulnerable to the code-execution path is running a release less than eight months old, and no advisory quantifies how many that is.

If you’re running a WordPress 6.8.4 site behind a compliance boundary — say, a healthcare content portal or a supply chain vendor microsite — you need 6.8.6 for the injection, but you are not on the RCE path. If you took the 6.9 upgrade in December to get the new features, you are, and you need 6.9.5 immediately. Teams building regulated healthcare software should treat this as a mandatory-patch event even where CMS content looks non-critical, because unauthenticated RCE is a pivot into whatever else that host touches.

Our take: agencies that never document which sites they upgraded to 6.9 are about to discover they don’t actually know their exposure.

Why the CVSS Scores Are Misleading You

Read the scores carefully, because the numbers invert the intuition. WordPress’s own advisory rates the RCE chain Critical, but the CVE record scores it 7.5 — only High — and credits data access alone, not the integrity or availability loss you’d expect from code execution. The SQL injection scores higher than 9.1, Critical.

So the bug everyone is calling a critical RCE is, by its own number, the lesser of the two, because the scoring system rewards the injection’s direct database reach and treats the route confusion in isolation as a parsing flaw. If your patch prioritization pipeline auto-sorts by CVSS, wp2shell’s RCE half may sit below yesterday’s noisy library CVEs. Track both IDs, not the label on either.

One caveat narrows the blast radius: per Cloudflare, which shipped WAF rules alongside the disclosure, the code-execution path only works when the site is not running a persistent object cache. Default installs have no such cache, so default exposure stands. A site fronting WordPress with Redis or Memcached as a persistent object cache dodges this specific RCE path — but that’s a side effect, not a mitigation, and it doesn’t touch the SQL injection at all.

Our take: expect CVSS scoring committees to face renewed pressure to score exploit chains as first-class entities, not just their component parts. The current system encourages defenders to underrate the exact class of bug that matters most.

The Patch Is the Exploit Map

WordPress core is open source, and the release notes name the files it touched. Searchlight held its own technical writeup and pointed owners at a checker at wp2shell.com. It didn’t matter. Within a day, other researchers had read the patch diff, published the mechanism, and shipped a working PoC on GitHub. You cannot ship the fix without shipping the map to the bug.

Mass exploitation of WordPress is an established industry. Before its server leaked in June, the WP-SHELLSTORM crew claimed more than 17,000 compromised sites via one caching-plugin flaw — a bug that was already public, already patched, and only worked in a non-default setting. wp2shell is public, patched, and works on the default setting. Rapid7 says authenticated checks for InsightVM and Nexpose land July 20. CISA hasn’t added it to the KEV catalog yet — that requires confirmed exploitation — but that’s cold comfort.

If you can’t update today, Searchlight’s stopgaps all target the batch endpoint: WAF rules must block both /wp-JSON/batch/v1 and rest_route=/batch/v1 (a rule covering only the path leaves the query-string route open), or disable the REST API wholesale, or install the drop-in plugin that rejects anonymous /batch/v1 requests at rest_pre_dispatch. All can break legitimate integrations. All are temporary.

Our prediction: within two weeks, opportunistic scanners will hit /batch/v1 at a rate comparable to historical Log4Shell-era WordPress campaigns, and the sites still on 6.9.0–6.9.4 will be the ones that turned off auto-updates for “stability.” WordPress’s version stats and batch/v1 scan traffic will tell the story of which curve moved faster.

FAQ

Q: What is wp2shell and which WordPress versions are affected? A: wp2shell is the name for a chained exploit combining CVE-2026-63030 (REST API batch-route confusion) and CVE-2026-60137 (SQL injection in WP_Query). The full unauthenticated RCE chain affects WordPress 6.9.0–6.9.4 and 7.0.0–7.0.1. Versions 6.8.0–6.8.5 have the SQL injection only. Patches: 6.8.6, 6.9.5, and 7.0.2.

Q: Am I safe if I use a persistent object cache? A: The code-execution path only works when no persistent object cache is running, per Cloudflare, so sites using Redis or Memcached as a persistent cache dodge the RCE path. But that’s a coincidence of your architecture, not a fix — the underlying SQL injection remains exploitable. Patch anyway.

Q: What should WAF rules look like if I can’t patch immediately? A: Block both /wp-JSON/batch/v1 and rest_route=/batch/v1 at the edge. A rule covering only the path route leaves the query-string variant wide open. Cloudflare’s managed WAF ships this coverage; other WAFs may need manual rules.

Key Takeaways

  • Prioritize by exploit chain, not CVSS component scores — wp2shell’s “7.5 High” RCE component understates the real risk, and any team relying on auto-sorted vuln queues will deprioritize the wrong bug.
  • Inventory your WordPress version strings now: the exposure boundary sits at 6.9.0, and agencies without version-tracking discipline can’t answer basic exposure questions during an active PoC window.
  • Treat open-source security patches as public exploit roadmaps by default — plan disclosure-day patching windows around the assumption that PoCs land within 24 hours, because they now do.
  • If you architect content or supply chain workflows that depend on WordPress as a front door, isolate the CMS from downstream systems so an unauthenticated RCE becomes a contained incident, not a pivot.
  • Watch the ratio between WordPress version-stats uptake and batch/v1 scan traffic over the next two weeks — the steeper curve decides whether wp2shell is a footnote or the next WP-SHELLSTORM.

Have a project in mind?

Tell us what you're building — we reply within 24 hours.