The question that sparked the discussion
In the beginning of the stream, Nathan mentioned what had happened with this vulnerability, and went into good detail about it, which we’ll also do a bit later. It was so severe that it had triggered an emergency update across millions of sites.
So, by the time our viewer asked her question, most people already knew what had happened. However, what hadn’t been covered yet, and what she wanted to know about, was the mechanics of this incident. Here’s what she asked:
Could you briefly get technical and explain to us how such a serious bug worked to allow anyone with the URL the right to create admin users?
It’s a good question to ask. Knowing how a bug works can help to prevent it. But let’s expand the question further. How did such a vulnerability even happen and what can we learn from it?
What are CVE-2026-60137 and CVE-2026-63030?
This part of the blog will be a bit more technical than our usual style, but it’s necessary to fully explain what had occurred. Firstly, the vulnerability, the bug, is instead two bugs that work together: CVE-2026-60137 and CVE-2026-63030.
Firstly, bug one, lived in a parameter WordPress uses internally called author__not_in. It’s part of the WP_Query logic that pulls posts, users, and other data from the database. This parameter is typically validated before it reaches the database by the Rest API. It checks that the parameter is an array of integers and rejects everything else. It’s what keeps random visitors from injecting their own SQL.
Bug two was a separate, unrelated flaw in the REST API’s “batch endpoint.” It’s a feature that lets multiple API requests get bundled and processed together. An indexing error introduced in WordPress 6.9 made it possible for requests inside a batch to get mismatched with the wrong internal handler. The result was a request’s validation step and its execution step ended up checking two different things. Because of that, validation ran against one handler while execution against another.
Chained together this mismatch allowed anonymous, unauthenticated requests to slip past the integer check guarding author__not_in. Then, they could land raw SQL directly in the database query. From there, this publicly available exploit allowed attackers to create new administrator accounts, giving them full access to the site. Below you’ll also find the full timeline of this vulnerability.
If all of that was too technical to understand (we don’t blame you), Nathan put it in a more succinct and simple way:
No, it didn't require any exploited plugins, didn't require any weird code. If you knew the script and how to exploit this thing that was built into core WordPress, you had full access to WordPress, to start creating admin users, anything else you wanted.
These two extremely specific bugs, neither destructive on its own, combined into a full site takeover vulnerability that needed nothing more than the site’s URL.
Why this vulnerability was different
WordPress exploits are nothing new. They have existed for as long as WordPress itself has. However, the majority of WordPress vulnerabilities (up to 94%) come from plugins. For something like this to sneak in through core WordPress is unusual. It was in WordPress’ own codebase, meaning every site was exposed regardless of what plugins it was using. Nathan was blunt about its severity:
This is the worst vulnerability I have ever personally seen.
However, there are a few more things that make this incident stand out, aside from the cause being core WordPress.
The silver lining, as Nathan’s own track record shows, is that the stars have to truly align for such an exploit to surface:
I've been using WordPress since 2008, exclusively WordPress since 2010. I don't know how many thousands and thousands of hours I have working with WordPress over those years. I've never seen anything that even is remotely similar to this.
Fortunately, as soon as the bugs and the connection between them were discovered, WordPress’ response was swift and a patch was pushed out.
WordPress’ response to this vulnerability
The core team at WordPress treated this as the significant threat to sites using the CMS that it was. They pushed the fix through the platform’s automatic update system, meaning most sites patched themselves without anyone having to do anything.
That’s also why Nathan flagged this as a good argument for leaving WordPress’ automatic minor-version updates enabled:
This is a fabulous case in point for why I make that recommendation. The default behavior of WordPress is to install these minor releases automatically, because when they push out these security updates, you really want them.
This is worth weighing against the general “Should you always update right away?” question. Our blog on updating WordPress and plugins recommends waiting for feature releases to get polished. However, security releases like 7.0.2 are the clear exception because they are narrow, tested, and close a specific vulnerability. They generally won’t introduce compatibility risks so leaving core auto-updates for minor/security releases enabled matters.
Additionally, WordPress’ core team informed major hosting and CDN providers before the fix was made available to the public so they could apply their own protections as well. For example, Cloudflare automatically protected all sites on its free plan through a rule baked into its ruleset. Paid-tier customers (Pro, Business, and Enterprise) had access to the same protection through Cloudflare’s Managed Rules, but needed to confirm if it was enabled, as it wasn’t automatically applied. Those sites were protected, even if the site hadn’t been patched yet.
The sites at the greatest risk were those with hardening measures that restricted file permissions. In those cases, site updates could be blocked and the patch never applied.
What to do if your site is affected or you manage such sites
If you are responsible for any WordPress sites right now, personal or as part of an agency, the good news is that most of the work you need to do is verification. We’ve put together a quick checklist for you to go through:
Check for signs of compromise: Patching closes the door, but doesn’t undo what already went through it. Review the admin user list for accounts that shouldn’t be there. Additionally, watch for unknown files, unexpected redirects, or other unusual behavior.
Treat a CDN or WAF as a second layer, not a substitute: Cloudflare’s free-tier protection genuinely blocked this exploit for sites behind it. That alone is a good reason to have such a service in front of your or client sites already. Still, patching comes first.
As you can see, none of these steps should take long individually so we recommend you don’t skip any of them. Due diligence is key in such cases, especially confirming that your site is actually updated.
The bigger-picture takeaway
The rarity of this vulnerability is a major part of the reason it’s worth understanding and not just patching and moving on. The mechanism is so specific here: two unrelated, individually minor bugs, combining into something serious. It’s a pattern worth keeping in mind and one the WordPress security team will no doubt be watching for too.
For someone managing a portfolio of sites asking “Did the automatic update apply?” should be your first step in ensuring everything is working as expected. It’s a habit worth reinforcing across every site you manage because automatic updates are only doing their job if they are actually completing. Make it part of your maintenance to confirm they are.
And if you have any more questions about this vulnerability or want to learn more about WordPress, agency work, or hosting in general, join us every Thursday at 2 p.m. EST for Office Hours. Nathan and our Agency Success community will be happy to give you answers live!
FAQ
Yes. Since the batch endpoint (/wp-json/batch/v1) is what gave unauthenticated attackers a path to the SQL injection flaw, disabling or restricting access to it on a still-vulnerable site would have closed that specific attack route even before the official patch landed. That's not a substitute for patching, though, as it only blocks the delivery method for this exploit chain, not the underlying bugs.
Why do different sources report different severity scores for this vulnerability?
The rating has shifted depending on when and how it's measured. WordPress's own GitHub Security Advisory initially scored the REST API batch flaw (CVE-2026-63030) at 7.5, while several independent trackers and CISA's advisory later cited scores as high as 9.8 once the full impact of chaining it with the SQL injection bug (CVE-2026-60137) became clear. When comparing severity numbers for this incident, it's worth checking which CVE, and which stage of the exploit chain, is being scored.
Is there a specific way to check server logs for signs this exploit was used against a site?
Yes. The exploit leaves a fairly identifiable trail: unusual POST requests to /wp-json/batch/v1 paired with SQL-injection-style payloads targeting the author__not_in parameter. A number of hosting providers and security plugins added detection rules for this specific pattern after disclosure, so it's worth checking whether yours does before ruling out compromise.