← Back to the blog

// blog · Vulnerability review / RCE

RCE in WordPress and beyond: a review of the latest vulnerabilities

The last few weeks brought a run of remote code execution flaws, and in software that runs a large slice of the internet. One rare event stands out: a bug that runs code without a login landed in WordPress core itself. Around it came the usual wave of critical plugin and theme flaws, and outside the WordPress world the tools developer teams rely on took hits too: the TeamCity CI/CD server, the self-hosted Gitea, and the Next.js framework. Several of these are already in the CISA KEV catalog, with public proof-of-concept code. This post is triage, not a scare piece: what each bug actually is, whether it is being exploited, and what to patch first.

Context and legality. This is educational material describing publicly disclosed and already patched vulnerabilities. Every flaw here has a fix, and we give the versions that carry it. We consistently separate confirmed exploitation from theory, and we do not publish working exploits. Testing systems you do not own is legal only with the owner's written authorisation.

WordPress: this time core itself took the hit (wp2shell)

The most interesting technically, and the most dangerous, is the bug disclosed on 17 July 2026 by the Assetnote team at Searchlight Cyber. They named it "wp2shell," and that is not marketing hype. An unauthenticated attacker can run code on a default WordPress install, with no account and no user interaction. RCE in core, rather than in a plugin, is very rare, because core has been audited for years, and that is exactly what makes this case unusual.

The vulnerability is really a chain of two bugs. The first, CVE-2026-63030, is a logic mistake in the REST API batch processor at /wp-json/batch/v1. When wp_parse_url fails on a sub-request path, the error is pushed to the validation array but not to the matches array. The two arrays drift out of sync, and every following request gets dispatched to the wrong handler. The second bug, CVE-2026-60137, is a SQL injection in the author__not_in parameter of WP_Query. Put together, they take you from an anonymous request to code execution on the server.

One detail is worth flagging. The batch endpoint the first bug abuses has shipped by default since WordPress 5.6 in 2020, so this hit a default install with no extra plugins involved. Affected versions run from 6.9.0 to 6.9.4 and from 7.0.0 to 7.0.1. The fixes shipped in 6.9.5 and 7.0.2. The raw CVSS landed at 7.5, but the practical risk was high enough that the project pushed a forced automatic update. Public proof-of-concept code is already circulating, and in-the-wild exploitation has been confirmed. If you run WordPress with automatic updates turned off, this is item number one to check today.

Plugins and themes: the standing attack surface

Core is the exception. The real, standing attack surface in WordPress has always been plugins and themes, because that is where code of very mixed quality lands. Summer 2026 was no different.

Forminator, a popular forms plugin with more than 600,000 active installations, got CVE-2026-15748, scored 9.8. It is the classic scenario: an unauthenticated attacker uploads an arbitrary file, including a PHP file, and gets code execution. The heart of it is the handle_file_upload function, where the dangerous-extension blocklist matched keys exactly, which could be bypassed with pipe-alternative MIME type keys. There is one precondition: the form has to contain both a File Upload field and a Select field. The fix is version 1.56.2, from 31 July 2026.

Higher still on the scale is GiveWP, a donations plugin, with CVE-2026-82222 and the maximum score of 10.0. Here the vector is PHP object injection, which leads to command execution on the server, again without authentication. The Avada theme, together with its Fusion Builder plugin, got CVE-2026-18431 (9.8): an arbitrary file write that also ends in remote code execution, in versions up to and including 7.16.

Rounding out the set was a run of bugs that do not give RCE directly, but lead to administrator account takeover, and from there to full control anyway: an authentication bypass in the WPMU DEV dashboard (CVE-2026-76581), a data exposure in TranslatePress (CVE-2026-19632, around 400,000 sites), and a privilege escalation in Pods (CVE-2026-19598, around 100,000 sites). All scored 9.8. The common denominator has held for years: WordPress admin is code execution in practice, because you can upload a plugin from the panel.

Beyond WordPress: CI/CD, Git and the framework

WordPress draws the attention because it is everywhere, but from an attacker's point of view the internal tools teams stand up on the internet "just for a moment" are often the more interesting targets. Three examples from the same window.

TeamCity, JetBrains' continuous integration server, got CVE-2026-63077, scored 9.8. It is unauthenticated RCE through the agent communication protocol. The root cause is deserialization of untrusted data: an overly permissive allowlist of classes in XStream that added TeamCity protocol classes without removing XStream's own default permissions. Taking over a CI/CD server is especially ugly, because it is the place every build artifact and secret passes through. JetBrains fixed it in versions 2025.11.7 and 2026.1.3 for on-premises installs. CISA added the flaw to the KEV catalog on 5 August, and Rapid7 published a working proof of concept two days later. This one is actively exploited, though the details of the campaign remain unknown.

Gitea, a lightweight, self-hosted Git server, has CVE-2026-60004, also 9.8. Formally it requires authentication and repository write access, but Gitea allows self-registration by default, so an attacker simply creates an account. The trick itself is elegant: the diffpatch endpoint lets you plant an executable Git hook from repository-controlled content, then run shell commands as the Gitea service account. This is not a memory bug or an exotic parser, it is the abuse of a perfectly legitimate feature. The fix is in 1.27.1. This one is not theoretical either: a targeted instance was reported, with something like a crypto miner dropped onto it, and CISA added it to KEV on 25 August.

Last, the framework layer. Next.js patched two serious holes at once. CVE-2026-75604 (9.0) is a path traversal that yields unauthenticated RCE, but only in applications running on a Windows filesystem. Linux and macOS are untouched. The second is a heap overflow in the libheif library while parsing AVIF images: a crafted file leads to an out-of-bounds write. Here a detail changes the real risk. AVIF optimization in Next.js is disabled by default and has to be turned on deliberately in the configuration, and the public proof of concept does not yet confirm full RCE. Both were fixed in 15.5.24 and 16.3.3.

Five recurring RCE primitives from 2026: unauthenticated file upload leading to a webshell, unsafe deserialization and object injection, a REST logic bug with SQL injection, abuse of a legitimate feature, and a memory-safety bug in a parser
//Five RCE patterns from this wave, with an example CVE for each

Five patterns that keep repeating

Line these eight bugs up next to each other and it is clear that RCE is rarely one magic trick. It is a handful of recurring primitives.

The first is an unauthenticated file upload that ends in a webshell. That is Forminator, and, in the file-write variant, Avada. The second is unsafe deserialization or object injection: TeamCity through XStream, GiveWP through PHP objects. The third is a logic bug paired with a classic web wound, SQL injection, as in the wp2shell chain. The fourth is the abuse of a feature that works exactly as designed, only on the attacker's data, like Git hooks in Gitea. The fifth is memory safety in parsers, like libheif in Next.js.

A simple operational observation follows. The attack surface is not just "the application," it is every point where untrusted data meets a parser, a deserializer, or a write to disk. Then there is the tempo. From the disclosure of wp2shell, TeamCity, and Gitea to a KEV listing with a public PoC took days, not months. The window for calm patching closes faster than it used to.

How to defend

Five defence priorities: inventory and patch velocity, shrink the internet-facing surface, harden file uploads, kill unsafe deserialization, and virtual patching with monitoring
//Five priorities: inventory and patching, smaller surface, safe uploads, no unsafe deserialization, virtual patching and monitoring

Responding to this wave takes no heroics, just the right order.

  1. Inventory and patch velocity. You cannot patch what you do not know about. Keep a list of your WordPress, plugin, CI server, and framework versions, watch the CISA KEV catalog, and where you can, turn on forced automatic updates. With wp2shell that was the difference between calm and a fire.
  2. Shrink the internet-facing surface. TeamCity, Gitea, and other management panels do not need to hang on the open internet. Put them behind a VPN or an allowlist, and enforce MFA on admin accounts.
  3. Harden file uploads. Validate by content, not by extension, keep uploaded files out of the directory served by the web server, and never let them execute. That kills the whole Forminator class of bug.
  4. Kill unsafe deserialization. Keep strict class allowlists and avoid native deserialization of data an attacker can reach. That is the lesson from TeamCity and GiveWP.
  5. Virtual patching and monitoring. When you cannot patch at once, a WAF rule can close the window for a while. Log and alert on unusual outbound traffic, assume compromise, and keep least privilege so a single taken host is not game over.

What this means

This wave is not unusual in the kind of bug, because file uploads, deserialization, and SQL injection have been with us for a long time. What is unusual is the tempo, and how little you have to bend down for access when a CI/CD server or the core CMS of millions of sites sits at the end of the chain. This is squarely NIS2 and KSC territory: vulnerability management, updates, access control, and the ability to detect an incident before a crypto miner on your Gitea does it for you. We wrote about the same thing in the anatomy of Log4Shell, in the Langflow chain, and in the MyDr incident. The product name changes, the pattern does not.

We covered the requirements on the NIS2 / KSC page. If you run or host internet-facing systems and want to find where you are actually exposed, from file uploads through deserialization to the blast radius after one host falls, that is exactly our specialisation: penetration testing and attack-surface review. Book a consultation before the newest PoC does a lap of the internet.


Sources: Rapid7 (wp2shell) · Strobes / Assetnote · The Hacker News (Forminator) · The Hacker News (five plugins) · The Hacker News (Gitea) · JetBrains (TeamCity) · The Hacker News (TeamCity, KEV) · The Hacker News (Next.js)

← Back to the blog