News and analysis
PHP2Shell: what I check on my servers while the whole world patches a hole in PHP
A rundown of the php2shell week: what PHP, Cloudflare, Ubuntu, Docker and GitLab published, and the checklist I run on the servers I'm responsible for.
On October 21, the PHP project released fixes for two holes in the interpreter itself, CVE-2026-109618 and CVE-2026-109619, which got the name php2shell. Through them, code can be run on a server with no login or password, and every version since PHP 5.4 is affected. If your company has a website, a control panel or an internal service on PHP, it needed updating this week. Below is how such weeks go for me.
What happened and why the release moved up a day
On October 21, Simon Willison relayed the PHP Foundation's account: on October 20 at around 15:00 UTC the CVE numbers leaked to forums with an incorrect score of 10.0 (the real one is 9.2), and the project moved the release from October 22 to October 21. One of the firms that reported the vulnerability, Calif, published a video with a working exploit by mistake. The same post has the Wiz timeline: the vulnerability was found on August 19 and reported to the PHP team on August 24.
On October 21, Cloudflare explained the mechanics: both holes are in how PHP handles memory on an error. Two points from that post I would write on a sticky note: updating a plugin or the site's code doesn't help, PHP itself has to be fixed; and if a hosting provider runs PHP for you, you have to ask them for the update. Cloudflare turned on its WAF rules 9 hours before disclosure. On October 23 they added a note: a related vulnerability, CVE-2026-115560, has come out, it is present even in the updated 8.5.12, and it will be fixed in the next scheduled release.
On October 21, Ubuntu published a table of fixed packages, from php5 in 14.04 to php8.5 in 26.10, and a command to check with: apt list '?installed ?name(^php[0-9.]+$)'. There's a reminder there too: unattended-upgrades will install the patch within a day, but the PHP processes won't restart because of it. On October 22, Docker reported that the official images were updated within 24 hours of the patches: 8.2.35, 8.3.36, 8.4.27 and 8.5.12. If you can't update right away, Docker advises shutting the system down and points to the same recommendation from the FBI.
On October 22, GitLab published what I think is the most practical checklist of the week. Ubuntu and Red Hat backport the fix while keeping the old version number, so you have to compare package versions, and php -v will mislead you here. Images with a floating tag like php:8.3 should be rebuilt with docker build --pull, and derived images like wordpress or drupal get the fix only after their maintainers release them. And a list of what people forget: the internal dashboard, the marketing site, the CI image.
On October 21, OpenAI described the coordination: Calif found the vulnerability with the GPT-5.6 Sol model, Wiz found it independently, the PHP maintainers did the fixes, and OpenAI expects more findings like this. On October 21, OVHcloud issued instructions for VPS owners: check the version, update, restart the PHP services. On October 23, Percona reported: the Cloudflare rules were in place before the patch came out, the patch was applied immediately, and no signs of compromise were found.
Why this concerns a company that “has no PHP”
Take a car rental company. A contractor built the booking site three years ago, it lives on shared hosting, and nobody at the company remembers what language it's written in. The owner is sure he has no PHP. According to Cloudflare, PHP runs on almost 70% of websites, so most of the time it is there, and in the one place nobody is responsible for.
The conclusion for the owner: the list of “what we have running on PHP” needs to exist before the next hole like this comes out. In a quiet week it takes an hour to put together.
How I do it
For a PDR company in the US I've run a server since 2022: Debian in Google Cloud, with a MariaDB database, the API, the website and telephony on it. Security questions at the company come to me, and when there is a major breach somewhere in the world, I check whether it affects us. Our main backend is on Node.js and Python, but that doesn't cancel the check: I go down the list of everything installed on the server and in the containers and look at the package versions. I maintain the server, the VPN and the telephony myself, with no back-and-forth with a contractor. Since 2022 we have had no serious outages that needed a recovery.
The studio's website and the “Coffee Together” service live on a shared server with 2 GB of memory, in Docker behind Nginx. For “Coffee Together” the procedure is this: on an update, the old instance stops before the new one starts, and if the build runs out of memory, the image is built elsewhere and uploaded ready.
What I would do this week
- Make a list of everywhere PHP lives: hosted sites, control panels, forums, Docker images, CI images.
- Update the package and restart every process that runs PHP. Verify by package version.
- Rebuild containers with --pull; check derived images against the maintainer's release date.
- If you can't update now: turn on a WAF, restrict file uploads, and as a last resort shut the service down.
- Look through the logs for October 20 to 23 for odd requests and new files, and come back to this after the next PHP release.
And keep a verified backup, one you have restored from at least once, in case there was a breach after all.
Related reading
On why a system needs one server that stores state and checks permissions: the article The server: data, access and process execution. Service area: infrastructure you can release and restore. The PDR company's server is described in the technical partner to a PDR company in the US case and on the Debian in Google Cloud page. On the same topic: my update routine for Node.js, Python and Next.js, zero trust for a 30-person company and a backup nobody has restored. Earlier I looked at how to pick which vulnerabilities to fix and what SBOM and provenance are. If you have a server nobody has been responsible for in a long time, tell me what's running on it: Discuss your task.