php2shell

CVE-2026-109618 · CVE-2026-109619 · live notes

Patched: PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 are out. Update now.

PHP release: 14:00 UTC · 10:00 EDT · 07:00 PDT

  • Yes Exploited in the wild?
  • Unconfirmed PoC possible, unconfirmed
  • No Full mitigation available?
  • Yes Patch available?

Auto-refreshes every 10s. Last updated 14:02 UTC · 10:02 EDT · 07:02 PDT. Send a tip

php2shell, short version

Live updates

  1. Cloudflare: WAF rules are on for every plan, Free included, plus a new response-side check that can block a matching origin response. Paid plans: confirm the Managed Ruleset (efb7b8c9…) is deployed. Cloudflare says patch anyway; the WAF is an extra layer. It worked with the PHP Foundation, OpenAI and Wiz on the fix. Cloudflare

  2. Laravel: Cloud patches running apps in place, with no redeploy needed, and pauses deploys while it does. On Forge, click "Update PHP" on 8.2–8.5 servers. Vapor redeploys native PHP 8.3+ runtimes itself; rebuild custom or Docker images yourself. Laravel

  3. PHP's advisories credit the reporters as lcfr-hax, sagitzadik-wiz, tomash-areion and amyb-oai (GitHub handles). Fixes by arnaud-lb, iluuu1994, bukka and ndossche. GHSA

  4. Plesk users: patched PHP packages aren't out yet (as of Plesk's 12:51 UTC update). Plesk will rebuild its PHP 7.4 through 8.5 packages now that upstream has shipped, with no date given. Hotfixes for Plesk's own sw-engine are planned as 18.0.80#11 and 18.0.81#4. Plesk

  5. Fix is out, about 25 minutes early: PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35. PHP: there's no complete mitigation, update now. php.net

  6. The bugs: CVE-2026-109618 is OOM handling via longjmp() leaving request memory half-initialized. CVE-2026-109619 is global state that outlives its memory and gets used by the next request on the same worker. RCE confirmed on mod_php before any app code runs; 109619 also validated on FPM. GHSA-w8hw · GHSA-6wmf

  7. On 8.1 or older? PHP published minimal source backports for 7.4, 8.0 and 8.1.

  8. Correction: Aikido said memory_limit=-1 doesn't help. PHP's advisory lists it, enforced with php_admin_value, as the main stopgap for CVE-2026-109618. Still partial. Don't use RLIMIT_AS/RLIMIT_DATA; they trigger the bug. php.net

  9. Sophos: someone on X says they have a working PoC for both CVEs. No confirmed in-the-wild exploitation, per Sophos. Sophos

  10. More precautionary takedowns: Finnish government sites, several European universities, 4chan. Telegraph

  11. CERT-EU and the UK NCSC: patch as soon as fixes ship. If you can't patch right away, take internet-facing PHP offline. CERT-EU

  12. One report calls CVE-2026-109618 a use-after-free. PHP hasn't confirmed the root cause. SecurityWeek

  13. Exploitation reports, but no agreement. Patchstack says several hosting partners reported active exploitation from 07:34 UTC. Aikido says it's in the wild. Australia's ACSC, in a critical alert today, says it's not aware of any. Patchstack · ACSC

  14. Aikido: neither session.upload_progress.enabled=0 nor memory_limit=-1 protects you, and no complete WAF rule exists yet. After patching, check for compromise going back to June 2026. Aikido

  15. More precautionary takedowns: Dutch DigiD and MijnOverheid, Wikimedia's Phabricator, the GrapheneOS forum, The SEO Framework. Wikipedia · The Verge

  16. WordPress sites: Wordfence says this fix won't arrive through WordPress auto-updates. PHP is a server package, so find out who patches yours (host, sysadmin, or you). The Verge

  17. Dozens of “php2shell PoC” repos on GitHub since midnight. Validity unknown. Don't run them on anything you care about.

  18. Precautionary takedowns in NL: Tweakers, Tweede Kamer, NCSC, Security.NL all offline. Sansec

  19. On Remi's repo (RHEL/Fedora)? No update today, per the PHP Foundation. Switch to distro packages or build from source now.

  20. Cloudflare reports early attacks and has pushed WAF rules to every plan, free included. Only helps if your origin rejects non-Cloudflare IPs.

  21. GMO Flatt Security: exploit code claiming to work is circulating. Disabling session.upload_progress mitigates but does not stop it. Flatt (JA)

  22. PHP core dev Gina Peter Banyard: patching is the only mitigation. If you can afford it, take PHP offline for the day.

  23. PHP security team: two criticals, CVSS v4 9.2, release Wed 14:00 UTC, earlier if details leak or exploitation appears. php.net

  24. HN post says two PHP RCEs drop Thursday. Pulled fast; screenshots spread. watchTowr confirms the leak is real.

Mitigate now

Stopgaps until you can patch. None of these is a fix. Remove them after you update PHP.

1. Block multipart at the web server

PHP parses multipart bodies before your code runs, so app-level fixes and maintenance modes don't help. Reject them in front of PHP.

nginx: every server block that passes to PHP, then nginx -t && systemctl reload nginx

if ($http_content_type ~* "multipart/form-data") {
    return 403;
}

Apache: every <VirtualHost> serving PHP, then reload

RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteRule ^ - [F]

Breaks every file upload, plus any form sent as multipart (some carts and checkouts). Place a test order. Allowlist only upload routes you can't live without.

2. Or go read-only, or offline

Can you go a day without PHP? Stop php-fpm and serve a static page. That's the safest move. Otherwise allow only GET and HEAD:

if ($request_method !~ ^(GET|HEAD)$) {
    return 503;
}

3. Put it behind Cloudflare

Cloudflare's managed WAF rules cover the known exploits on every plan. They do nothing if attackers can reach your origin directly. Firewall HTTP/HTTPS to Cloudflare's IP ranges.

4. Harden PHP settings

These reduce exposure but do not prevent the attack. Use them in addition to the steps above, never instead of them.

session.upload_progress.enabled = 0
session.use_strict_mode = 1

php-fpm ignores the CLI php.ini. Set it per pool, then reload php8.x-fpm:

; e.g. /etc/php/8.3/fpm/pool.d/www.conf, every pool
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[session.use_strict_mode] = on

5. Verify from outside

# expect 403 (or 503 if read-only)
curl -s -o /dev/null -w '%{http_code}\n' -F probe=1 https://example.com/

# expect 200 still
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/

Check the web SAPI, not php -i. Drop this in, load it, delete it:

<?php echo ini_get('session.upload_progress.enabled') ? 'ON' : 'off';

6. Get ready to patch

Watch for compromise

Send in your updates

Seen a release, an exploit in the wild, or a mitigation that works (or breaks)? Tell us. Links help. We post what we can confirm.

Send a tip

Sources