Skip to content

WordPress core (CVE-2026-60137)

CVE-2026-60137CWE-89OWASP A03:2021CVSS 5.9Updated October 1, 20264 min read

CVE-2026-60137 is a SQL injection in WP_Query, the query engine of WordPress core. On its own it is rated 5.9, because a plugin or theme has to pass in untrusted input. Chained with the REST API flaw CVE-2026-63030 as "wp2shell", it lets an anonymous visitor create an administrator on unpatched WordPress 6.9 and 7.0. Attackers were trying it about 90 minutes after the patch shipped.

Affected
WordPress 6.8.0 to 6.8.5, 6.9.0 to 6.9.4 and 7.0.0 to 7.0.1 (the unauthenticated chain with CVE-2026-63030 from 6.9.0 only)
Patched in
WordPress 6.8.6, 6.9.5 and 7.0.2 (17 July 2026) and every later release
Actively exploited
yes

On 17 July 2026 WordPress released versions 7.0.2, 6.9.5 and 6.8.6 to fix two flaws in its core. According to Patchstack, the first exploitation attempts reached its sensors roughly 90 minutes later. This article covers the SQL injection half of that pair. On its own it is a medium. Combined with CVE-2026-63030 it hands an anonymous attacker the whole site.

What is CVE-2026-60137

WP_Query is the class WordPress uses to fetch posts from the database. Its author__not_in parameter, reachable through the REST API as author_exclude, was not properly sanitised, so a crafted value ended up inside the SQL query: a classic SQL injection. WordPress calls it a “facilitated” injection. On its own it only works “when a plugin or theme passes untrusted input to the parameter”, in the words of the NVD entry, and Patchstack notes that it can read data but not write it. That explains the CVSS score of 5.9 from the CNA, WPScan. CISA’s ADP scores it 9.1, and as of 1 October 2026 NIST has published no score of its own. WordPress 6.8 introduced the vulnerable code; older versions are not affected.

From 6.9 onwards a second flaw supplies the missing piece. CVE-2026-63030 is a route confusion in the REST API batch endpoint (/batch/v1): a sub-request is validated for one handler and then executed by another. Patchstack puts it this way: the batch confusion “lets an unauthenticated request smuggle the SQL injection past the schema that would normally sanitize it”. The public exploit then uses the injection to forge data that WordPress acts on, ending in a new administrator account. That is privilege escalation from anonymous visitor to administrator, and from there, Patchstack notes, the rest is routine: upload a plugin that is really a webshell and run code on the server. Adam Kues of Assetnote / Searchlight Cyber reported the chain and published it as “wp2shell”; the injection itself was reported by TF1T, dtro and haongo.

What the attackers did

This was an n-day, not a zero-day: the patch came first, then the attacks. The fix landed in WordPress’s public code about 1.5 hours before the release, and Patchstack calls that commit “effectively the disclosure”: anyone could read the diff. The first exploitation attempts followed three hours after the commit. CISA added both CVEs to its catalogue of exploited vulnerabilities on 21 July, the day the Dutch NCSC reported that abuse had been observed. Germany’s BSI rated the situation 3 out of 4 (orange), citing active exploitation.

Patchstack described the first days as “a land rush” by many different actors rather than one coordinated botnet, with only three IP addresses in its data attempting the full chain to an administrator account. CrowdSec counted 62,802 unique attacking IP addresses in the 15 days to 23 August 2026 and still classed the flaw as actively exploited. Targeted use exists as well: GreyNoise describes an actor it calls Kapibala, in its assessment a suspected Chinese speaker, who used the chain from around 20 July and succeeded against at least 49 organisations in 29 countries, four of them in Germany and one in the Netherlands. At one western government body the actor stole more than 18,000 records.

Why a 5.9 deserved an emergency

Anyone triaging by individual CVSS scores would have put this CVE in the next maintenance window. That is the lesson: attackers think in chains, so assess a medium alongside whatever it can be combined with. The second lesson is about time. Ninety minutes from patch to attack leaves no room for a change process, and the forced auto-update only helps where it actually lands. CrowdSec saw tens of thousands of addresses still finding sites where it had not: automatic updates switched off, a host pinning the version, or a staging copy nobody owns. Those are outdated components in their purest form.

What to do now

  • Check the version actually running on every WordPress instance, including staging, test and forgotten campaign sites. Do not assume the forced update arrived.
  • Run the latest release. As of 1 October 2026 that is 7.1.2, which also fixes CVE-2026-87902, a separate core flaw that CISA has listed as exploited since 25 September. For this CVE alone the minimum is 7.0.2, 6.9.5 or 6.8.6.
  • If a site ran an affected 6.9 or 7.0 version after 17 July 2026, look for administrators you did not create, plugins you do not recognise, PHP files under wp-content/uploads and anything in wp-content/mu-plugins.
  • Cannot update straight away? Block both /wp-json/batch/v1 and ?rest_route=/batch/v1 at the edge, and test the rule against the variant that carries rest_route in the POST body. CrowdSec and Patchstack found rules that only looked at the URL.
  • Building plugins or themes? Never pass request input to WP_Query unchecked; author IDs should be cast to integers first. See input validation.
  • Include your WordPress sites in a regular penetration test, forgotten ones first.

Sources

Frequently asked questions

Why is the score only 5.9 if this was so serious?

The 5.9 from the CNA, WPScan, covers this flaw on its own: the injection only reads data, and it needs a plugin or theme that passes untrusted input to the parameter. The danger lies in the chain. The same CNA rates CVE-2026-63030 at 9.8, and together they give an anonymous visitor an administrator account.

Didn't WordPress update everyone automatically?

WordPress enabled forced updates through its auto-update system. That covered most sites, but not those with automatic updates switched off, sites a host pins to a fixed version, or installations where the update fails, for instance over file permissions. CrowdSec saw attackers still finding such sites five weeks later.

Is updating enough?

Only if nobody got in first. An administrator account or webshell plugin created through the chain survives the update. If a site ran an affected 6.9 or 7.0 version after 17 July 2026, check it for signs of compromise as well.

Related articles

Press / to search · Esc