Security alert · Critical vulnerability

PHP2Shell: fix it, or migrate the PHP versions that will not be fixed.

PHP2Shell is the name given to two critical vulnerabilities in the PHP engine, CVE-2026-109618 and CVE-2026-109619, rated 9.2 out of 10 (CVSS v4.0) and disclosed on 21 October 2026. Combined, they allow code to be executed on the server, remotely and without an account, wherever PHP 5.4 or a later version runs. The flaw is in PHP itself: WordPress, Drupal, Symfony or custom code are exposed in the same way.

Sourced facts: PHP advisories, CVE records, php.net · sources consulted on 22 October 2026

Page updated on

§ 01 / Sheet

The vulnerability in seven points.

The items below come from the security advisories published by the PHP team and from the CVE records; details on the attack vector come from Sansec.

Identifiers
CVE-2026-109618 · CVE-2026-109619
Severity
CVSS v4.0: 9.2 (critical)
Impact
Remote code execution, without authentication
Affected versions
PHP 5.4 and every later version
Official fix
21 October 2026, 4 pm Paris time: PHP 8.2 to 8.5 only
Fixed versions
PHP 8.2.35 · 8.3.36 · 8.4.27 · 8.5.12
No fix
PHP 5.x, 7.x, 8.0 and 8.1

CVE-2026-109618

Code execution through corruption after an out-of-memory error

When a request exhausts the memory allotted to PHP, the interruption leaves request data in an invalid state, which the end-of-request routine then reads again. According to the PHP advisory, several ways of causing this out-of-memory condition go through the parsing of multipart request bodies. Sansec adds that this flaw can also send fragments of server memory back to the client.

CVE-2026-109619

Code execution through stale global state

Some of PHP’s global state keeps a pointer to the memory of a request that has already been freed. The next request handled by the same process can then read this stale state before resetting it, which opens the way to code execution.

The PHP advisory describes Apache with mod_php as the most exposed case: code execution was demonstrated there over HTTP, with the default configuration, before the application code even runs. PHP-FPM is also affected according to source code analysis, even though no complete attack has been demonstrated on it. In every case, updating PHP is the only complete protection.

§ 02 / Timeline

From discovery to exploitation.

Times in UTC, as in the sources; add 2 hours for Paris time in October.

  1. 1 August 2026

    Step 1: Discovery

    Calif researchers find several remote code execution paths in PHP.

  2. 11 August 2026

    Step 2: Reported to PHP

    Calif reports the first issue to the PHP team: coordinated disclosure begins.

  3. 24 August 2026

    Step 3: Second report

    Wiz Research in turn reports the vulnerabilities to the PHP team.

  4. 20 October 2026

    Step 4: Announcement and leak

    PHP announces a fix for the next day, 14:00 UTC. Details leak; watchTowr confirms remote code execution.

  5. 21 October 2026 · 07:43

    Step 5: First attacks

    Cloudflare reports the first attacks, before the fix is published.

  6. 21 October 2026 · 14:00

    Step 6: Fix released

    PHP releases 8.2.35, 8.3.36, 8.4.27 and 8.5.12 (4 pm in Paris). End-of-life branches get no fixed version.

  7. Then

    Step 7: Mass exploitation expected

    The analyses and an attack tool are public; Sansec expected automated attacks within fifteen minutes of the fix.

§ 03 / Versions

Which version to install, by branch.

Every PHP version since 5.4.0 (2012) contains the vulnerable code, according to Sansec. The official advisories only list a fixed version for the maintained branches, 8.2 to 8.5.

PHP2Shell: version to install by branch
BranchFixed versionStatusNote
PHP 8.5 8.5.12 Fixed Security support until 31 December 2029
PHP 8.4 8.4.27 Fixed Security support until 31 December 2028
PHP 8.3 8.3.36 Fixed Security support until 31 December 2027
PHP 8.2 8.2.35 Fixed, ending soon Security support until 31 December 2026 only: plan a migration
PHP 8.1 and 8.0 None No fix End of life: no fixed version
PHP 7.x None No fix End of life: no fixed version
PHP 5.4 to 5.6 None No fix End of life: no fixed version

Some Linux distributions or hosting providers may offer a fix backported to an older branch; Sansec advises asking them. It is not a version maintained by the PHP project: the lasting solution remains migration.

§ 04 / Check

Check the PHP version actually served.

Several PHP versions often live on the same server: the command-line one, one or more PHP-FPM, sometimes mod_php or containers. The “php -v” command only gives the first one. What matters is the version that handles each site’s requests.

  1. Step 1 : List the installed PHP versions

    “php -v” gives the command-line version, useful for scheduled tasks, but not necessarily the site’s. On Debian and Ubuntu, each installed version has its folder in /etc/php/.

    php -v
    ls /etc/php/
  2. Step 2 : Query each PHP-FPM and its pools

    Each PHP-FPM version has its binary and its pools. The exact name depends on the distribution. Then find which pool, or which socket, each site uses in the web server configuration.

    php-fpm8.3 -v
    ls /etc/php/*/fpm/pool.d/
    grep -Rn "proxy:unix\|fastcgi_pass" /etc/apache2/sites-enabled/ /etc/nginx/sites-enabled/ 2>/dev/null
  3. Step 3 : Check a request actually served

    Only a page executed by the web server is authoritative. If the expose_php directive is on, the X-Powered-By header gives the version. Otherwise, upload a temporary phpinfo() with an unpredictable name and restricted access, and delete it right after reading it.

    curl -sI https://your-site.example/ | grep -i x-powered-by
  4. Step 4 : Do not forget containers

    In a container, PHP ships inside the image: updating the host server does not change it. Query each service, then rebuild the image on a fixed version.

    docker compose exec <service> php -v

§ 05 / Emergency mitigation

Filter multipart uploads before they reach PHP.

According to Sansec, every known trigger goes through a “multipart/form-data” request, the file upload format, which PHP parses before the application runs. The PHP advisory also recommends blocking these requests upstream when the application does not need them.

Apache: in each VirtualHost that serves PHP, then reload
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^POST$ [NC]
RewriteCond %{HTTP:Content-Type} ^[[:space:]]*multipart/form-data([;,[:space:]]|$) [NC]
RewriteRule ^ - [F,L]
nginx: in each server block that passes to PHP (rule published by Sansec)
if ($http_content_type ~* "multipart/form-data") { return 403; }
Check: a multipart upload must be refused (403), a regular form must go through
curl -s -o /dev/null -w '%{http_code}\n' -F 'test=1' https://your-site.example/
curl -s -o /dev/null -w '%{http_code}\n' -d 'test=1' https://your-site.example/

Test the configuration before reloading (“apachectl configtest” or “nginx -t”) and keep a copy of the previous one.

Sansec mentions other temporary measures: taking the site offline behind a static page, accepting only GET and HEAD requests, or changing two PHP settings (session.upload_progress.enabled and memory_limit). These settings only protect partially, and a PHP developer warned that disabling upload progress is not enough on its own.

§ 06 / Fix

Apply the fix.

For PHP 8.2 to 8.5, the fix is a simple version update, provided it actually reaches the PHP that serves your sites.

  1. Step 1: Get the fixed version

    Through your distribution’s packages, the rebuilt official Docker image, or your hosting provider. Check that your package source actually offers the fixed version: according to Sansec, the Remi repository, common on RHEL servers, had not published it on 21 October.

  2. Step 2: Restart every PHP process

    A PHP-FPM or Apache process already running keeps the old binary in memory until it is restarted. Restart each PHP-FPM service and the web server, version by version.

  3. Step 3: Check on a served request

    Check again the version actually served for each site: that check confirms the fix, not the package manager.

  4. Step 4: Remove the mitigation

    Once the fixed version is confirmed, remove the multipart filtering and the temporary settings, then test file uploads again.

§ 07 / Migrate

PHP 5.x, 7.x, 8.0 and 8.1: migrate to a maintained version.

These branches have reached end of life: the PHP project no longer publishes fixes for them, neither for PHP2Shell nor for future vulnerabilities. The emergency mitigation buys time, nothing more. The way out is a migration to PHP 8.3 or 8.4, often together with the framework. PHP 8.2, fixed this time, in turn stops being maintained on 31 December 2026.

Fixed-price migration, on a written quote before we start.

§ 08 / Sooatek

What Sooatek does for you.

An intervention announced beforehand, checked afterwards, preceded by a backup. Directly or white-label for agencies.

  1. Step 1: Inventory of the PHP versions in service

    Each server, FPM pool and container; the version served site by site; exposed sites ranked by priority.

  2. Step 2: Mitigation applied and tested

    Multipart filtering before PHP, test of a refused upload and of an accepted form, list of disabled features shared beforehand.

  3. Step 3: Verified update

    PHP 8.2 to 8.5 moved to the fixed version, processes restarted, check on a served request, mitigation removed.

  4. Step 4: Migration of end-of-life versions

    Inventory, before/after test bench, production release approved by you, rollback planned.

On our own servers, we applied this mitigation on 21 October 2026.

Fixed-price emergency intervention, per server, on quote.

The Security hardening and NIS2 readiness offer

§ 09 / Questions

Frequently asked questions about PHP2Shell.

Is updating WordPress, Drupal or Symfony enough against PHP2Shell?

No. PHP2Shell is a flaw in the PHP engine, not in application code: an up-to-date WordPress, Drupal or Symfony remains exposed if the PHP that serves it is not fixed. The only complete fix is updating PHP on the server, to 8.2.35, 8.3.36, 8.4.27 or 8.5.12.

Is PHP-FPM less exposed than mod_php?

The PHP security advisory describes Apache with mod_php as the most exposed case: code execution was demonstrated there with the default configuration. PHP-FPM is also affected according to source code analysis, even though no complete attack has been demonstrated on it. In both cases, PHP must be updated.

My site is on shared hosting: what should I check?

The PHP version actually served to your site: through the X-Powered-By header if present, or through a temporary protected phpinfo(), deleted right away. If the version is not 8.2.35, 8.3.36, 8.4.27, 8.5.12 or later, ask your hosting provider for the update, or for a move to a maintained branch if you are on PHP 8.1 or older.

Is disabling session.upload_progress enough?

No. It is a partial measure: according to Sansec, a PHP developer warned that disabling upload progress is not enough on its own, and the PHP advisory points out that only the update fully fixes the flaw. Combine it, in the meantime, with filtering multipart uploads before they reach PHP.

Will filtering multipart requests break my site?

It cuts off file uploads (résumés, documents, images, attachments) and forms sent as multipart, sometimes order forms. The rest of the site keeps working. Test the critical user journeys after putting it in place, warn the users concerned and remove it as soon as PHP is up to date.

Is there a PHP2Shell fix for PHP 7.4 or 8.1?

No official version: the PHP security advisories only list fixed versions for branches 8.2 to 8.5. Some distributions or hosting providers may offer a backported fix; ask them. The lasting solution is migrating to PHP 8.3 or 8.4.

Should passwords be changed after the update?

It is prudent if the server stayed exposed. Sansec states that CVE-2026-109618 can send fragments of server memory back to the client, which may contain passwords, session tokens, API keys or private keys. Take stock of the secrets used on this server and renew the most sensitive ones.

A PHP server to check, a version with no fix to migrate?

Tell us which application is affected, its PHP version and where it is hosted. We get back to you in writing with a first opinion and the possible next step. Do not send passwords or exploitable details.