On 21 October, PHP’s security team shipped emergency fixes for two critical remote code execution flaws, nicknamed “php2shell,” after details leaked on Hacker News ahead of the planned disclosure. Patched releases are out now: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Both flaws, CVE-2026-109618 and CVE-2026-109619, carry a CVSS v4.0 score of 9.2.
If you run PHP anywhere in your stack, the instruction is simple: patch now. What’s worth fifteen minutes of your time is being precise about what else does and doesn’t help here, because it isn’t what you might assume if you work on the header and policy side of web security.
What’s actually broken
PHP’s own changelog describes the fix as avoiding “state corruption via bailout.” In practice, that means memory exhaustion can interrupt PHP mid-request, leaving request data only partly initialised, and that state can then be mishandled during cleanup. A related issue lets internal state from one request outlive the memory it points to, so a later request handled by the same long-running worker can end up using stale, corrupted state. Neither bug is confined to file uploads or any single feature; both sit in PHP’s general request handling, which is why every major deployment model, PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed, is affected, with mod_php carrying the greatest risk.
An earlier leaked theory pointed specifically at the multipart/form-data parser and the session.upload_progress feature. That theory drove a lot of the early mitigation advice circulating this week, but it isn’t what the official fix addresses, so treat any guidance built solely around blocking multipart uploads as incomplete.
The reason this is so severe either way: PHP parses incoming requests before your application code, your framework’s middleware, or your WAF rules get a look at them. An attacker who successfully exploits this gets to run arbitrary code on your server directly, with whatever privileges your PHP process has. That typically includes your database credentials. It can mean a full data dump with no application-layer step in between.
Exploitation status is genuinely unsettled at the time of writing. Some researchers report no confirmed in-the-wild exploitation yet; others, citing Cloudflare, say exploitation attempts began shortly after the patch was released, which is roughly what security researchers had predicted given how quickly a patch diff can be reverse-engineered into a working exploit. Treat this as live and assume attempts are either underway or imminent.
What doesn’t help here
A strict Content-Security-Policy, HSTS, X-Frame-Options, Permissions-Policy: none of these touch this vulnerability. They’re enforced by the browser, on content the server sends back after a request has already been processed. This exploit happens upstream of all of that, inside PHP’s own request handling. There’s no response for a header to govern, and no script execution in a browser for CSP to restrict. If your PHP process has database access, the database is exposed, full stop, regardless of how well-configured your headers are.
If you haven’t patched yet, the controls that actually matter in the interim are restricting your PHP process’s database credentials to the minimum it needs, watching your egress traffic for anything unusual in case an attacker already got in, and applying any WAF rules your provider has published for known exploit patterns, understanding that these are a stopgap rather than a fix. The only confirmed remedy is the patch itself.
Where headers do come back into it
There’s a second-order scenario worth planning for. If an attacker uses this RCE not to dump data quietly but to modify the pages your server serves, injecting a skimmer, a crypto-drainer, or a malicious third-party script into your front end, that’s a content-injection problem happening downstream of the breach, and that’s exactly where your CSP, Subresource Integrity, and script-src policy earn their keep. They won’t stop the initial compromise. They can stop a compromised backend turning into a mass client-side attack on every visitor who loads your site afterwards.
That distinction matters: headers protect your visitors’ browsers from what your server serves them. They don’t protect your server, and they don’t protect your database. Knowing which layer each control actually covers is the difference between a false sense of security and a genuinely resilient setup.
What to do this week
Patch every PHP branch you run now, including anything bundled inside vendor software, and restart your PHP-FPM workers or long-running processes afterwards, since the old code stays loaded until you do. If you’re on an end-of-life branch (7.4, 8.0 or 8.1), check whether your distribution or hosting provider has issued a backport; PHP itself released minimal backports for those branches given the severity, though moving onto a supported version remains the better long-term fix. After patching, check your logs for anything unusual going back to around 15:00 UTC on 20 October, when the leak first circulated, and review your database credentials for least privilege, since that’s what limits the damage from a server-side flaw like this one regardless of how fast you patch.
Sources: Help Net Security, PHP ChangeLog, TheHackerNews