Two flaws in PHP can let an attacker run code on a web server without logging in, according to the PHP project. For Apache with mod_php, the project says there is a demonstrated exploit where an unauthenticated request triggers the attack before any application code runs. The fixes shipped on 10/21/26. The fix is a PHP update. This post is our checklist for confirming the update reached the PHP that answers web requests.

This post is a checklist. It covers how to find your version, how to upgrade, and how to verify. It contains no exploit details, and nothing here needs you to test anything against a site you do not own.

What was fixed, and in which versions

Everything in this list comes from the PHP project’s advisory and the national vulnerability database (NVD), checked on 10/24/26.

  • The two CVEs are CVE-2026-109618 and CVE-2026-109619. NVD published both on 10/21/26.
  • NVD lists a CVSS 4.0 score of 9.2, Critical, for both. It also lists CVSS 3.1 scores of 9.8 for the first and 8.1 for the second.
  • The patched releases are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
  • PHP 8.1 and older no longer get updates from the PHP project. The project says some distributions and long-term-support vendors provide backported fixes, so contact your vendor or move to a supported version.
  • The project says the risk covers any PHP serving web requests: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. It considers the risk highest for mod_php.
  • Linux distributions and long-term-support vendors received the patches in advance, so your vendor may already have updated packages.

The flaw is in PHP itself. The PHP version on the server has to change.

The name PHP2Shell comes from outside the PHP project. NVD’s references link a Wiz post with that name in its address, and the PHP advisory does not use it.

Sources: PHP security advisory, CVE-2026-109618 and CVE-2026-109619.

A third issue, not fully published yet

On 10/23/26 the PHP project posted an informational advisory about a third item, CVE-2026-115560. This is what the project has said so far.

  • It suggests setting session.upload_progress.enabled=0 until the next regular bugfix release, to protect from an unlikely remote code execution vector.
  • That setting was already listed as a mitigation for CVE-2026-109619. If you applied it then, keep it in place.
  • The issue needs an unusual combination. An application sets session.serialize_handler to php_binary or php_serialize in its configuration, switches it to php at runtime with ini_set() before session_start(), and session upload progress is still enabled. Applications that never change the serialize handler at runtime can keep the feature enabled.
  • The project says it will publish a full advisory for CVE-2026-115560 with the next release.

Not published as of 10/24/26: a score, a list of affected versions and a fixed version. NVD returned no record for it when I queried it that day. Check the PHP advisory again when the next release lands.

Source: PHP informational advisory, 10/23/26.

The version checklist

Match your branch to the first version that is safe.

Your PHP branchFirst safe version
8.5.x8.5.12
8.4.x8.4.27
8.3.x8.3.36
8.2.x8.2.35
8.1 and oldernone from the PHP project, ask your vendor

A version lower than the one in your row is not patched. A version at or above it is.

If you run 8.1 or older, or a vendor’s own build, the version number alone may not tell you the whole story, because the project says vendors provide backported fixes. Read your vendor’s advisory for the build that carries the fix.

Step 1: find the version you are running

Many servers have more than one PHP. The one you care about is the one serving your website.

Start with the command line:

Terminal window
php -v

That reports the command-line PHP. Compare it with the four patched versions above. Then find out what the web server reports. Your host’s control panel or server information screen usually shows it. If you manage the server yourself and have no other view, a temporary page prints it:

<?php echo PHP_VERSION, ' ', PHP_SAPI;

Illustrative minimal snippet. Request it in a browser, read the result, and delete the file straight away. Do not leave version information on a public page.

If the two versions disagree, the web one is the one that matters.

Step 2: upgrade

Take a backup first, one you know how to restore. Moving across a branch can break old code, so test somewhere that is not your live site when you can.

Upgrade through the package channel you already use. That is your Linux distribution’s own packages, your host’s control panel, or your image or platform provider. Then read that provider’s advisory or changelog for the CVEs to confirm the build you installed carries the fix. Do not add a new package source just for this.

On managed hosting, pick a patched version in the host’s settings and ask the host to confirm in writing which release is running.

If you cannot update today. The PHP advisory lists settings that reduce exposure and says they do not make an installation safe. Only an update does. The project lists:

  • memory_limit=-1, set where applications cannot override it
  • a low post_max_size (8M without uploads, 32M with) and an upload_max_filesize below it
  • session.upload_progress.enabled=0, with every worker restarted
  • on PHP 8.5, fatal_error_backtraces=0, with every worker restarted

It also says not to use RLIMIT_AS or RLIMIT_DATA. Read the advisory itself before changing any of these.

Step 3: prove it took

An upgrade you did not check is only a hope. Do all of these.

  • php -v shows a version at or above your row in the table.
  • You restarted PHP-FPM, or the web server if PHP runs inside it, so the new binary is actually running.
  • The version the web server reports is at or above your row too, not just the command line. A fixed php -v on a site that still runs the old PHP is the easiest way to think you are safe.
  • Your site still loads, you can log in, and a form or checkout you care about still works.
  • Any temporary version page is deleted.
  • You wrote down the date, the version before and after, and how you checked.

Where this leaves you

Finding the version is the first half. Checking the PHP that serves the site, after a restart, is the second. If your host or a former developer set the server up and you do not know where to begin, there is a page for that: get help with PHP2Shell.

The last check, and what done looks like

Run one more check before you close the ticket. Find your branch in the table, then read the version the web server reports. That is the line from the temporary page, or the PHP version shown in your host’s panel.

You are done when the web server’s version is at or above the first safe version for your branch: 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Anything below the number for your branch fails. Then run php -v. If it prints a different version from the web server, the web server’s version is the one that counts, and the command-line PHP is a second install to update too.

If the web server still reports a version below your row, the upgrade did not reach the PHP that serves your site. Repeat the restart, or check which PHP binary the web server is configured to use. On 8.1 or older, or on a vendor build, the version number is not the answer. Done means your vendor’s advisory names the build you run as carrying the fix.

Write the date, the before and after versions, and how you checked, so the next person does not have to repeat it. The finish line is one reading: the version your web server reports, at or above 8.5.12, 8.4.27, 8.3.36 or 8.2.35 for its branch.