Agentic AI
PHP2Shell: The Patch Took a Day. The Sites Nobody Remembers Are the Real Risk.
How we checked our WordPress sites after the PHP2Shell fix, which CMS are affected, how to patch PHP on your own server, and why "we don't run PHP" is not the whole answer.
On October 22, the day PHP shipped its fixes for PHP2Shell, Jason Clinton of Anthropic posted a warning to security leaders: "as bad as things have gotten in the past 4 days, they are going to get a lot worse before they get better." His advice was not to buy more AI. It was to go to the board and ask for help with the basics, because "we need to hold on for ~18 months." You can read Jason Clinton's post on X.
We did not wait for the board meeting. Our sites were running the fixed PHP build by early morning on October 23, hours after the releases came out, and that same morning I sat down to check the basics on every one of our WordPress sites. The safety setting that blocks the most reported attack path was off. Every WordPress core file matched the official copy. By most checklists, we were done.
Then a plugin check flagged nine files that should not have been there.
They turned out to be harmless: leftovers from a plugin update in 2024 that nobody had looked at since. But that is the part of PHP2Shell worth writing about. The patch was the easy part. The real exposure is the old file, the forgotten install and the subdomain nobody remembers, and AI is about to make finding them much faster for everyone, including attackers.
Key takeaways
- PHP2Shell is a pair of flaws in PHP itself (CVE-2026-109618 and CVE-2026-109619), announced by PHP on October 21, 2026 and fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released October 22. Updating WordPress, Drupal or any other app does not fix it. Only the PHP version on the server does.
- Any CMS built on PHP is exposed until its server is patched: WordPress, Drupal, Joomla, Magento, PrestaShop, Craft, TYPO3, MediaWiki, Moodle and more.
- A hosted website builder does not run your PHP, so there is nothing for you to patch for this bug. That does not mean your company has no PHP. Blogs, docs, careers pages and old campaign sites often live somewhere else.
- Any single
.phpfile that answers requests is enough to be exposed, even a one-linehello.php. - If you run your own server, you patch PHP yourself: update the packages, restart every PHP worker, then verify on the live site.
- AI is finding bugs faster than teams can fix them. Expect more of these, in PHP and everywhere else.
- The useful work this week: list every site you run, know who patches each one, verify the patch on the live site, and remove what you no longer use.
What is PHP2Shell, in plain words?
PHP is the programming language that runs most of the web. According to W3Techs' PHP usage statistics, it runs on about 70% of the websites whose server-side language can be detected. WordPress is the best-known example, but it is far from the only one.
PHP2Shell is the name for two flaws in the PHP engine, tracked as CVE-2026-109618 and CVE-2026-109619. A CVE is the public ID number given to a known security flaw. One is in how PHP handles running out of memory, which can leave a request's data half-built. The other lets data tied to a request live on after PHP has freed it. Put together, they let someone run their own code on a server with a single request, without logging in, before your application code even starts. The details are in the official PHP 8.2.35 release announcement.
That last part matters more than it sounds. The request only has to reach PHP. What the file does is irrelevant. A hello.php with one line of code, a phpinfo.php left over from a server setup, an old contact form handler on an otherwise static site: any .php file the server will run can be the way in. A site is potentially exposed if it has a single PHP file that answers requests.
The PHP team published a security advisory on October 21, 2026 and shipped the fixed releases on October 22. The official PHP 8 changelog lists both fixes under one line: "Avoid state corruption via bailout." The team was direct about what to do. Their guidance is that there are no complete mitigations, and updating is the only safe choice.
Three facts matter most for site owners:
- The bug is in PHP, not in your CMS. A fully updated WordPress site on an old PHP build is still exposed.
- The version number is not always proof. Hosting vendors often patch older builds without changing the version number. Proof is one of three things: a fixed upstream version, a build date after October 21, or a vendor changelog that names both CVEs.
- Old branches got no official fix. PHP 8.1 and older are past end of life, so only some hosting vendors have patched them. In its PHP2Shell exposure analysis, Bitsight found that only about a third of the PHP installs it could identify run a branch covered by this update.
Why are security leaders saying PHP2Shell is only the start?
This bug was found with AI. OpenAI says its models helped researchers find it through its Patch the Planet program, and that a second team found it independently. In its Patch the Planet disclosure post, OpenAI called it an example of the "Defender's Window" in action: "to our knowledge, frontier AI was able to find this vulnerability ahead of attackers, giving defenders time to prepare."
That window was short. Details leaked before the planned release, and attack traffic was reported before the fix was public.
Anthropic described the bigger shift in its Project Glasswing progress update: "Progress on software security used to be limited by how quickly teams could find new vulnerabilities. Now it's limited by how quickly they can verify, disclose, and patch the large numbers of vulnerabilities found by AI." Earlier this year, Axios reported that an Anthropic model found more than 500 previously unknown high-severity flaws in open-source software. The same capability is behind the agent security questions I covered in how to secure AI agents in the enterprise.
That is the backdrop to Jason Clinton's post. Bugs are being found faster than ever, the fixes are not keeping pace yet, and his estimate is that defenders need to hold on for about 18 months. In the same post he said it plainly: "please go to your boards and ask for help right now. not for ai, for the basics."
Here is why PHP in particular draws attention:
- Old code in a memory-unsafe language. The PHP engine is decades of C code. That is exactly the kind of code where AI tools are finding memory bugs fastest.
- One bug leads to its neighbors. When a flaw like this is published, researchers and attackers look for the same mistake nearby. The area of PHP involved here will get a lot of attention for a while.
- Fixes become instructions. Once a patch ships, anyone can compare the old and new code to see what changed. AI shortens the time from patch to working exploit.
- A large, slow-moving install base. Millions of sites run PHP, many on branches nobody patches anymore, on servers the site owner does not control.
None of this means PHP is uniquely bad. It means PHP is big, old and everywhere, which makes it the first large target. Every language and platform with a long history is in the same queue.
Isn't Facebook still written in PHP?
Not in the way most people think. Facebook started on PHP, then built its own engine (HHVM) and its own language based on PHP, called Hack. Meta runs Hack on HHVM, and the HHVM project itself no longer recommends HHVM for plain PHP projects (see the HHVM overview on Wikipedia).
PHP2Shell is a flaw in the standard PHP engine. HHVM is a separate codebase, so this particular bug does not carry over. The lesson is still useful: the companies that outgrew PHP did it by owning the whole stack, engine included. Most website owners do the opposite. They depend on a host, or on whoever runs their server, to keep the engine patched. That is why the first question below matters so much.
How we checked our sites for PHP2Shell, step by step
We ran these checks on our own WordPress sites and on our clients' sites that run WordPress. The steps are the same for any PHP site.
If several sites share one server account, treat them as one unit. They usually run as the same user, so a break-in on one site can reach every other site on that account, along with anything stored there, such as deploy keys.
1. Who patches PHP?
Start here, because the answer decides everything else.
On shared hosting, the provider patches PHP for every account on the server. If you are on shared hosting and cannot confirm this from your control panel, open a ticket and ask for three things: the exact PHP version and build date serving your site, confirmation that all PHP workers were restarted after the update, and whether session upload progress is off.
On your own server, nobody does it for you. That covers a VPS, a dedicated server, a cloud instance, or containers you build yourself.
If you run your own server
1. Back up first. Take a copy of the files and the database before you touch anything, and keep it outside the web root:
mkdir -p ~/backups && chmod 700 ~/backups
wp db export ~/backups/db-$(date +%F).sql --path=/var/www/example.com
tar -czf ~/backups/files-$(date +%F).tar.gz -C /var/www example.com2. Find every PHP build on the server, not only the one your main site uses. Servers often have several versions installed side by side, and an old one can still be serving a forgotten folder or subdomain:
ls /usr/bin/php* /usr/sbin/php-fpm* 2>/dev/null
systemctl list-units --type=service 'php*'3. Update from your package source, then restart. At the time of writing:
| Setup | Update | Then restart |
|---|---|---|
| Ubuntu or Debian | sudo apt update && sudo apt install --only-upgrade 'php8.3*' (use your branch) |
sudo systemctl restart php8.3-fpm and the web server |
| RHEL, AlmaLinux or Rocky with a PHP repository | sudo dnf upgrade 'php*' |
sudo systemctl restart php-fpm and the web server |
| cPanel/WHM server | sudo dnf upgrade 'ea-php*' |
Restart PHP-FPM and the web server from WHM |
| CloudLinux | sudo dnf upgrade 'alt-php*' |
Restart the web server and check no old PHP processes remain |
| Docker | Rebuild from a fixed official image tag with docker build --pull --no-cache |
Redeploy every container |
Distribution packages often keep their own version numbers, so look for the distribution's security notice that names both CVEs rather than the upstream version.
4. Restart every PHP worker. PHP-FPM is the service that runs PHP for the web server, and it keeps a pool of PHP processes running. A new binary on disk does not replace the PHP processes already running in memory. Until they restart, the old, vulnerable code is still answering requests.
5. Verify on the live site, not in the terminal, with the check in step 2 below.
6. No fixed package for your branch? PHP 8.1 and older have no official fix. Move to a supported branch on a staging copy first, test the pages that matter, then roll it out. Until then, use the stopgaps further down.
2. Which PHP does the website actually run?
This is the step most checklists skip. The php -v command in a terminal shows the command line version. The website can run a different build entirely, set per folder or per domain.
The reliable check is a temporary PHP file with an unguessable name, opened through the website and deleted right after:
cd ~/public_html
F="check-$(head -c6 /dev/urandom | od -An -tx1 | tr -d ' \n').php"
echo '<?php echo PHP_VERSION, " | ", PHP_SAPI, " | upload_progress=", var_export(ini_get("session.upload_progress.enabled"), true);' > "$F"
curl -s "https://example.com/$F"; echo
rm -f "$F"Seven sites answered with a PHP version, and all seven returned the fixed release for their branch, with a build date of October 22 and upload progress off. The rest were static, redirected elsewhere, or sat behind a login.
One site that is still in use did not answer at all. It is now on our list to look at, which is exactly the kind of thing this check is for.
3. Has anything changed since the exposure window opened?
Attack traffic was reported before the fix went public, so we treated October 20 as the start of the window and listed every PHP file changed since then:
find ~/public_html -type f -name '*.php' -newermt 2026-10-20 \
-not -path '*/cache/*' | sed -E 's#(/wp-content/(plugins|themes)/[^/]+).*#\1/#' | sort | uniq -cThe raw list had 790 files. Grouped by plugin, it came down to 13 lines, and every one was explained: six files from our own deploys that week, and routine updates to four plugins, one of them a caching plugin with 187 files on each of three sites. We also confirmed there were no PHP files inside upload folders, no scheduled jobs we did not create, and no new login keys on the server.
4. Do the files match the official copies?
WP-CLI, the command line tool for WordPress, can compare core files and wordpress.org plugins against their official checksums with wp core verify-checksums and wp plugin verify-checksums:
wp core verify-checksums
wp plugin verify-checksums --allCore matched on all four installs. Of the 40 plugins that could be checked, 39 matched, including every plugin that had changed since October 20. That confirmed those changes were real updates and not someone else's code. Paid plugins and theme add-ons cannot be checked this way, because wordpress.org does not have their checksums. Those need a backup to compare against.
5. The nine files
One plugin failed: nine files that the official version does not include. Here is how we worked it out:
- All nine were dated August 2024. The plugin itself was installed in November 2024. So the files were older than the current version, not added recently.
- None of them contained the usual signs of injected code (
eval,base64_decode,shell_execand similar). - They were all parts of a feature the plugin had removed in a later version.
An update in 2024 had replaced the plugin's files without removing the old ones. We reinstalled a clean copy of the same version, and the check passed.
Leftover files like these are common, and in this case they were harmless. The point is that we did not know they were there until we looked, and two years had gone by.
Which CMS are affected by PHP2Shell?
Any software that runs on the standard PHP engine is exposed until its server runs a fixed build. That includes:
- WordPress and WooCommerce, including "headless" setups where a separate front end pulls content from a WordPress backend. The backend is still PHP.
- Drupal, Joomla, TYPO3, Craft CMS and Statamic.
- Magento and PrestaShop for online stores.
- MediaWiki, Moodle, Nextcloud and phpBB, which often run inside companies and schools, outside the marketing team's view.
- Custom PHP code and frameworks such as Laravel and Symfony.
None of these projects can fix this in their own code. Each one depends on the PHP build underneath it. A CMS on Node.js, Python or Ruby is not affected by this bug, but it has its own engine, its own dependencies and its own turn coming.
"We're not affected": what website builders get right, and what they leave out
Several hosted website builders have told customers they are not affected. For the bug itself, that is fair. On a fully hosted builder, you do not run PHP, so you have nothing to patch.
What the message leaves out is everything around the builder:
- The marketing site is rarely the only site. I have seen many companies with a website builder for the homepage and a WordPress install for the blog, the docs, the careers page, an old event site or a campaign landing page from three years ago. The board asked "are we affected?", and the honest answer depends on all of them. Most companies also stop looking at a site's files once it launches, a pattern I wrote about in why a site that scores 100 on Lighthouse can still be unreadable to AI search.
- Your site connects to other systems. Forms, scheduling tools, chat widgets, analytics scripts and integrations all reach into other services. Some of those run PHP. Many hold your data.
- This week's other incidents had nothing to do with PHP. API keys leaked from several AI developer tools in the same days. Stolen keys work the same way whatever your site is built on.
- You cannot check the patch yourself. On a hosted builder you trust the vendor's word. That is often a good trade, but it is a trade, and "not affected" is a statement you cannot verify.
- The wave is not about PHP. The AI tools that found this bug can read any codebase. PHP is first because it is big and old, not because it is the only one.
The useful question is not "does our website builder use PHP?" It is "where does PHP run anywhere under our name, and who is patching it?"
What to do if you can't patch PHP yet
If you run your own server, or your host has not shipped the fix, there are stopgaps. Treat them as time to test the update properly, not as a fix.
A web application firewall. Cloudflare added rules for PHP2Shell to its managed rulesets, on by default for all plans including Free, starting before the public disclosure, according to Technobezz's report on Cloudflare's PHP2Shell rules. On paid plans, confirm the managed ruleset is deployed and set to block. Two limits: attackers are already changing their payloads to get around the rules, and a firewall only protects traffic that goes through it. If your server's address is public (old DNS records, mail records on the same server), requests can skip the firewall entirely. Restricting your server to accept web traffic only from the firewall's IP ranges closes that gap. Cloudflare publishes its current IP ranges for this.
Turn off session upload progress. Few applications use it, WordPress included. It is a per-folder PHP setting. On your own server, set it in php.ini or the PHP-FPM pool configuration and restart PHP. On most shared hosts, one line in a .user.ini file in the site's root folder does it:
session.upload_progress.enabled = 0Some hosts expose the same setting in the control panel. Then run the runtime check above to confirm it reads 0 on the live site. Researchers report that this blocks the most reported attack path but not every variant, so it buys time and nothing more.
Test the update before it goes live. The fix is a significant change to the PHP engine. Take a full backup of files and database, apply the new PHP build to a staging copy, click through the pages that matter (forms, checkout, logins), then roll it out with the firewall still in place.
If none of this is possible soon, take the site offline. The UK's National Cyber Security Centre urged organizations to consider taking unpatchable systems offline until they can be fixed.
PHP2Shell checklist you can run this week
- List every site and subdomain under your name, including blogs, docs, careers, event and campaign sites, and anything on an old domain that still resolves.
- Write down who patches each one: you, your host, or the platform vendor.
- Get proof, not reassurance: a fixed PHP version, a build date after October 21, 2026, or a vendor changelog naming both CVEs.
- Check the live site, not the terminal. Use the temporary file check above.
- Turn off session upload progress where you control PHP settings, and keep it off.
- Check files against official copies.
wp core verify-checksumsandwp plugin verify-checksums --allfor WordPress, or compare with a backup taken before October 20. - Remove what you no longer use: old plugins, staging copies, test installs, stray files like
hello.phporphpinfo.php, and sites nobody owns anymore. On a site that should be static,find /var/www/example.com -name '*.php'should come back empty. - Rotate keys if anything looks wrong: hosting and database passwords, WordPress salts, API keys and deploy keys.
- Plan the next upgrade. PHP 8.2 reaches end of life on December 31, 2026, according to PHP's supported versions page. Moving to a newer branch now is cheaper than doing it during the next emergency.
The basics, for the next 18 months
When we started the review, the patch was already in place. Everything worth doing came after: proving which PHP each site really ran, explaining every changed file, and finding nine files from 2024 and a site that did not answer.
That is what "the basics" means when AI can read every line of old code faster than any team. Patching is necessary, and often someone else does it for you. Knowing what you run, who patches it and what is sitting on it is the part only you can do. It takes an afternoon, and it is the same work whether the next flaw is in PHP or somewhere else.
FAQ
What is PHP2Shell? PHP2Shell is the name for two critical flaws in the PHP engine, CVE-2026-109618 and CVE-2026-109619. They let an attacker run code on a server with a single request, without logging in. PHP fixed them in 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released October 22, 2026.
Does updating WordPress fix PHP2Shell? No. The flaws are in PHP, the engine WordPress runs on. Updating WordPress, plugins or themes does not change the PHP version. Only a fixed PHP build on the server does.
How do I know if my host has patched PHP? Check the version and build date on the live site with a temporary PHP file, as shown above, or ask your host for the exact version, build date and restart time. The fixed releases are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. A patched build of an older branch may keep its old version number, so look for a build date after October 21, 2026.
Can a single hello.php file make a site vulnerable? Potentially, yes. The flaw is triggered when a request reaches PHP, before the file's own code runs. Any .php file the server will execute can be the entry point, so remove stray test files and check that static sites have no PHP files at all.
How do I patch PHP2Shell on my own server? Back up files and the database, update the PHP packages from your distribution or vendor, restart PHP-FPM and the web server so no old workers keep running, then confirm the version and build date on the live site with a temporary PHP file.
My site is on a hosted website builder. Am I safe? From this specific bug, very likely yes, because you do not run PHP. Check whether anything else under your name does: a blog, docs site, careers page or old campaign site. Those are often on WordPress and often forgotten.
Is a firewall like Cloudflare enough? No. A firewall helps while you test the update, but attackers are already changing their payloads, and it does nothing for requests that reach your server directly. Patch PHP regardless.
What if I'm on PHP 8.1 or older? There is no official fix for those branches. Some hosting vendors have patched their own builds, so ask yours. Otherwise, plan the upgrade now, and keep the firewall and upload progress stopgaps in place until it is done.
Roberto Iriondo is a fractional CMO and technical marketing advisor for AI companies, working on website strategy, SEO, GEO and go-to-market. He co-founded Towards AI and runs Generative AI Lab Co., where he publishes small product experiments and notes from real work.
Let's connect on LinkedIn or see how I work with AI teams on marketing.