On July 17, 2026, WordPress dropped 7.0.2 to patch a chain of two vulnerabilities — CVE-2026-60137 (SQL injection) and CVE-2026-63030 (REST API batch route confusion → RCE). The chain is nicknamed WP2Shell. Chained together, on default installations with no plugins involved, it lets a remote attacker with no WordPress account reach full code execution.
If you're running WordPress 6.8 through 7.0.1, you need to update right now. Not next week. Right now.
Update (July 18): two days after disclosure, working proof-of-concept code is now public and Patchstack reported signs of in-the-wild exploitation attempts within hours of the advisory going out. Treat this as actively exploited, not theoretical.
Here's the technical breakdown.
What the Two CVEs Actually Do
CVE-2026-60137 — SQL Injection via WP_Query
The vulnerability lives in WP_Query's handling of the author__not_in parameter. The parameter lacks proper escaping and query preparation, letting an attacker inject arbitrary SQL.
On its own, this bug is narrower than it sounds: reaching it typically requires either an authenticated context, or a plugin/theme that passes untrusted input into author__not_in. It's not directly reachable by an anonymous visitor through stock WordPress core by itself — that's exactly what the second CVE changes.
Affected: WordPress 6.8 through 7.0.1
Patched in: 6.8.6, 6.9.5, 7.0.2
Reported by: TF1T, dtro, and haongo
This isn't a plugin issue — it's core. Every WordPress installation with this version range is exposed.
CVE-2026-63030 — REST API Batch Route Confusion → RCE
This is the more dangerous half of the chain. The REST API batch endpoint (/wp-json/batch/v1) has a route confusion issue (CWE-436) discovered by Adam Kues at Assetnote / Searchlight Cyber. This is what turns CVE-2026-60137 into something an anonymous, unauthenticated attacker can trigger: the route confusion lets a crafted batch request slip past the auth boundary that would normally gate the SQL injection, and reach it with unauthenticated privileges — from there, the SQLi is escalated into RCE.
Important caveat: according to Cloudflare's and SOCRadar's analysis, this RCE path is reachable when a persistent object cache (Redis, Memcached, etc.) is not enabled — which is the WordPress default for most installs, but not universal. If you run a persistent object cache, you're likely at reduced risk for the full RCE chain specifically, though the underlying SQLi in WP_Query is still a real problem worth patching regardless.
Affected: WordPress 6.9.0–6.9.4, 7.0.0–7.0.1
Patched in: 6.9.5, 7.0.2
The batch endpoint itself has shipped by default since WordPress 5.6 (2020); it's the route-confusion bug introduced in 6.9 that opens the door.
Why the Chain Matters
Neither CVE alone reaches the full impact:
CVE-2026-60137 (SQLi) ──→ DB access, but gated behind auth/plugin context
CVE-2026-63030 (route) ──→ bypasses that gate + drives it to code execution
Combined = unauthenticated remote code execution
Rapid7's advisory put it well: "Organizations should not interpret the absence of public exploitation reports as an indication of low risk." That framing has already aged — as of this writing, public PoC code and early signs of exploitation attempts exist. The advice underneath it still holds: don't wait for confirmed mass exploitation before you patch.
Affected Versions
| Branch | CVE-2026-60137 | CVE-2026-63030 | Patch |
|---|---|---|---|
| 6.8.x (< 6.8.6) | ✅ | ❌ | 6.8.6 |
| 6.9.0–6.9.4 | ✅ | ✅ | 6.9.5 |
| 7.0.0–7.0.1 | ✅ | ✅ | 7.0.2 |
| 7.1 beta | ✅ | ✅ | 7.1 Beta 2 |
| < 6.8 | ❌ | ❌ | N/A |
Note: on 6.8.x, only the SQLi (CVE-2026-60137) applies — the route-confusion bug that unlocks unauthenticated RCE was introduced in 6.9. That branch is still worth patching, but it isn't exposed to the full pre-auth WP2Shell chain.
Emergency Mitigation (If You Can't Patch Immediately)
Searchlight Cyber recommends blocking anonymous access to the batch API while you stage the update:
At your WAF/CDN level (Cloudflare, etc.):
# Block the batch endpoint
/wp-json/batch/v1
?rest_route=/batch/v1
Via a plugin: Install a plugin that blocks anonymous REST API access.
Cloudflare users: An emergency managed rule was released July 17, 2026. Check Security → WAF → Managed Rules to confirm it's active.
Running a persistent object cache? You're likely lower-risk for the RCE chain specifically, but this isn't a substitute for patching — the SQL injection itself is still live until you update.
⚠️ Both mitigations may break legitimate site functionality — use only as temporary measures until you patch.
How to Patch
WP-CLI (recommended for ops)
# Back up first
wp db export backup-$(date +%Y%m%d).sql
# Update core
wp core update
# Update database schema if needed
wp core update-db
# Verify
wp core version
# Should show: 6.8.6, 6.9.5, or 7.0.2
Manual via SSH
# Backup
mysqldump -u user -p wordpress_db > backup.sql
# Download and extract
cd /path/to/wordpress
curl -O https://wordpress.org/wordpress-7.0.2.tar.gz
tar -xzf wordpress-7.0.2.tar.gz
# Replace core files (keep wp-content and wp-config.php)
rsync -av wordpress/ ./ --exclude wp-content/ --exclude wp-config.php
# Run database update
wp core update-db
WordPress Dashboard
Dashboard → Updates → Update Now
WordPress has enabled forced auto-updates for affected installations, but verify manually — auto-update can silently fail.
Docker / CI-CD
If you're running WordPress in containers, update your base image tag and redeploy. If you use a build pipeline that pins WordPress versions, update the version pin and trigger a rebuild.
# Before
FROM wordpress:7.0.1-php8.2-apache
# After
FROM wordpress:7.0.2-php8.2-apache
Post-Patch Verification Checklist
After updating, verify your installation is clean:
1. Version check
wp core version
grep '$wp_version =' wp-includes/version.php
2. Check for new admin accounts
wp user list --role=administrator
3. Look for recently modified core files
# Find PHP files modified in the last 7 days
find /path/to/wordpress -name "*.php" -mtime -7 -type f | \
grep -v wp-content/uploads
4. Database audit
wp db query "SELECT user_login, user_email, user_registered \
FROM wp_users WHERE user_registered > '2026-07-01'"
5. Log analysis
Search your access logs for POST requests to /wp-json/batch/v1 from unknown IPs, particularly around and after July 17, 2026, and watch specifically for anomalous author__not_in parameter values — that's the earliest indicator of exploitation attempts against this chain.
6. WAF rule status
If you're behind Cloudflare, verify the emergency managed rule for this CVE chain is active in your dashboard.
What This Means for Your Deployment Pipeline
If you're managing WordPress at scale — multiple installs, staging environments, client sites — this should trigger:
- Inventory audit: Which of your installs are running 6.8–7.0.1? You need a definitive list.
-
Automated patching: If you don't have automated WordPress updates, this is the push to set them up. The
WP_AUTO_UPDATE_COREconstant orwp auto-update enableCLI command handles this. - Staging-first policy: Update staging, test, then roll to production. But given that PoC code is already public, don't let the staging test delay the patch by more than a few hours on anything internet-facing.
- Monitoring: After patching, monitor logs for 48–72 hours for indicators of pre-patch compromise, especially around the disclosure window (July 17–19).
The Broader Pattern
This isn't an isolated incident. WordPress core vulnerabilities are rare, but when they hit, they hit hard because of the sheer install base. The pattern we're seeing in 2026:
- Core vulnerabilities (not just plugins) are being discovered and weaponized faster
- Chained CVEs are the norm — individual low/medium issues escalate when combined
- Unauthenticated attack paths are increasingly common in WordPress's REST API surface
- Batch processing endpoints are a new attack surface that most operators don't think about
If you manage WordPress infrastructure, add REST API endpoint auditing to your regular security reviews. The batch API (/wp-json/batch/v1) should be restricted by default.
Quick Reference
| Item | Detail |
|---|---|
| CVE-2026-60137 | SQL injection via WP_Query / author__not_in (CVSS 9.1) |
| CVE-2026-63030 | REST API batch route confusion → RCE (CVSS 7.5) |
| Chain name | WP2Shell |
| Affected | WordPress 6.8.0–7.0.1 (full unauthenticated RCE chain: 6.9.0–7.0.1) |
| Patched in | 6.8.6, 6.9.5, 7.0.2 |
| Attack complexity | Unauthenticated when chained, no plugins needed; RCE path requires no persistent object cache |
| WAF emergency rule | Cloudflare released July 17, 2026 |
| Status as of July 19, 2026 | Public PoC exists; early exploitation attempts reported |
| WP2Shell disclosure | Adam Kues, Assetnote / Searchlight Cyber |
Top comments (0)