If your website runs PHP, check its version today. Two critical vulnerabilities in PHP itself, nicknamed PHP2Shell, were patched on October 21, 2026, and exploitation attempts have already been observed. The short version: update to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, depending on your branch. Anything older in those branches is exposed, and PHP 8.1 and older receive no fix at all from the PHP project. Both flaws let an unauthenticated attacker run code on your server, and both are rated CVSS v4.0 9.2 by the PHP security team, according to the official advisory on PHP.net. The longer version, including how the flaws work, who is most at risk, how to check your exposure, and what to do if you cannot patch today, is below.
Key Takeaways
PHP2Shell is the pair CVE-2026-109618 and CVE-2026-109619, two unauthenticated remote code execution flaws in PHP, both rated CVSS v4.0 9.2.
Fixed releases shipped on October 21, 2026: PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and older get no release.
Every web-facing PHP setup is in scope, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The risk is highest for mod_php.
OpenAI published a free checker that reads your PHP version and flags exposure, but an UNKNOWN result does not mean you are patched.
There is no complete configuration workaround. Updating is the only safe fix, per the PHP security team.
Attempts have been seen since October 17, but as of October 22 no confirmed successful exploitation has been reported, and public exploits need specific conditions. Patch fast, but do not panic.
What Is PHP2Shell?
PHP is the server-side language behind a huge share of the web: Tenable, citing W3Techs, puts it at 69.3% of websites whose server-side programming language is known. The two flaws were found in August 2026 by researchers from Calif, Wiz Research, and OpenAI working under the Patch the Planet initiative, as JFrog and Sansec report. Coordinated disclosure was planned for October 22. On October 20, details leaked early: a social media post and screenshots of a private exploit tool named PHP2Shell circulated online, and watchTowr was the first to publicly confirm the leak was genuine. The PHP security team published an advance notice that evening and shipped the fixed releases on October 21, a day ahead of the original schedule. One detail worth knowing: the leaked posts claimed a CVSS score of 10.0. The official score from the PHP security team is 9.2, as Check Point confirms.
The Two Flaws, in Plain English
CVE-2026-109618: RCE via out-of-memory corruption
In the words of PHP.net, "out-of-memory handling can interrupt PHP while internal request data is only partially initialized. Request cleanup may then treat the invalid data as valid." The GitHub advisory explains the mechanism: PHP uses longjmp() to bail out of out-of-memory errors, so if an attacker can force a memory shortage at the wrong moment, the shutdown code runs on half-built request data and can be steered into executing code. Forcing that shortage is cheaper than it sounds. The advisory lists attacker-reachable tricks such as multipart requests without a usable declared Content-Length that slip past the first post_max_size check.
CVE-2026-109619: RCE via stale global state
The second flaw is a use-after-free. Per PHP.net, "request-owned internal state can survive after its backing memory has been freed. A later request handled by the same worker may use that stale state before normal initialization resets it." The GitHub advisory confirms two attack paths. The first abuses the session upload progress feature, which is enabled by default and works even if your application never calls session_start(). The second, on PHP 8.5, abuses fatal error backtraces. Confirmed impact is unauthenticated remote code execution with the web worker's privileges, plus memory disclosure: freed worker memory can leak data from other requests, as Sansec describes in the upload progress handler.
Both flaws need the attacker's requests to be handled by the same worker process for some paths, which is why busy multi-worker servers are harder to hit per request. That lowers the odds. It does not remove the bug.
Who Is at Risk?
The official answer is broad. PHP.net states: "all PHP installations serving web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. We consider the risk highest for mod_php, with a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs."
That last point is what makes mod_php special here. Per the advisory for CVE-2026-109618, complete remote code execution was validated over HTTP against mod_php with default limits, because mod_php runs the request shutdown procedure even when request startup has failed. The attack happens before any of your application code executes, so application-level defenses never get a chance. For PHP-FPM, the same advisory says source analysis supports FPM as susceptible for the OOM flaw, though no complete FPM exploit has been demonstrated for it. For CVE-2026-109619, the session lifecycle path was validated against both mod_php and FPM, according to its advisory.
Affected and Fixed Versions
The hard facts come from the release announcements on PHP.net, all dated October 21, 2026:
Branch | Status | What to do |
|---|---|---|
PHP 8.5.x | Vulnerable before 8.5.12 | Update to 8.5.12 |
PHP 8.4.x | Vulnerable before 8.4.27 | Update to 8.4.27 |
PHP 8.3.x | Vulnerable before 8.3.36 | Update to 8.3.36 |
PHP 8.2.x | Vulnerable before 8.2.35 | Update to 8.2.35 |
PHP 8.1 and older | No fixed release from the PHP project | Use vendor LTS packages or PHP's source backports, and plan migration |
PHP 5.4 to 7.3 | End of life, no fix | Migrate to a supported branch |
Three caveats matter here:
Distro packages can differ. Linux distributions received the patches in advance and often backport fixes into older version numbers. A server reporting PHP 8.3.20 might already be patched by its distribution. Check your vendor's security advisory, not just the version string, as PHP.net advises.
Old branches got a lifeline, not a release. Because of the severity, the PHP security team published minimal source backports for PHP 7.4, 8.0, and 8.1 for people who build from source or have no LTS vendor. Long-term-support vendors such as Ubuntu and TuxCare also shipped backported packages, per Sansec.
The clock is ticking on 8.2. PHP 8.2 reaches end of life on December 31, 2026, and receives no security fixes after that date, per the 8.2.35 release note on PHP.net.
How far back does the vulnerable code go? The PHP advisory does not print an affected range, but researchers attribute the vulnerable code to PHP 5.4.0, released in 2012, as Tenable reports from Calif's writeup. Treat every unpatched PHP from the last decade as in scope until your vendor says otherwise.
How to Check Your PHP Version
Start on the server itself. Run `php -v` and compare against the fixed versions above. One warning: the command-line PHP version can differ from the version actually serving your site under FPM or mod_php, so check the runtime your web server uses, not just the CLI.
For a quick outside view, OpenAI published php2shell-checker on GitHub under the Apache-2.0 license. It is a small Node.js tool, also packaged as Codex skills, that reads the PHP version from a site's HTTP response headers (or from `php -v` with the `--local` flag) and compares it with per-branch cutoffs:
``` node phpcheck.js "https://example.com" node phpcheck.js --local ```
It answers OK, VULNERABLE, or UNKNOWN. Respect its limits, which the README states plainly: it only evaluates the version it can see, a site that hides its version headers returns UNKNOWN, and distribution backports can make a patched server look vulnerable because the version number does not change. In the project's own bold warning: UNKNOWN does not mean the target is patched.
Patch First: How to Update
Back up and preserve logs first if you have seen suspicious traffic. One of the flaws lives in worker memory, so restarting workers destroys evidence. watchTowr advises preserving PHP and web server logs, configuration snapshots, and suspicious files before making changes.
Install the fixed release for your branch from PHP.net, or update your distribution packages if your vendor shipped a backport. On shared or managed hosting, check your host's advisory and ask them directly if their PHP builds are patched.
Restart every PHP worker (FPM pools, Apache, your container images) so the new code is what actually serves requests.
Re-check with `php -v` on the web runtime and the OpenAI checker from outside.
If You Cannot Patch Today
The PHP security team's position is blunt: there are no complete mitigations, and updating is the only safe choice. The measures below, from the official advisory and the two GitHub advisories, reduce exposure to specific attack paths. None of them makes an unpatched server safe.
Turn off session upload progress. Set `session.upload_progress.enabled=0` in php.ini or the FPM pool config and restart every worker. This blocks the confirmed session paths of CVE-2026-109619, but not other variants.
On PHP 8.5, disable fatal error backtraces. Set `fatal_error_backtraces=0` and restart workers. This blocks the confirmed backtrace path only.
Set memory_limit to -1, enforced administratively (for example with php_admin_value) so applications cannot override it. This narrows the OOM path of CVE-2026-109618, but PHP warns it is incomplete and removes PHP's own protection against resource exhaustion. Do not use RLIMIT_AS or RLIMIT_DATA instead: those cause the allocation failures that trigger the vulnerable path.
Lower post_max_size. PHP suggests 8M for applications that do not need file uploads and 32M where uploads are necessary, with upload_max_filesize kept below it.
Block multipart requests at the proxy if your application does not use multipart form data. The community toolkit php2shell-protection by Syhunt does this for Apache, and its README is explicit that it is "NOT a complete mitigation for either CVE". Blocking multipart also breaks every file upload on covered routes.
As a last resort, isolate. CISA and CERT-EU guidance, relayed by Tenable, is to consider taking internet-facing PHP systems offline or isolating them until they are patched.
Was Anyone Actually Exploited?
Attempts, yes. Confirmed breaches, not so far, and the distinction matters. Tenable reports that Amazon Threat Intelligence observed a PHP2Shell exploitation attempt against its MadPot honeypot network on October 17, four days before public disclosure, and recommends starting investigations from that date. Cloudflare reported early attack attempts on October 21 and pushed WAF rules to all customers, including the free tier. watchTowr confirms exploitation was observed in its global honeypot network as of October 21, while also saying no attempt had succeeded at the time. The PHP Foundation inspected the proof-of-concept code that appeared after the leak and found no functional exploit at release time, and CISA said it had not observed exploitation as of its advisory.
On October 22, Sansec updated its assessment downward: mass exploitation is less likely than expected on release day, an attack needs specific knowledge of the target server and specific conditions on it, the public exploits do not work against a default PHP installation, and most public proof-of-concept code needs the target application to already have a local file inclusion bug. In plain terms: the window to patch is real, but it will not stay open forever. Use it.
How to Hunt for Signs of Attack
Whether you patch today or next week, spend twenty minutes checking for the indicators below, compiled from the GitHub advisory logging guidance, Check Point, and watchTowr. Treat single hits as triage, not proof. Correlation is what matters.
Multipart POST requests carrying a PHP_SESSION_UPLOAD_PROGRESS field, or large and malformed multipart requests to endpoints that never accept uploads
Repeated "Allowed memory size exhausted" fatal errors and request timeouts in PHP logs, which the OOM flaw leaves behind
PHP-FPM or Apache worker segfaults, or bursts of worker crashes and respawns
New or modified .php files under web roots, especially in upload, cache, or temp folders, and unexpected files in the session save path
Changes to auto_prepend_file or auto_append_file in any php.ini
Web server processes spawning sh, bash, curl, wget, or nc, plus new cron jobs, systemd units, user accounts, or authorized_keys entries
Check Point advises repeating these checks right after patching and again at 24 and 72 hours. For network-level detection, Corelight published open-source Zeek and Suricata rules in its php2shell-detect repository, built with OpenAI and the PHP team before disclosure, as ASEC notes.
Beware Fake Exploit Repositories
Within a day of disclosure, GitHub filled with repositories named php2shell. ASEC counted the top 100 search results on October 22: 99 addressed these vulnerabilities, nearly all were created on October 21 alone, and they split into 46 defensive and 36 offensive projects. Not all of them are honest. JFrog investigated fake proof-of-concept repos and found pranks rather than confirmed malware: one fake hid a Base64 string that looks like a malware dropper but actually changes the victim's wallpaper to NSFW content. ASEC separately spotted a clone of a popular proof-of-concept repository with modified code, and warns that even defensive one-line tools may demand root privileges, with at least one admitting it was written by AI with no guarantees.
The safe habits are simple. Never run exploit or checker code you have not read yourself. Run any test code only in an isolated environment. For checking exposure, the version number is the check, and the official OpenAI checker and the downloads on PHP.net are the sources to trust.
Frequently Asked Questions
Is my WordPress site affected? The flaw is in PHP itself, not in WordPress or any single application. Your exposure depends on the PHP version your host runs and how it is set up. Update PHP first (or confirm your host has), then update the application as usual.
The checker says UNKNOWN. Am I safe? No. UNKNOWN means no version could be detected, usually because the server hides its headers. The checker project warns explicitly that UNKNOWN does not mean patched. Check the version on the server itself.
I run PHP 7.4, 8.0, or 8.1. What are my options? There is no official fixed release for these branches. Your options are a long-term-support vendor package with the backported fix, PHP's own minimal source backports for 7.4, 8.0, and 8.1, or migrating to a supported branch. Treat migration as the real answer and the backports as a bridge.
Is turning off session upload progress enough? No. It blocks the confirmed session paths of one of the two flaws. The PHP advisories state there is no complete generic configuration mitigation. Only the update covers both flaws.
Were any real sites hacked? As of October 22, 2026, exploitation attempts have been observed since October 17, but watchTowr, CISA, and the PHP Foundation have all reported no confirmed successful exploitation. That status can change, which is exactly why patching now matters.
The Bottom Line
PHP2Shell is as serious as a PHP vulnerability gets: unauthenticated remote code execution in the language layer itself, rated 9.2, with attack attempts already in the wild. It is also unusually well handled: coordinated fixes for every supported branch, an official checker, open detections, and honest vendor communication about what is and is not confirmed. Your move is simple. Check your version, update to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, restart your workers, and spend twenty minutes hunting through your logs.
Want more open source security tools and projects worth your time? Browse the latest repo signals on RepoManiac, where new GitHub projects are vetted and summarized in 30-second videos. Reading this in Indonesian? Here is the Indonesian version of this article.
