Follow Cyber Kendra on Google News! | WhatsApp | Telegram

Add as a preferred source on Google

WP2Shell (CVE-2026-63030): Checker, Patch & Detection Guide

Is your WordPress site vulnerable to WP2Shell? Instant version checker, patch steps, WAF rules, detection scripts and IOCs for CVE-2026-63030
The 20-second version: WP2Shell is a pre-authentication remote code execution (RCE) chain in WordPress core — no plugin required, no login required. It affects WordPress 6.9.0–6.9.4 and 7.0.0–7.0.1. WordPress shipped emergency fixes on 17 July 2026: update to 7.0.2, 6.9.5, or 6.8.6 right now. Public exploit code exists. If you can't patch this minute, block /wp-json/batch/v1 and ?rest_route=/batch/v1 at your WAF. Scroll down for a version checker, patch steps, WAF rules, detection scripts and indicators of compromise.

Is my site affected? (Instant checker)

Type your exact WordPress version (find it in Dashboard → Updates, or the bottom-right of your admin screen) and hit check. Everything runs in your browser — nothing is sent anywhere.

Prefer an external second opinion? Searchlight Cyber (the team that found the bug) runs a free tester at wp2shell.com that probes your live site. You can also check our wp2shell vulnerability checker tool.

The facts at a glance

ItemDetail
NameWP2Shell (a.k.a. "wp2shell")
CVE IDsCVE-2026-63030 (REST API batch-route confusion → RCE) chained with CVE-2026-60137 (SQL injection in core)
TypeUnauthenticated / pre-auth Remote Code Execution
PreconditionsNone. Works against a stock install with zero plugins.
Affected (RCE)WordPress 6.9.0–6.9.4 and 7.0.0–7.0.1 (plus 7.1 beta1)
Affected (SQLi only)WordPress 6.8.0–6.8.5 — vulnerable to CVE-2026-60137 but not the full RCE chain
Not affectedAnything below 6.8.0
Fixed in7.0.2, 6.9.5, 6.8.6 (released 17 July 2026)
Entry pointThe REST batch endpoint: /wp-json/batch/v1
Discovered byAdam Kues, Searchlight Cyber
ExposureWordPress powers 500M+ sites; forced auto-updates were enabled for affected installs

How WP2Shell actually works

WordPress 6.9 introduced a REST batch endpoint — a convenience feature that lets a client bundle several API calls into one request. The flaw is a route-confusion bug: the batch handler can be tricked into resolving inner requests to routes it shouldn't, in a context where the normal permission checks don't apply the way you'd expect.

On its own that's a nasty logic bug. The problem is what it can reach: a second vulnerability, an SQL injection in core (CVE-2026-60137), that an anonymous request can now touch through the batch route. Chain the two together and an attacker walks a completely unauthenticated request from "hello, I'm nobody" all the way to running SQL — and from there to code execution on the server. That's the "2shell" in the name: WordPress to shell, no account needed.

The reason the security community is treating this as a five-alarm fire isn't cleverness — it's reach. There is no plugin dependency, no unusual configuration, no authenticated user required. If you're on an affected version and reachable from the internet, you're in scope. That's why WordPress.org took the rare step of forcing auto-updates.

Patch it — the 5-minute fix (do this first)

Patching is the only real fix. Mitigations below are stopgaps; this is the cure.

  1. Back up first. Snapshot your database and files (your host's one-click backup is fine). Core updates rarely break anything, but you want a rollback point.
  2. Go to Dashboard → Updates. If WordPress already auto-updated you (many sites did), you'll see you're on 7.0.2 / 6.9.5 / 6.8.6 — you're done, jump to detection to make sure you weren't hit before the patch landed.
  3. Click "Update Now." Land on the fixed release for your branch:
    • On the 7.0 branch → 7.0.2
    • On the 6.9 branch → 6.9.5
    • On the 6.8 branch → 6.8.6 (fixes the SQLi; consider moving to a current branch after)
  4. Confirm the version. Don't assume — check the number in your dashboard footer after the update completes.

Prefer the command line? With WP-CLI:

wp core update wp core version # confirm you're on 7.0.2 / 6.9.5 / 6.8.6 wp core verify-checksums # confirm core files weren't tampered with

That last command is doing double duty: verify-checksums compares your core files against WordPress.org's official hashes, so if an attacker modified a core file before you patched, it'll flag the mismatch.

Can't patch right now? Emergency mitigations

Maybe you have a fragile custom build, a change-freeze, or 200 sites to coordinate. These buy you time — they are not a permanent fix, and each can interfere with legitimate REST traffic. You must block both forms of the route; blocking only the pretty path leaves the query-string version wide open.

Option A — Block at your WAF / CDN

Block requests to both of these:

/wp-json/batch/v1 ?rest_route=/batch/v1

If you're behind Cloudflare, you already have automatic protection — Cloudflare deployed managed WAF rules for both CVEs across all plans, including free, for proxied sites. It's still worth patching; a WAF rule is a filter, not a fix.

Option B — Drop-in "must-use" plugin (no WAF needed)

Create wp-content/mu-plugins/block-batch.php with this. It rejects anonymous calls to the batch route while leaving logged-in admin traffic alone:

<?php /** * Emergency WP2Shell mitigation — blocks anonymous access to the REST batch route. * TEMPORARY. Remove after updating to 7.0.2 / 6.9.5 / 6.8.6. */ add_filter('rest_pre_dispatch', function ($result, $server, $request) { $route = $request->get_route(); if (strpos($route, '/batch/') !== false && !is_user_logged_in()) { return new WP_Error( 'rest_forbidden', 'Batch endpoint temporarily disabled (WP2Shell mitigation).', array('status' => 403) ); } return $result; }, 0, 3);

mu-plugins load automatically and can't be deactivated from the dashboard, which is exactly what you want for an emergency control. Delete the file once you've patched.

Were you already hit? Detection & log-hunting

Because public exploit code circulated quickly, patching doesn't answer the real question: did someone reach me first? Here's how to check.

1. Hunt your access logs for batch-endpoint abuse

The earliest signal is traffic to the batch route, especially with suspicious SQL-ish parameters. On most Apache/Nginx hosts:

# Any hits on the batch endpoint (both route forms) grep -Ei "batch/v1" /var/log/nginx/access.log* # Higher-signal: batch traffic carrying SQL injection markers grep -Ei "batch/v1" /var/log/nginx/access.log* \ | grep -Ei "author_?_?not_?_?in|author_exclude|SELECT|SLEEP\(|SUBSTRING|CHAR_LENGTH|UNION" # POSTs to the batch route (the exploit is a POST) grep -Ei "POST .*(batch/v1|rest_route=/batch)" /var/log/nginx/access.log*

Anomalous author__not_in / author_exclude values containing SQL keywords are one of the cleanest early indicators of an exploitation attempt against this chain.

2. Look for dropped web shells

Successful exploitation typically drops a PHP payload. Scan for recently-changed or suspicious PHP files:

# PHP files created/modified in the last 7 days under your webroot find /var/www/html -name "*.php" -mtime -7 -print # Classic web-shell function calls hiding in your uploads/plugins grep -RilE "eval\(|base64_decode\(|system\(|shell_exec\(|passthru\(|assert\(" \ /var/www/html/wp-content/uploads /var/www/html/wp-content/plugins # PoC-tool artifacts: rogue plugin folders/zips named like wp2shell-xxxxxxxx find /var/www/html/wp-content/plugins -iname "wp2shell*" -print

3. Verify core integrity

wp core verify-checksums # Any "File doesn't verify against checksum" line = investigate that file immediately.

4. Check the database for injected admin users / options

# New admin accounts you don't recognise wp user list --role=administrator --fields=ID,user_login,user_email,user_registered # Suspicious auto-loaded options (common persistence spot) wp option list --search="*eval*" --autoload=on

Indicators of Compromise (IOC)

The following are associated with public WP2Shell proof-of-concept tooling. Treat them as leads, not proof — they're trivial for an attacker to change, and some payloads self-delete after running, so their absence doesn't clear you. Use them to prioritise investigation, alongside the log and file checks above.

CategoryIndicator
Target endpointsPOST to /wp-json/batch/v1 or /?rest_route=/batch/v1
Request bodyNested requests[] arrays with malformed http:// / http:: paths
SQLi markersauthor_exclude / author__not_in values containing SELECT, IF, SLEEP, SUBSTRING, CHAR_LENGTH
User-Agentswp2shell-check/1.0, wp2shell-poc/1.0
Multipart boundaryBoundaries beginning ----wp2shell
Dropped filesPlugin ZIPs named wp2shell-<8-hex>.zip; files/dirs under wp-content/plugins/wp2shell-*
Command channelRequests containing ?tok=<token>&c=<command>; cleanup requests with &rm=1
Response markersResponses containing WP2SHELL_OUT_START / WP2SHELL_OUT_END

If you find evidence of compromise: assume full server compromise. Patching does not evict an attacker who already has a shell. Take the site offline, rotate all secrets (database password, wp-config.php salts, API keys, admin passwords), restore from a known-clean pre-incident backup, then patch before bringing it back. When in doubt, engage an incident-response professional.

Public PoC code & research resources

Use responsibly. The repositories below contain working exploit code and are listed for defenders, researchers and penetration testers to understand and test the flaw on systems they own or are authorised to assess. Running exploits against a site you don't control is illegal in most jurisdictions. All links are external and open in a new tab. WatchTowr has reported in-the-wild exploitation, so treat any unpatched, internet-facing install as a live target.
ResourceTypeWhat it is
0xsha/wp2shell PoC (Python) Single-file, stdlib-only tool that unifies several public PoCs; forges a post via the UNION confusion, creates an admin, and drops a token-gated webshell. Verified end-to-end in-lab.
Icex0/wp2shell-poc PoC (Python) Independent PoC for the batch-route SQLi chain with three modes: check (confirms the SQLi path), read (DB read), and shell (plugin-backed command shell).
mverschu/CVE-2026-63030 PoC (Exploit) PoC exploit for the unauthenticated RCE; documents affected 6.9.0–6.9.4 / 7.0.0–7.0.1 and fixes in 6.9.5 / 7.0.2.
ProjectDiscovery Nuclei template Detection Community Nuclei template for non-intrusive detection of WP2Shell across many hosts at once (search the repo for “wp2shell” / CVE-2026-63030).
ZSec – Code Trace Deep Dive Analysis Line-by-line trace of how the batch route confusion reaches the author__not_in SQL injection. Best read for understanding the root cause.
Rapid7 – Emergent Threat Report Analysis Vendor breakdown of the chain, exploitation status and detection guidance.
Searchlight Cyber advisory Primary source The original disclosure from the team (Adam Kues) that found the bug.
wp2shell.com Live checker Searchlight's hosted tool that tests whether a live instance is exposed. Occasionally offline under load.

Repositories can be renamed or taken down without notice, and GitHub may remove PoCs that violate its policies — if a link 404s, search GitHub for “wp2shell” or “CVE-2026-63030” for current mirrors. We only link to code already public and widely cited by mainstream security outlets.

WP2Shell FAQ

What WordPress versions are vulnerable to WP2Shell?

The full remote code execution chain affects WordPress 6.9.0 through 6.9.4 and 7.0.0 through 7.0.1. WordPress 6.8.0–6.8.5 is affected by the underlying SQL injection (CVE-2026-60137) but cannot be driven to full RCE because the vulnerable batch route was introduced in 6.9. Versions below 6.8.0 are not affected. Fixed releases are 7.0.2, 6.9.5 and 6.8.6.

What are the CVE numbers for WP2Shell?

WP2Shell is a chain of two CVEs: CVE-2026-63030 (REST API batch-route confusion leading to RCE) and CVE-2026-60137 (SQL injection in WordPress core). They are exploited together.

Is there a public WP2Shell PoC or exploit?

Yes. Public exploit code and testing tools circulated shortly after disclosure on 17 July 2026, which is why patching immediately is critical. Searchlight Cyber, who discovered the flaw, deliberately withheld deep technical detail at disclosure to give defenders time, but working exploits are now in the wild.

Do I need a plugin to be vulnerable?

No. This is a WordPress core vulnerability. A stock install with no plugins on an affected version is exploitable by an anonymous, unauthenticated attacker.

I'm on Cloudflare — am I safe?

Cloudflare deployed managed WAF rules covering both CVEs for proxied sites across all plans, including free, which blocks known exploitation patterns. That's a strong safety net, but it's a filter, not a fix — you should still update WordPress to the patched version.

How do I know if my site was already hacked?

Search your access logs for POST requests to /wp-json/batch/v1 with SQL-like author_exclude / author__not_in parameters, scan for recently-modified or web-shell PHP files, run wp core verify-checksums, and check for unfamiliar administrator accounts. See the detection section above for exact commands.

Sources & further reading

Post a Comment