LXer hardens against PHP2Shell

Posted by bob on Oct 26, 2026 12:59 PM EDT
LXer; By bob
Mail this story
Print this story

When the PHP2Shell vulnerabilities went public on October 21, they put every PHP web application on the internet at risk. Here is what we have done to keep LXer safe for our readers, and the simple steps anyone running PHP on Linux can take today.

On October 21, the PHP project disclosed two critical vulnerabilities that quickly became known as PHP2Shell. They are serious enough that projects such as SuperTuxKart, along with Wikimedia, DeviantArt and a number of government websites, took systems offline rather than risk being exploited while they patched. LXer runs on PHP, so we want to tell you where we stand, and share what we have learned for anyone else who runs a PHP site.

What PHP2Shell is

PHP2Shell is the nickname for two flaws in the PHP engine itself, CVE-2026-109618 and CVE-2026-109619. Both are rated critical (CVSS 9.2). In the words of the PHP project's advisory, they "can allow unauthenticated remote code execution": someone with no account and no password can make a web server run code of their choosing.

  • The first (out-of-memory corruption) lets PHP be interrupted while it is still setting up a request, after which the cleanup code trusts data that was never properly initialized.
  • The second (stale global state) leaves internal state from one request behind after its memory has been freed, where a later request handled by the same worker can pick it up.


Because the bugs are in PHP itself, it does not matter how carefully an application is written. Every way of serving PHP is affected: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP project rates mod_php as the highest risk, since a demonstrated exploit fires before any application code runs. Disclosure was planned for October 22 but was moved forward a day after the details leaked.

The fix is to update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your distribution's patched package.

Where LXer stands

This past weekend LXer completed its move to a new server built on Rocky Linux 10.2, with PHP 8.3 running under PHP-FPM and MariaDB 10.11. That server runs PHP 8.3.36, the release that fixes both PHP2Shell vulnerabilities, and we have confirmed that the PHP workers serving the site were restarted after the update was installed. That last check matters more than it might seem, as you will see below.

Patching PHP was the urgent part, but it was not the only work. Moving a site that has grown over twenty years onto a modern stack meant going through a lot of old code, and we used the opportunity to harden LXer well beyond this one bug:

  • Member passwords are now stored as bcrypt hashes, and logins use random session tokens in cookies marked HttpOnly, Secure and SameSite.
  • Lost passwords are handled with short-lived reset links.
  • We fixed old code that could pass visitor input to a shell command, and removed code that ran text stored in the database as PHP.
  • We reviewed the public pages for SQL injection and cross-site scripting, and retired an old member feature that let users publish their own HTML.
  • Requests that change data are checked to make sure they come from LXer itself, not from another site.
  • Files uploaded by our editors can never be run as code, and the whole site is served over HTTPS only.


None of this makes any site invulnerable, but it shrinks the target considerably.

What you can do today

If you run a website, a blog or an internal tool on PHP, here are the steps that matter, roughly in order.

1. Update PHP. Use your distribution's packages wherever you can:
  • Debian and Ubuntu:
    sudo apt update && sudo apt upgrade
  • RHEL, Rocky Linux, AlmaLinux, Oracle Linux and CentOS Stream:
    sudo dnf upgrade --refresh 'php*'
  • Fedora:
    sudo dnf upgrade --refresh
  • openSUSE and SLES:
    sudo zypper refresh && sudo zypper patch
  • Arch Linux:
    sudo pacman -Syu
  • Alpine:
    apk update && apk upgrade
Do not judge your package by its version number alone. Distributions often backport fixes into older versions: Ubuntu 24.04, for example, ships the fix in 8.3.6-0ubuntu0.24.04.13, a number that looks older than the upstream 8.3.36 but is patched. On the Red Hat family the package changelog may only say "rebase to 8.3.36" without naming the CVEs. Check your distribution's security advisory, such as Ubuntu's PHP2Shell notice, for the exact fixed package.

2. Restart PHP. This is the step that is easiest to forget. Updating the package replaces the files on disk, but PHP-FPM workers and Apache with mod_php keep running the old code until they are restarted:
sudo systemctl restart php-fpm
The service may be called php8.3-fpm (or similar) on Debian and Ubuntu, and with mod_php it is apache2 or httpd that needs the restart.

3. Check that the new code is really running. Running
php -v
only tells you about the command-line PHP, not the workers serving your site. On RPM-based systems, compare when the package was installed with when the service last started:
rpm -qi php-common | grep 'Install Date'
systemctl show -p ActiveEnterTimestamp php-fpm
If the service started before the package was installed, it is still running the vulnerable version. On the Red Hat family,
sudo dnf needs-restarting -s
lists services that need a restart; on Debian and Ubuntu, the needrestart package does the same job.

4. Remember containers and hand-built PHP. Updating the host does not touch PHP inside a container image. Pull the updated base image and rebuild. If you build PHP from source, upgrade to one of the fixed releases.

5. Leave unsupported PHP behind. PHP 8.1 and older no longer get fixes from the PHP project. Some vendors backport fixes, and the PHP team made minimal patches for 7.4, 8.0 and 8.1 available for this case, but the lasting answer is a supported PHP release.

6. If you truly cannot patch right away, the PHP advisory lists stopgaps that narrow the known attack paths without closing them, among them setting
session.upload_progress.enabled = 0
and a modest
post_max_size
in php.ini or your FPM pool (not in .user.ini files or with ini_set()), then restarting every worker. Treat these as a bridge to the update, not a replacement for it.

7. Make the next one easier. A few habits pay off every time:
  • Apply security updates automatically: unattended-upgrades on Debian and Ubuntu, dnf-automatic on Fedora and the Red Hat family, and plan for the service restarts that follow.
  • Subscribe to your distribution's security announcements.
  • Run PHP as an unprivileged user that cannot write to your site's code, and never allow PHP to execute in upload directories.
  • Give your application a database account with only the rights it needs.
  • Set
    expose_php = Off
    so your server does not advertise its exact PHP version to every visitor.


Thanks

Our thanks go to the PHP security team and to the distribution maintainers who had patched packages ready on disclosure day. If you notice anything on LXer that looks wrong, please let us know.

  Nav
» Read more about: Story Type: LXer Features, News Story, Security; Groups: Linux, LXer, PHP

« Return to the newswire homepage

This topic does not have any threads posted yet!

You cannot post until you login.