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 Enter fullscreen mode Exit fullscreen mode 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 ( 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 Enter fullscreen mode Exit fullscreen mode 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 Enter fullscreen mode Exit fullscreen mode Post-Patch Verification Checklist After updating, verify your installation is clean: 1. Version check wp core version grep '$wp_version =' wp-includes/version.php Enter fullscreen mode Exit fullscreen mode 2. Check for new admin accounts wp user list --role=administrator Enter fullscreen mode Exit fullscreen mode 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 Enter fullscreen mode Exit fullscreen mode 4. Database audit wp db query "SELECT user_login, user_email, user_registered \ FROM wp_users WHERE user_registered > '2026-07-01'" Enter fullscreen mode Exit fullscreen mode 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_CORE constant or wp auto-update enable CLI 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
WordPress 7.0.2 — Patching an Unauthenticated RCE Chain Right Now
Full Article
Original Source
Read the full article at Dev →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.