wp2shell is a critical, unauthenticated remote code execution vulnerability in WordPress core shared with the public on July 17th, 2026. It requires no plugins, no theme, and no login. It was discovered and disclosed by Adam Kues of Searchlight Cyber, who published an official advisory and a live vulnerability checker at wp2shell.com. Credit for the discovery and the checker belongs entirely to their team.
At Eye Security, we were among the first responders. WordPress.org forced automatic updates across its install base, and with an estimated 200-plus million live WordPress sites that push almost certainly saved a very large number of them before the exploit spread. But, it probably did not save all of them: forced updates do not reliably reach sites that disabled auto-updates, or were already compromised before the update landed.
This post documents the defensive tooling and forensic incident response methodology our team built to answer the questions a defender actually has: Am I on a patched version? Was I already hit? And if I was, where is the evidence?
Update 20-07-2026 11:00 CET: both our WP plugin (compromise scanner wp2shell) as our Chrome/Edge browser extension (wp2shell Checker) just got officially approved and listed in the respective app stores.
Update 20-07-2026 12:00 CET: Searchlight Cyber (Adam Kues) have now published their official writeup of the discovery. It confirms the two-bug chain and root cause we describe here, and adds context on how the vulnerability was originally found.
About wp2shell
wp2shell chains two WordPress core flaws: a REST API route-confusion bug in the batch endpoint (CVE-2026-63030) and an SQL injection in WP_Query (CVE-2026-60137). Together they let an unauthenticated attacker go from no access to a rogue administrator and code execution on a default install. The full mechanics are in the section below.
Why this one is different
The vast majority of WordPress security issues live in plugins or themes. wp2shell is in WordPress itself, so it reaches a bare install with nothing added. It is unauthenticated, requires no user interaction, and the entry point (the REST batch endpoint) is enabled by default. The exposed population is enormous, which is exactly why WordPress.org initiated forced automatic updates.
One narrowing condition is worth noting: the code-execution path depends on the site not using a persistent external object cache (such as Redis or Memcached), which changes how the underlying query is built. That reduces the blast radius for some larger deployments but does nothing for the millions of stock installs that never touch an external cache.
How the exploit chain works
A full, working proof-of-concept has been public on GitHub since shortly after disclosure (Icex0/wp2shell-poc) and we have independently verified that it executes end to end against an affected, default install.
- The chain: an unauthenticated route-confusion bug in the default /wp-json/batch/v1 endpoint (CVE-2026-63030) smuggles input into an author__not_in SQL injection in WP_Query (CVE-2026-60137). That gets escalated via a UNION-forged post and oEmbed cache write into a rogue administrator and a webshell plugin, taking it from pre-auth all the way to RCE. Fixed by wp_parse_id_list() in 7.0.2.
- Not one request, and log-blind: a full run is a dozen to dozens of requests (one value per UNION read, far more when forced into blind/error extraction). The decisive steps ride inside batch POST bodies that rarely appear in access logs, so the database artifacts are the primary evidence, not the logs.
- Residual evidence and caveat: the PoC self-cleans the admin and webshell but leaves the oEmbed cache rows and changeset/request posts (the basis for our Compromise Scanner below). The UNION step needs the full-row query path, so sites on a persistent external object cache (Redis/Memcached) may dodge this specific path. Patch anyway.
Affected and fixed versions
The two bugs do not reach the same versions, which is the key to who is exposed to what. The SQL injection reaches further back than the full RCE chain, so the ranges split.
| Version range | Exposure | Fixed in |
|---|---|---|
| 6.8.0 โ 6.8.5 | SQL injection only (no RCE chain) | 6.8.6 |
| 6.9.0 โ 6.9.4 | Full unauthenticated RCE chain | 6.9.5 |
| 7.0.0 โ 7.0.1 | Full unauthenticated RCE chain | 7.0.2 |
What to do right now
Verify that your WordPress instance is running a patched version, do not assume your site has already been updated automatically, and monitor for unexpected activity on any WordPress infrastructure exposed to the internet.
The forced auto-update rollout very likely protected you, and that is genuinely good news. We have not independently verified how broadly or reliably those updates reach environments where auto-updates are disabled or restricted, and a site that was compromised before the patch arrived stays compromised. Confirm the version in your dashboard, and if there is any doubt, run a compromise check rather than trusting that the update happened.
- Check your website via wp2shell.com (maintained by SearchLight Cyber)
- Use one or both of our free tools below: a browser extension and WordPress plugin
If you genuinely cannot update immediately, the advisory lists temporary measures that all amount to keeping anonymous callers off the batch endpoint.
If you think WordPress might have been exposed, and/or if you just want to be sure: reset every user password. The injection alone can read the wp_users table, which means an attacker may already hold your password hashes. Force a reset for all accounts (administrators first) and encourage users to change that password anywhere else they reused it.
Our free tools
We built two free tools plus a forensic methodology to help checking if you are patched and to check for signs of (active) compromise.
Tool 1: wp2shell checker (browser extension)
Our browser extension can be used on any WordPress site to answer three questions: is this WordPress, is it running a patched version, and is it exposed to wp2shell?

Download our browser extension for Chrome/Edge in the Chrome Web Store
Disclaimer the checker reports what a WordPress site tells the outside world, so it is a fast triage aid rather than a guarantee. Version strings can be hidden or spoofed, hardened sites may not expose enough to judge confidently, and a report of “patched” does not mean a site was never compromised before it was updated. Use it to prioritise, then confirm with the compromise scanner and the checks below. We will keep the checker updated as new details and intelligence about wp2shell come to light.
Tool 2: compromise scanner (WordPress plugin)
Our Compromise Scanner is a simple WordPress plugin that detects the artifacts this chain leaves behind. It does not mitigate; you still need to update. A weighted-indicator scan maps to a score, which maps to one of three verdicts. Each indicator carries a severity and a point value; the table below lists them.

We added an export button that can be used for further (forensic) analysis. Privacy is built in: password hashes and session tokens are never exported, nothing will leave your WordPress installation.
Download our WordPress extension here (source).
Disclaimer: the scanner is a first signal, not a guarantee. It looks for the specific traces this attack is known to leave, so a clean result lowers your risk but does not prove a site was never touched, and a determined attacker who cleaned up thoroughly can still evade it. Treat its output as evidence to act on, not a final verdict, and combine it with manual checks. As new details and intelligence about wp2shell emerge, we will update the detection logic, so make sure you are running the latest version.
Indicators of compromise
The following indicators are derived from reading and testing the public proof-of-concepts. Because rogue accounts and plugin folders use a static prefix plus a random suffix, match on the prefixes rather than exact strings. Attribution to the specific PoC that introduced each indicator is noted where relevant.
| Type | Indicator |
|---|---|
| Rogue admin login | wp2_* , w2s_* |
| Rogue admin email domain | @wp2shell.invalid , @wp2shell.shellcode.lol |
| Exploit endpoint | /wp-json/batch/v1 , /?rest_route=/batch/v1 |
| Database artifacts | oembed_cache loopback rows, customize_changeset with very high parent IDs, orphaned usermeta, user-ID gaps |
Where to look on Linux (forensics & incident response)
Because the steps of the chain never seem to reach the web server access log, the database is your primary evidence and the filesystem is where the follow-on activity lands. On a typical Linux WordPress host, the following paths are the ones worth pulling for further forensic analysis.
- Database (primary evidence): the
wp_usersandwp_usermetatables for unexpected administrator rows, andwp_optionsfor tamperedactive_plugins,siteurl/home, and any injected_transient_/ object-cache entries. Dump viamysqldumpfrom a copy, not the live DB. - Web root:
/var/www/html(or the site’s docroot), look for recently modified or newly created PHP files.find DOCROOT -name "*.php" -newermt "2026-07-16" -printf "%TY-%Tm-%Td %TH:%TM %p\n"is a fast first pass. - Web server logs:
/var/log/apache2/or/var/log/nginx/. The access log will show the REST batch entrypoint and any later webshell hits (source IP, timing, entrypoint) but not the injection itself. The Apacheerror.logcan accidentally leak an injected query if a UNION threw a SQL syntax error, so check it. - PHP and FPM logs:
/var/log/php*-fpm.logand theerror_logfiles PHP drops into the web root or per-directory; unexpected fatal errors or warnings around the intrusion window are useful corroboration. - PHP sessions and temp:
/var/lib/php/sessions/and/tmpfor dropped payloads or staging files. - System and auth:
/var/log/auth.log(orsecure), shell history (~/.bash_historyforwww-dataand any service accounts),/etc/crontab,/etc/cron.*and per-user crontabs for persistence, and/etc/passwdfor added local accounts.
One caveat of this vulnerability: a clean exploit run can leave almost nothing in the logs, so the absence of log lines is not evidence of safety. Let the database rows and file timestamps lead, and use the logs to corroborate source IP, timing, and entrypoint.
Bottom line
wp2shell is a pre-auth, unauthenticated RCE in WordPress core with a working public exploit. If you run WordPress, treat it as actively exploited and act today:
- Confirm you are patched. Update to a fixed release (6.8.6, 6.9.5, or 7.0.2 depending on your branch). Auto-updates likely saved most of the 200M+ sites out there, but not all, so verify rather than assume.
- Check whether you were hit before you were patched. Run the compromise scanner, review your admin users, and pull the artifacts above. No indicators is a good sign, not a guarantee. Verify before any reinstall.
- Preserve evidence if anything looks off. Image the database and web root read-only before remediation, and bring in help if you find an admin you did not create.
- Reset passwords, even for SQLi-only sites. The injection can read password hashes from
wp_users, so force a reset for all accounts and rotate API keys. Hashes still need cracking, but weak passwords will not survive it.
Patching alone is not enough for anyone who was exposed before updating. The point of our tooling is to answer the harder question of whether the door was already opened.
References
- Searchlight Cyber: wp2shell.com and slcyber.io.
- WordPress 7.0.2 release notes
- WordPress core security advisories: GHSA-ff9f-jf42-662q and GHSA-fpp7-x2x2-2mjf.
- The Hacker News
- Aikido Security
- Public proof-of-concept (verified by Eye Security)