Executive Answer
Two CVEs chained together - CVE-2026-63030 and CVE-2026-60137 - give any attacker on the internet unauthenticated remote code execution on WordPress 6.9 and 7.0. No login. No plugin. No prior foothold. This was found by a continuous attack surface monitoring team, not a pen test. WordPress 6.9 shipped December 2, 2025. Any engagement scoped before that date missed it entirely. The core CTEM question this raises: how long would it take your organization to know that a critical zero-auth RCE had landed on a platform you are running?
- 500M+ WordPress websites in total install base - making unauthenticated RCE on WordPress core a wide-radius event.
- 6.9.0 - 6.9.4 and 7.0.0 - 7.0.1 - affected versions for the full RCE chain. WordPress 6.9 shipped December 2, 2025 - less than 8 months ago.
- 2 CVEs chained - CVE-2026-63030 (REST API batch-route confusion) + CVE-2026-60137 (SQL injection in WP_Query). Neither is exploitable to RCE alone on 6.9+.
- 7.5 (High) - CVSS score. WordPress rated it Critical internally. The gap between those two ratings matters when organizations use CVSS thresholds to triage patching.
- July 18, 2026 - public proof-of-concept appeared on GitHub. Exploitation window is open now.
- 6.9.5 and 7.0.2 - fixed versions. Auto-updates were pushed, but auto-updates can be disabled.
On July 17, 2026, Searchlight Cyber published the technical writeup for wp2shell - a pre-authentication remote code execution chain in WordPress core. The researcher who found it, Adam Kues at Assetnote, was not running a pen test. He was doing continuous attack surface monitoring. That distinction is the entire point of this article.
WordPress powers roughly 40% of the web. A zero-credential RCE on WordPress core - not a plugin, not a theme, core - is not a niche event. The affected versions shipped in late 2025, which means any security engagement conducted before December 2025 would not have found this. Any engagement conducted after might still have missed it if the WordPress install was out of scope.
That window - between "vulnerability introduced" and "pen test catches it" - is where this chain lived. It is also where most organizations' security programs have the least visibility.
What wp2shell Actually Is
wp2shell is not a clever name for a simple bug. It is a two-CVE chain that requires both components to achieve code execution.
The first component is CVE-2026-63030, a batch-route confusion flaw in the REST API. WordPress has had a batch endpoint since version 5.6 (December 2020). This endpoint processes multiple REST API requests in a single HTTP call. The confusion in 6.9 is new: a specific combination of route parameters causes the batch processor to misidentify the request context in a way that bypasses authentication checks that would normally apply to subsequent operations.
The second component is CVE-2026-60137, an SQL injection flaw in WP_Query - the core class WordPress uses to query the database. On 6.8.x, this injection exists but cannot be reached without authentication. On 6.9 and 7.0, the batch-route confusion from CVE-2026-63030 opens a path to reach WP_Query without credentials.
The chain: unauthenticated HTTP request hits the batch endpoint, batch-route confusion (CVE-2026-63030) strips the authentication requirement, SQL injection via WP_Query (CVE-2026-60137) provides a write path to the database, and from there an attacker writes a PHP shell. Full RCE in a single request sequence.
The CVSS score came out at 7.5 - High. WordPress internally rated it Critical. This discrepancy is worth noting because a lot of organizations use CVSS thresholds to triage patching priority. If your threshold is 9.0 for emergency patching, this vulnerability would not have made the cut on score alone. WordPress's internal Critical rating reflects the real-world impact more accurately.
How the Chain Works
The batch endpoint at /wp-json/batch/v1 has existed since WordPress 5.6. Its purpose is legitimate - allow API clients to submit multiple requests in one HTTP call rather than making separate calls. Nothing about this endpoint was inherently dangerous until the changes in 6.9 introduced the route-handling logic that CVE-2026-63030 exploits.
The confusion happens at the route matching layer. When the batch processor parses an incoming request, it resolves which registered route each sub-request targets. In 6.9, a specific crafted sub-request structure causes the permission callback for that route to be evaluated against the wrong context - specifically, a context that does not carry any user authentication. Routes that require authentication to access pass their permission check because the check runs against a blank context rather than the actual request.
With that gate open, CVE-2026-60137 becomes reachable. WP_Query accepts user-supplied parameters to construct database queries. The injection point is a meta-query argument that is not properly sanitized when called through the batch route in this context. An attacker can craft a payload that writes attacker-controlled PHP content into a writable location on the filesystem - typically the WordPress uploads directory - and then make a second request to execute it.
The public proof-of-concept on GitHub as of July 18 automates this sequence. Exploitation requires no specialized knowledge. Any attacker with the PoC and a target URL running a vulnerable version has everything they need.
Who Found It and Why That Matters
Adam Kues is a researcher at Assetnote, which is Searchlight Cyber's attack surface management arm. The discovery was made through continuous monitoring - systematically analyzing newly introduced changes in WordPress's codebase as part of ongoing attack surface research, not as a response to a specific customer engagement.
Kues reported through WordPress's HackerOne program. The WordPress security team issued the fix, and WordPress pushed auto-updates for 6.9.5, 7.0.2, and 6.8.6.
The discovery method is the story here. Assetnote found this because they continuously monitor the attack surface of major platforms. They watch for changes, analyze new code, and follow the threads that look interesting. That is a fundamentally different posture than scheduling a pen test engagement.
A penetration tester working a two-week engagement against a scope list would typically check for known CVEs, run automated scanners, and manually probe specific areas. They would not analyze the internal route-handling changes in a REST API batch processor that shipped eight months earlier unless they had a specific reason to look there. Assetnote had a reason: they were looking everywhere, continuously.
The Pen Test Gap
WordPress 6.9 shipped December 2, 2025. The vulnerability was introduced in that release. The writeup appeared July 17, 2026 - roughly seven and a half months after the vulnerable code went live.
Consider the typical enterprise security calendar. An annual pen test might run in Q1 or Q3. If the test ran in Q1 2026, WordPress 6.9 had been out for three months. Did the scope include the WordPress instance? Did the tester run it against a production environment or a staging box? Was the tester checking for this specific class of batch-route confusion, or working from CVE databases that did not yet list the vulnerability?
The most optimistic scenario is that a Q1 2026 engagement included the WordPress instance, ran it against a current production version, and had a researcher who happened to look at REST API batch processing. Even then, CVE-2026-63030 had not been published. There was no CVE to check against. The tester would have needed to find it from scratch.
This is the pen test gap. It is not a failure of the pen test methodology - pen tests are designed to do something specific, and they do it reasonably well. The gap is structural: a point-in-time assessment cannot cover vulnerabilities that did not exist at the time of the assessment, or that were introduced in versions deployed after the engagement closed.
In this case, from December 2, 2025 to July 17, 2026, any organization running WordPress 6.9 had an unauthenticated RCE path that no pen test could have found unless it was run on a current version after the vulnerability was introduced and before the fix shipped. The window was seven and a half months. For most organizations running annual engagements, that means the vulnerability existed for its entire life without pen test coverage.
CTEM - Continuous Threat Exposure Management - is the operational response to this structural problem. The concept (formalized by Gartner) is not about running more pen tests. It is about building ongoing visibility into your actual exposed attack surface, so that when new vulnerabilities land on platforms you are running, you know quickly rather than waiting for the next engagement cycle.
The question worth asking internally: if a critical zero-auth RCE drops on a platform you are running today, how many days would it take your team to know? If the answer is "whenever someone checks the news" or "whenever our next engagement runs," wp2shell illustrates exactly what that gap costs.
What to Do Now
The immediate priority is confirming your WordPress versions. Check every installation in your environment - including sites managed by third parties, subsidiary domains, and internal tools built on WordPress. The vulnerable range is 6.9.0 through 6.9.4 and 7.0.0 through 7.0.1. If you are running any of those, update to 6.9.5 or 7.0.2 respectively. If you are on 6.8.x, update to 6.8.6 to address the SQL injection component.
Auto-updates were pushed by WordPress, but do not assume they applied. Managed hosting environments, enterprise WordPress configurations, and sites with auto-updates disabled will not have received them automatically. Verify the version directly.
If you have a WAF in front of WordPress installations, a rule targeting the batch endpoint at /wp-json/batch/v1 with the specific payload patterns documented in the Searchlight writeup can provide a compensating control while patching is confirmed. This is not a substitute for patching - it is a bridge.
Use the checker at wp2shell.com to validate exposure status on public-facing installations.
Beyond the immediate fix, this is a good moment to inventory how many web properties your organization runs on WordPress and whether they are included in ongoing vulnerability monitoring. The answer is often "more than we thought" and "not consistently." Both of those feed into the CTEM argument: you cannot manage exposure on assets you have not fully mapped.
The WordPress advisory is at the link in the sources below. The Searchlight technical writeup covers the chain mechanics in detail if you need the full picture for internal reporting.
Every time a zero-auth RCE lands on a major platform, the same conversation happens internally: "why didn't we know about this?" The honest answer is usually that the asset was known but not continuously monitored, or that the last engagement ran before the vulnerable version shipped. wp2shell is a clean example of a class of risk that pen tests structurally cannot cover - new vulnerabilities introduced between engagement cycles on assets that may or may not be in scope. The organizations that caught this fast did so because they had continuous visibility into what versions they were running and what new CVEs applied. That is not a premium security capability. It is table stakes. If you don't have it, the next wp2shell will find you before you find it.
Related Expertise
Sources & Further Reading
- Searchlight Cyber - wp2shell: Pre-Authentication RCE in WordPress Core - Full technical writeup by Adam Kues at Assetnote, including chain mechanics and PoC details
- WordPress Security Advisory - GHSA-ff9f-jf42-662q - Official advisory covering CVE-2026-63030 and CVE-2026-60137, affected versions, and fix details
- wp2shell.com - Exposure Checker - Public tool for checking whether a WordPress installation is exposed to the wp2shell chain
- NIST Cybersecurity Framework - Foundation for continuous exposure management and identify/protect/detect functions
- Gartner - Implement a Continuous Threat Exposure Management (CTEM) Program - Gartner research note introducing the CTEM concept and five-stage cycle (subscription required)
Related Articles
cPanel Auth Bypass and Mass Exploitation
What happens when authentication bypass hits a platform managing millions of hosting accounts - and how continuous monitoring changes the response window.
Threat IntelligenceThree Doors Ransomware Groups Use That You Have Probably Left Open
Ransomware groups do not need zero-days. They use the exposure gaps that accumulate between pen test cycles.
Frequently Asked Questions
What is the WordPress wp2shell vulnerability?
wp2shell is a two-CVE chain: CVE-2026-63030 (REST API batch-route confusion) and CVE-2026-60137 (SQL injection in WP_Query). Together on WordPress 6.9.0-6.9.4 and 7.0.0-7.0.1, they allow unauthenticated remote code execution - no credentials, no plugin, just an HTTP request. Discovered by Adam Kues at Assetnote (Searchlight Cyber) through continuous attack surface monitoring. A public proof-of-concept has been on GitHub since July 18, 2026.
Which WordPress versions are affected by the RCE?
The full RCE chain affects 6.9.0-6.9.4 and 7.0.0-7.0.1. WordPress 6.8.x has the SQL injection component only, not the full chain. Fixed versions are 6.9.5, 7.0.2, and 6.8.6. WordPress pushed auto-updates, but they can be disabled - verify your version directly rather than assuming the update applied.
What is CTEM and how does it differ from penetration testing?
CTEM (Continuous Threat Exposure Management) provides ongoing visibility into your actual attack surface rather than point-in-time assessments against a defined scope. A pen test done before December 2025 could not have found wp2shell - the vulnerable code did not exist yet. A pen test done after might still have missed it if the WordPress install was not in scope. CTEM is specifically designed to catch vulnerabilities that land between assessment cycles on assets that might be outside formal pen test scope.
How do I check if my WordPress site is patched?
Check the running version in Dashboard > Updates or via WP-CLI with "wp core version". Update to 6.9.5 or later if on 6.9.x, 7.0.2 or later if on 7.0.x, 6.8.6 if on 6.8.x. The checker at wp2shell.com can validate exposure status for public-facing sites. Do not rely on auto-update confirmation - verify the version directly.
Did the WordPress auto-update cover wp2shell?
WordPress pushed auto-updates for 6.9.5, 7.0.2, and 6.8.6. But auto-updates can be disabled by site owners, by hosting configurations, or by enterprise deployment pipelines that control the update cycle. Organizations running WordPress on-premises or through managed hosting environments should verify the running version explicitly rather than assuming the auto-update was applied.
Want to understand your organization's exposure window?
wp2shell existed for seven and a half months before a public writeup appeared. The question is not whether the next one will happen - it is how fast your program will detect it. I help organizations build continuous exposure management programs that close the gap between pen test cycles.
Let's Talk