PHP2Shell: two critical holes in PHP that can't wait
On October 20, PHP announced an emergency security release for the next day. It fixed two bugs that let an attacker run their own code on a server without logging in. What they are, why they happened and what to do.
PHP fixes usually ship quietly. This time the PHP team warned in advance on October 20 that it would release a fix for two critical vulnerabilities rated CVSS 9.2 out of 10 the next day, and earlier if details leaked. They did leak, and attackers were trying them before the fix was out.
The bugs got the nickname PHP2Shell. They let an attacker run code on the server without a password, with the site's privileges: its files, the database password and write access wherever PHP can write. That covers practically every PHP site, whether it runs WordPress, Laravel, Nette or custom code. Apache with mod_php is the most exposed, because the attack lands before the application runs.
Fixed versions: 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 7.4 to 8.1 only have source patches, and older versions get nothing.
How it works
Both are use-after-free bugs: PHP uses memory it has already freed, which may by then hold the attacker's data.
CVE-2026-109618 is like a cook who drops everything and leaves when the counter runs out of space. The cleaner then tidies up according to a note the cook only half wrote. PHP does something similar when it runs out of memory: it jumps out of the current work immediately, and cleanup trusts half-initialized data.
CVE-2026-109619 is like a hotel where the room isn't fully reset between guests. A PHP server reuses the same processes for visitor after visitor. When a request is interrupted unexpectedly, a "note" pointing to memory that now belongs to someone else stays in the process, and the next request follows it.
Why it happened
PHP was built on the rule that everything is thrown away at the end of a request and the next one starts clean. For performance, though, processes are reused, and the rule breaks as soon as something somewhere isn't reset. Add the shortcut of "bail out immediately on out-of-memory", which assumes every place in the code is ready for it. And PHP is written in C, which doesn't check whether memory still belongs to you. So the bug comes from three old decisions meeting in situations nobody routinely tests.
In practice
According to Amazon, the first exploitation attempt came on October 17, four days before the fix. Right after the release hundreds of "exploits" appeared on GitHub, mostly fake. Security firms still caught real attempts, including one trying to plant a webshell, a script an attacker uses to control the server.
A typical victim looks unremarkable: a small e-shop on a cheap VPS, PHP last updated over the summer. An automated scanner breaks in after a few attempts, reads the database password and injects a card-skimming script into checkout. The site doesn't need a single bug in its own code.
This isn't overcautious. CVE-2024-4577 from June 2024 was being used by ransomware less than two days after disclosure.
What to do
- Update PHP and restart all its processes (PHP-FPM, Apache). Debian and Ubuntu often backport fixes into an older version, so a lower
php -vnumber doesn't necessarily mean you're vulnerable. Check your distribution's security tracker. - In Docker, rebuild the image with a freshly pulled base (
docker compose build --pull).up -dalone isn't enough. Then check the version inside the container. - On shared hosting, ask your provider whether they've updated.
- If you can't update right away, the temporary measures in the official advisory help, such as turning off
session.upload_progress. They don't fully close the hole, though. - Check the server. If it ran a vulnerable version, look for new files in the web root, new cron jobs and crashing PHP processes.
A website's security rests not only on its own code but on the environment it runs in. That's why it pays to have deployment set up so a fix takes a single command.
Sources: php.net – advance notice · php.net – releases · Root.cz · GHSA-w8hw-w9fx-j79w · GHSA-6wmf-4rv5-p3rp · Censys