Skip to content
Agentic Matt

PHP2Shell, explained: what it is, who's affected and what to do

Two PHP bugs let a stranger run code on a web server with no login. What that means, how to check your app, why AI is finding more of these, and a prompt to check your code.

Matt Neves

·11 min read

On this page

On October 21st, PHP shipped emergency fixes for two bugs that, in PHP's words, "can allow unauthenticated remote code execution." In plain English: a stranger on the internet could make a website's server run their commands, without logging in. Together the two bugs are called PHP2Shell, and according to Vercel they reach back to PHP 5.4, released in 2012.

Researchers found them with help from an OpenAI model. And it won't be the last time: in the same two weeks, Node.js, Next.js and GitLab all shipped fixes for serious bugs too.

This guide explains what happened, how to tell if your app is affected, what to do about it, and how to hear about the next one before it hits you.

The short version

  • If anything you run uses PHP (WordPress, Laravel, a PHP backend for your app), check the PHP version your site runs. Fixed: 8.2.35, 8.3.36, 8.4.27, 8.5.12 or newer. Older than 8.2 needs an upgrade.
  • Update PHP, then make sure your site is actually running the new one. Updating WordPress or your plugins doesn't fix this.
  • If your server stayed on an old version, make new keys for everything it could read, delete the old ones, and look for admin accounts you didn't create.
  • Limit what one leaked key can do: restricted keys for Stripe and OpenAI, one key per AI agent, two-factor everywhere.
  • No PHP? Check your Node.js and Next.js versions. Both had fixes this month.
  • Set up alerts so you hear about the next one, and run the prompt at the bottom of this page on your code.

This is a free, educational overview, not security advice for your setup. It's built from PHP's, CISA's and each vendor's own pages, linked throughout, as of October 27, 2026. Your host, your framework and PHP's own advisory come first. If you think your server was broken into, get help from your host or a professional.

What happened

WhenWhat happened
2024A PHP core developer finds the first signs of the problem during an audit, but no concrete attack is found.
July 30, 2026An audit of PHP starts under OpenAI's Patch the Planet program.
August 11A researcher reports a working remote code execution bug to PHP. OpenAI's own team independently reports the same root cause, then more ways in on September 18th.
October 20The two CVE numbers leak on forums and social media, without technical details. PHP moves the release up a day.
October 21PHP releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35 and publishes its advisories.
October 26CISA, the US government's cyber agency, adds both bugs to its Known Exploited Vulnerabilities list.
October 29CISA's patch deadline for US federal civilian agencies. (The deadline only binds them, but CISA urges everyone to patch.)

The timeline is from PHP's own write-up, which is unusually honest. About the gap since 2024, PHP says: "We won't pretend otherwise: the delay was a structural failure."

The two bugs are CVE-2026-109618 and CVE-2026-109619, both rated 9.2 out of 10. PHP describes where they live like this: "Both issues sit in parts of PHP that nearly every request touches: memory management and error handling." That's why almost every PHP site is in scope.

What "remote code execution" means

Remote code execution means someone on the internet can make your server run their commands, as if they were sitting at its keyboard. It's the most serious kind of bug a web server can have, because once someone can run commands, everything else on that server is within reach.

Two parts of PHP's description make this one worse:

  • Unauthenticated. No account, password or login needed. Sending the server a request is enough.
  • "As the web worker account." Their commands run as the same user your site runs as. Whatever your site can read, they can read.

For most apps, that's everything that matters. Your server holds your secrets: your Stripe key, your OpenAI key, your database password, usually in an .env file or environment variables your site reads. If someone can run commands as your site, they can read those too, and use them as if they were you.

And on the most exposed setup, your own code doesn't matter at all. On Apache with mod_php, PHP says "an unauthenticated request can trigger the attack before any application code runs."

Is your app affected?

PHP's answer is short: "all PHP installations serving web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed."

That covers:

  • Every WordPress site. WordPress says the bugs "are not specific to WordPress and affect any server that hosts a PHP application," and "No WordPress update is required or planned." Updating WordPress or your plugins won't fix it. Only updating PHP will.
  • Laravel, Drupal, Magento and plain PHP apps. Laravel calls them "extremely serious vulnerabilities affecting every PHP application on the web."
  • The backend of your mobile app, if that backend runs on PHP.
  • Old side projects, marketing sites and blogs you forgot were PHP. W3Techs counts PHP on 69.2% of websites whose server language it can detect.

If nothing you run uses PHP, these two bugs can't reach you. A Next.js app, a Node or Python backend, or a fully static site has no PHP2Shell exposure. But CISA warns that "PHP is often a component of other software," so a tool you host yourself may include PHP without saying so. And JavaScript stacks had their own fixes this month (see It's not just PHP).

How to check your PHP version

  • WordPress: go to Tools, then Site Health, then the Info tab, and open Server. It shows the PHP version your site runs.
  • Managed or shared hosting: look in your host's dashboard. On cPanel it's the MultiPHP Manager, which shows the PHP version each domain uses. If you can't find it, ask your host.
  • Your own server: php -v shows the command-line PHP, which can be different from the one serving your site. As OpenAI's checker puts it: "The default CLI PHP may differ from PHP-FPM or Apache's PHP module." Check the version of the service your web server actually uses.
  • Docker: check the FROM php:... line in your Dockerfile and the image you actually deployed.

Then compare it with this table:

Your versionWhat to do
8.5Update to 8.5.12 or newer
8.4Update to 8.4.27 or newer
8.3Update to 8.3.36 or newer
8.2Update to 8.2.35 or newer, and plan your move to 8.3 or newer: 8.2 stops getting security fixes on December 31st, 2026
8.1 or olderNo official update. PHP published minimal source patches for 7.4, 8.0 and 8.1 only, for people who build PHP themselves. CISA says organizations still on 8.1 or earlier "should take PHP-based systems offline until they can be patched." Upgrade.

One catch on Linux servers. Ubuntu, Debian and Red Hat ship the fix inside their own packages, and the number can look old. OpenAI's checker lists Ubuntu 24.04's fixed package as 8.3.6-0ubuntu0.24.04.13, which is patched even though "8.3.6" is lower than 8.3.36. If you use your distribution's PHP, check its security notice for the fixed package, not just the first three numbers.

How to fix it

On managed hosting, switch to a fixed version in the dashboard or ask your host to do it. WordPress keeps a ready-made email you can send your host. Many hosts update PHP for you, but check the version yourself.

On your own server, install the update from your package manager, then restart PHP-FPM (or Apache, if it runs PHP directly), and check the version your site serves again. The restart matters. In OpenAI's words: "A fixed installed package does not prove that web workers use it."

In Docker, the official php images were updated on October 21st, but your running container still has the old PHP. Vercel's advice: "rebuild with an updated PHP base image and redeploy."

Don't rely on workarounds. PHP lists a few settings that reduce the risk, then says they "do not make an installation safe." Its release notes are blunter: "There are no complete mitigations, updating is the only safe choice."

If your server was on an old version

A CISA listing means there's "reliable evidence that the vulnerability has been actively exploited," and CISA counts attempted attacks in that, not only successful ones. So it doesn't tell you anyone got into your server. It does mean you can't rule it out if your server stayed on an old version after October 21st, and the cleanup is cheap compared to the risk.

  1. Make new keys for everything that server could read: Stripe, OpenAI, your database, email, storage, anything in its .env file. GitHub's order avoids downtime: "first generate a new secret with the same permissions, make the application start using the new token, and then revoke the old secret." Stripe can also rotate a key in one step, but that revokes the old key right away, so have the new one ready to deploy.
  2. Look for admin accounts you didn't create. In WordPress, that's Users, filtered by Administrator. Check your hosting account and database users too.
  3. Look for changes you didn't make: recently modified files, plugins you don't recognize, scheduled tasks you didn't set up. CISA tells defenders to watch for PHP processes "launching shells or downloading tools." If you find anything, stop and get help from your host.

Limit what one leaked key can do

Updating fixes this bug. These steps make the next leak, from any cause, much smaller.

  • Use restricted Stripe keys. Stripe recommends restricted keys "for most use cases," because they "limit the damage to your business that a fraudulent actor could cause if they obtained your key." You can also lock a key to your own servers, and tag a key that belongs to an AI agent.
  • Restrict your OpenAI keys. OpenAI keys default to "All: Full permissions." You can set them to Restricted or Read Only, keep them inside one project, and set a hard spending limit so a stolen key can't run up an unlimited bill.
  • Give each AI agent its own key. An agent, script or automation gets its own key with only what it needs. If something leaks, you replace one key, and you know where it came from.
  • Turn on two-factor for your host, GitHub, Stripe and your domain registrar. It doesn't stop this bug, but it stops a leaked password from becoming a lost account. GitHub recommends an authenticator app over SMS. Save your recovery codes.
  • Keep secrets out of your code. Never commit an .env file, and never put a secret key in anything that runs in the browser.

Why AI is finding more of these

This bug sat in PHP for over a decade. What changed is how fast code is being read.

OpenAI says a research partner "identified a critical flaw using GPT‑5.6 Sol," and that "frontier AI found these vulnerabilities before attackers did." It also says "we expect similar findings to increase sharply in the coming months." It launched Patch the Planet in June to help open-source maintainers fix what AI finds.

PHP's maintainers see the same thing from the other side. Their team has published 15 CVEs since July 1st and worked through more than 100 reports that turned out to be invalid. In their words: "Tools now find bugs faster than ever, for defenders and attackers alike, and the number of reports will keep growing."

It's not one lab, either. Anthropic reported in May that its Claude Mythos Preview model found "more than ten thousand high- or critical-severity vulnerabilities," and that "the bottleneck in fixing bugs like these is the human capacity to triage, report, and design and deploy patches."

The takeaway for builders isn't to panic. Old, popular code is being read faster than ever, so fixes will keep coming. The people who update quickly are fine. The ones who find out months later are the ones who get hurt.

It's not just PHP

The same few weeks:

  • Node.js fixed a bug in the Brotli decompression code it includes on October 21st (versions 22.23.4, 24.22.1 and 26.12.1), and CISA added it to its exploited list on October 27th. Node.js credits OpenAI Codex Security with finding it. It only matters if your code or a library decompresses Brotli data from outside, but upgrading is the simple fix. Node 20 is end of life and won't get it. If you're on Vercel with Node 22 or 24, Vercel says it's rolling the patch out for you; anywhere else, upgrade Node yourself.
  • Next.js shipped an emergency security update on October 14th: two critical bugs that could let someone run code on the server, plus one that can take an app down. Fixed in 16.4.1 and 15.5.28. One of the critical ones only applies on glibc-based Linux and the other only to Next.js 16. Upgrading covers both.
  • React Server Components had a matching critical fix the same day (19.0.9, 19.1.10, 19.2.9 and 19.3.1).
  • GitLab fixed a bug rated 10 out of 10 on October 21st, the same day as PHP. It lets someone run code on the GitLab server without logging in. GitLab.com is already patched; if you host GitLab yourself, GitLab says to upgrade "immediately."

If you build apps, at least one of these is probably somewhere in your stack.

Stay ahead of the next one

  • Turn on Dependabot alerts in GitHub. It tells you when something your app depends on has a known security bug. In your repo, go to Settings, then Advanced Security, and enable Dependabot alerts (you can turn it on for all your repos at once in your account settings). By default, GitHub emails people with write access who watch the repo. Two catches from GitHub's docs: it doesn't email you about problems it finds the moment you turn it on, so look at the alerts tab once, and it reads your package files, so it would flag an old next in package.json but not the PHP or Node version on your server.
  • Subscribe to CISA's list. The Known Exploited Vulnerabilities catalog has a "Subscribe to the KEV Catalog Updates" link for email. It's the list of bugs being used in real attacks, so it's short and worth reading.
  • Know where your stack posts security news: php.net, the Next.js blog, the Node.js vulnerability blog, and your host's status or security page. Find them before you need them.

The prompt

Paste this into Claude Code, Cursor or Codex, opened in your project. It only reads and reports. It won't change anything until you say so.

Act as a security reviewer for this project. Don't change anything yet. Check these and report the most serious first:
1. Secrets: API keys, tokens or passwords in the code, the git history, or anything sent to the browser.
2. Versions: the PHP, Node.js, framework and CMS versions this project uses or pins (composer.json, package.json, Dockerfile base images, runtime settings), and any that are missing security fixes as of today. Include PHP2Shell (fixed in PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12), Node.js (22.23.4, 24.22.1, 26.12.1) and Next.js (15.5.28, 16.4.1).
3. Packages: run the package manager's audit and list anything high or critical.
4. Access: which keys each part of the app and each AI agent uses, and which have more access than they need.
5. Forms and routes with no login check or no rate limit.
For each finding: where it is, why it matters in one sentence, and the smallest fix. Tell me anything you can't check from the code, like the PHP version my server actually runs. Ask me before changing anything.

AI can miss things and can be wrong. Treat its findings as a to-do list, not a clean bill of health. And check the PHP or Node version on your server yourself: the prompt can only see what's in your project.

Sources

Everything above comes from these pages, read on October 27, 2026: PHP release announcement · PHP advisory CVE-2026-109618 · PHP advisory CVE-2026-109619 · The PHP Foundation · PHP supported versions · CISA alert · CISA KEV catalog · WordPress · Laravel · Vercel PHP bulletin · Vercel Node.js bulletin · OpenAI · OpenAI php2shell-checker · Anthropic · Node.js · Next.js · React · GitLab · W3Techs · GitHub Dependabot · GitHub leaked secrets · Stripe API keys · OpenAI API keys

Get better at growing apps.

New case studies and guides on how apps grow. Free, straight to your inbox.

Matt Neves, the creator behind Agentic Matt

Written by Matt Neves

I study how apps grow and break down the case studies for 18,000+ app builders as @agenticmatt. I test what I learn on my own apps.

More about me