blog

There's a third PHP2Shell bug. One setting protects you until the fix

If you run PHP websites, there's one more setting to change this week. PHP has reserved a third CVE linked to the PHP2Shell flaws, and this one won't be fixed until the next regular release. Until then, turning off one feature in php.ini protects you completely.

If you already did that last week, you can stop reading. Well done.

What happened

On 23 October the PHP project published an informational advisory about CVE-2026-115560, another way to run code remotely. The Register covered it the same day.

The good news is that it's much harder to trigger than the first two. According to PHP, it only happens under "an unusual combination of configuration and application code". Your app has to set something called the session serialize handler to one value in its configuration, then switch it back to the default with ini_set() before starting a session. And a feature called session upload progress has to be switched on.

Because that setup is rare, PHP is fixing it in the normal release cycle, not with an emergency release. A full advisory will come out with the next release.

So the updates you installed last week, 8.5.12, 8.4.27, 8.3.36 or 8.2.35, don't cover this one.

Does it affect you?

Probably not. Most PHP apps never touch the serialize handler at all. PHP says that apps which never change it at runtime "can keep the feature enabled".

The trouble is that most business owners have no idea whether their app does that, and I wouldn't expect them to. If it's WordPress with 30 plugins, or a custom app written by someone who left years ago, nobody's going to read every line to find out.

Session upload progress is switched on by default, according to the PHP manual. So unless someone has changed it, yours is on.

What to do this week

PHP's advice is simple: set session.upload_progress.enabled=0 until the next bugfix release. This is the same setting that was listed as a stopgap for the second PHP2Shell flaw back on 21 October, so if you set it then, keep it in place and you're done.

1. Check whether it's already off. On Debian or Ubuntu, this searches your PHP config files for it:

grep -r upload_progress /etc/php/

If nothing comes back, or it says On or 1, it's still on.

2. Turn it off in the right place. PHP's original advisory is clear that you should use php.ini, an FPM pool or the server configuration. Don't rely on ini_set() in your code or a .user.ini file. On Debian or Ubuntu with PHP-FPM, the tidiest way is a small file of its own. Swap 8.3 for your version:

echo "session.upload_progress.enabled = 0" | sudo tee /etc/php/8.3/fpm/conf.d/99-upload-progress.ini

If you use Apache with mod_php, put the same file in /etc/php/8.3/apache2/conf.d/ instead. If you've got more than one PHP version installed, do it for each one that serves websites.

3. Restart PHP. Like last week, running workers keep the old settings until they restart:

sudo systemctl restart php8.3-fpm

Or sudo systemctl restart apache2 for mod_php.

4. Check it took. For PHP-FPM:

php-fpm8.3 -i | grep upload_progress.enabled

You want to see Off. Running plain php -i checks the command line version, which uses a different config file, so it can tell you the wrong thing.

5. Test an upload. The setting only switches off PHP's built-in way of tracking upload progress, which an app reads from the session to show a progress bar. The manual page explains how it works. Uploads themselves still work. But if your site has an upload form, try it afterwards, just to be sure.

If you're on shared hosting

You probably can't edit php.ini yourself. Ask your host whether session.upload_progress.enabled is off for your account, and if not, whether they'll turn it off. It's a reasonable question and a good host will know the answer.

While you're in there

Two things from last week's advisory are worth a second look.

First, check you actually installed the PHP2Shell updates. php -v on the server, and anything below the versions above needs doing today, not this week.

Second, PHP says 8.2 reaches end of life on 31 December 2026 and gets no more security fixes after that. If you're on 8.2, you've got about two months to plan the move. Anything on 8.1 or older is already past it.

The bigger point

The PHP2Shell flaws have now produced three CVEs in a week. That's no criticism of PHP. Once people start looking hard at one bit of code, they tend to find more, and that's how it should work.

But it does mean the job isn't "install one update and forget it". Someone needs to keep reading the advisories as they come out and know what's on each server. If you're not sure how your PHP is set up, or which versions you're running where, that's exactly what my server health check is for.

For what this looked like in practice, here's how we handled PHP2Shell at Dev Partners.