Kumar Deepansh

Home / Blog

wp2shell: the WordPress core flaw of July 2026 and what to do

By Kumar Deepansh ·

wp2shell is a chain of two bugs in WordPress core (CVE-2026-63030 and CVE-2026-60137) that let an unauthenticated attacker run code on a default install, with no plugins needed. WordPress fixed it on July 17, 2026 in versions 6.9.5 and 7.0.2. If your site runs 6.9.0 to 6.9.4 or 7.0.0 to 7.0.1 and was not updated, update now and check for signs of compromise.

What happened with wp2shell?

On July 17, 2026, WordPress shipped a security release (7.0.2) that fixed two issues. One was a REST API batch-route confusion bug combined with SQL injection that can lead to remote code execution. It was reported by Adam Kues at Assetnote / Searchlight Cyber. The other was a facilitated SQL injection issue reported by TF1T, dtro and haongo.

The two CVEs are:

  • CVE-2026-63030: the REST API batch-route confusion flaw, introduced in WordPress 6.9.
  • CVE-2026-60137: an SQL injection in the author__not_in parameter of WP_Query.

Neither one alone gives unauthenticated code execution. Chained, they can lead to an administrator account being created, followed by a malicious plugin upload, according to Rapid7. The entry point is the REST API batch endpoint at /wp-json/batch/v1.

Exploitation followed quickly. Public proof-of-concept code appeared on GitHub. Wiz reported exploitation in the wild on July 20, and both CVEs were added to CISA’s Known Exploited Vulnerabilities catalog on July 21, per Rapid7.

Which WordPress versions are affected?

Branch Affected Fixed in
Before 6.8 Not affected No action needed
6.8 SQL injection only (CVE-2026-60137), cannot be chained to RCE 6.8.6
6.9 6.9.0 to 6.9.4, full chain 6.9.5
7.0 7.0.0 to 7.0.1, full chain 7.0.2

WordPress.org also backported the fixes to older branches as a courtesy, but only the most recent version is actively supported. The 6.8 branch is not exposed to the full chain because the batch-route bug arrived in 6.9.

Searchlight Cyber said the attack works against a stock install with no plugins. Rapid7 relays a Cloudflare note that the vulnerable path is reachable when a persistent object cache is not in use. I have not tested that condition myself, so do not treat an object cache as protection.

How do I check if my site is affected?

  1. Log in to the dashboard and open Dashboard, then Updates. The current version is shown at the top.
  2. Compare it with the table above. Anything from 6.9.0 to 6.9.4 or 7.0.0 to 7.0.1 was vulnerable.
  3. If you cannot log in, check your host’s control panel or the version file on the server. Do not rely on the version shown in the public page source, since many sites hide it.
  4. Searchlight Cyber launched wp2shell.com, where admins can test whether an install is vulnerable. I did not open that tool, so check it yourself before relying on it.

WordPress.org enabled forced updates through the auto-update system for affected versions, so many sites patched themselves. Rapid7 still advises verifying that each internet-facing site actually reached a fixed release.

What should I do right now?

  1. Update. Go to Dashboard, Updates, Update Now. Or download the fixed release from WordPress.org. Take a backup first if you can, but do not delay the update for long.
  2. If you cannot update today, use a temporary mitigation. Block /wp-json/batch/v1 and ?rest_route=/batch/v1 at your firewall, or install a plugin that disables anonymous REST API access. Searchlight Cyber describes these as stopgaps only.
  3. Cloudflare users: Cloudflare deployed WAF rules for both CVEs on all plans for proxied sites, but states they are not a substitute for patching.
  4. Check for compromise, because patching does not remove a backdoor that was already planted. See the next section.

How do I tell if my site was already compromised?

Wiz documented what attackers did after exploiting the chain on cloud-hosted sites. Look for these:

  • Batch endpoint hits. Search your access logs for /wp-json/batch/v1 and /?rest_route=/batch/v1. Wiz calls HTTP 207 or 200 responses to those requests a high-fidelity indicator.
  • User-agent strings containing wp2shell or rezwp2shell.
  • Plugin uploads. Requests to /wp-admin/plugin-install.php?tab=upload and POST /wp-admin/update.php?action=upload-plugin.
  • User enumeration. Requests to /wp-json/wp/v2/users?context=edit.
  • Config probing. Requests like admin-ajax.php?template=../../../wp-config.
  • Unknown admin accounts. Check Users for any administrator you do not recognize.
  • Unknown plugins or PHP files. Wiz observed a one-line eval webshell that returns a 404 to hide, a roughly 150 KB webshell disguised as a plugin, and a malicious plugin that registers a REST route under the morning/v1 namespace and runs commands through passthru.

Wiz also published webshell file hashes and exploitation IP addresses on its blog if you want to match against logs. Wiz noted that no lateral movement or data exfiltration had been identified at the time of writing, but that is a snapshot from July 20.

A clean log does not prove a clean site. If you find any of the signs above, assume the server is compromised, not just WordPress.

What do I do if I find a backdoor?

When I clean a site like this, the order matters:

  1. Take a full copy of the site and logs for evidence before changing anything.
  2. Put the site in maintenance mode or block public traffic.
  3. Update core to a fixed version.
  4. Remove unknown admin users and unknown plugins. Reinstall core files and every plugin and theme from clean sources instead of trying to edit infected files.
  5. Rotate everything: all WordPress passwords, the database password, the salts and keys in wp-config.php, and hosting and SFTP credentials.
  6. Check the database for injected content and scheduled tasks, then restore from a backup taken before the exploit date if the damage is deep.
  7. Turn on automatic updates for core and set up monitoring so the next patch does not depend on someone noticing.

If the site is business critical and you are not sure it is clean, a rebuild on a fresh server from known-good files is often faster than hunting for every leftover.

FAQ

Do I need plugins installed to be vulnerable to wp2shell?

No. Searchlight Cyber says the chain works against a default install with no plugins, because the flaws are in WordPress core itself.

Was WordPress 6.8 vulnerable?

Only to the SQL injection (CVE-2026-60137), which cannot be chained to remote code execution on that branch. WordPress released 6.8.6 with the fix, and versions before 6.8 are not affected.

Did my site update itself?

Possibly. WordPress.org forced updates through the auto-update system for affected versions, but a site with auto-updates disabled or blocked by the host may not have moved. Confirm the version in the dashboard.

Is updating enough if I was already exploited?

No. Updating closes the hole but does not remove a webshell, a rogue admin or a malicious plugin that was already installed. Check logs and files as described above.

Sources