CVE-2026-63030 and CVE-2026-60137: WP2Shell: Pre-Auth RCE in WordPress EITW

Last Updated: 2026-07-22T19:26:12Z

This is now tracked in two separate CVEs: CVE-2026-63030 and CVE-2026-60137. The former is for REST API route confusion/validation failures, and the latter for SQL Injection. Reports are coming in of succesful exploitation in the wild.

CVSSv3: 9.8, 5.9

Searchlight says:

Searchlight Cyber’s security research team has discovered a pre-authentication RCE in WordPress Core. The attack has no preconditions and can be exploited by an anonymous user in a stock install of WordPress with no plugins.

Their disclosure site has a checker you can use to determine site vulnerability.

Affected Versions

Version Status
< 6.9.0 not affected
6.9.0 - 6.9.4 affected, fixed in 6.9.5
7.0.0 - 7.0.1 affected, fixed in 7.0.2

The earliest vulnerable version was released on 2025-12-02, so a 7 month window.

The founder of Hexastrike claims they are seeing successful exploitation in the wild

A reasonable PoC has been posted to GitHub:

Actions

Update to the fixed versions ASAP.

If patching isn’t possible, Searchlight recommends blocking /wp-json/batch/v1 and ?rest_route=/batch/v1 URIs at a WAF level.

Indicators of Compromise

Even with the few details we have, some solid indicators of exploitation are clear.

Type Value Category
URI /wp-json/batch/v1 Network activity
URI ?rest_route=/batch/v1 Network activity

You’re going to see these in site access logs, so make sure you have visibility there.

These and supporting IoCs are in our MISP feed.

Elastic has published a threat hunting guide with more detailed attack indicators.

Notes

Tenable’s advisory links SQL Injection to route confusion in the REST API.

The Patch Diff for the updated version makes the issue clear enough for rapid exploit development. I expect this to become a Problem™ quickly, if it’s validated.

WordFence has a writeup that showed a different CVSS value, so we updated ours.

2 Likes

SQL injection ? Comparing 7.0.1...7.0.2 · WordPress/wordpress-develop · GitHub

1 Like

Maybe! But you know, SQL Injection is not automatically pre-auth RCE, even in vanilla WordPress. So there’d still be some missing pieces there.

The two changes to the batch REST API below that seem directly relevant to the indicators and mitigations mentioned.

Looking at the changes, my guess is a race condition/TOCTOU situation where you can piggyback a legitimate REST request from an authenticated entity with your own unauthenticated one.

Update: not quite. What’s probably closer is careful ordering of legit/illegitimate REST API jobs in batch mode. And this bypasses sanitization due to route confusion. Now the SQLI is accessible, and yeah: database updates, content injections, etc. That seems likely.

2 Likes

Trying to puzzle this together from the 6.9.4 → 6.9.5 diff (subset of 7.0.2 → 7.0.1) ( https://github.com/WordPress/wordpress-develop/compare/6.9.4…6.9.5 ):

  • The class-wp-query.php change is just a straight-forward SQLi if something other than an array is passed as $query_vars['author__not_in'] (reachability of that point… :person_shrugging: )
  • rest-api.php & the first change to class-wp-rest-server.php look like early bails for parallel calls? I am honestly not sure where this plays into this.
  • $matches[] = $single_request;looks interesting - the serve_batch_request_v1 function loops over $requests twice. Pre-patch it failed to append anything to $matches during the first pass, leading to a mismatch of actual request & $match (the handler) entry during the second pass .

The two things that are still open for me are 1. how this actually be triggered - the CVE mentions “which could allow SQL Injection when a plugin or theme passes untrusted input to the parameter”, so this may actually not be universal? and 2. where the bails for parallel calls comes from.

So I think the trick is that the processing of an unvalidated batch job results in the processing of requests with author__not_in payloads, leading to SQLI and then you’re off to the races.

See the top post for a PoC

1 Like

This new vulnerability once again shows the time-to-exploit is down to (less than) a day. At this moment every website owner must assume compromise if this was not automatically updated on the 17th.

My own observation is that the prevalence of exploitable configurations is far lower than 100%. Web application firewalls with up-to-date rules also mitigate attacks.

I also noticed that some of the public exploit scripts or vulnerability checks contain too much filtering, leading to false negative results. Examples are matching a WordPress version before exploitation check and not checking both batch API endpoints.

Aside from the online rumours on active exploitation, I have not yet found a good incident report about follow-up activity. That makes recovery somewhat tricky. Successful credential dumping or implanted backdoors may not be restored or removed if no one knows where to look. I do not think many people will use a safe backups to recover. Let alone do a credential rotation after restoring.

I expect that multiple actors will jump on this and we will likely see a lot of these vulnerable sites join the ClickFix and infostealer ecosystems.

This is common, and I agree that this is going to become yet another vector for ClickFix delivery (and also maybe some gambling proxies).

What you really want in situations like this is monitoring of file writes on the server, so you can hunt for suspicious activity during the vulnerable window. I’m also a big fan of entropy scanning web roots to identify potential web shells—especially in PHP apps.