PHP is the engine that runs many websites’ application code. Updating a WordPress plugin changes part of the application; updating PHP changes the machinery underneath it. PHP2Shell concerns that machinery: two memory failures in PHP itself, with different routes to dangerous behavior.
The reported consequences include remote code execution—running attacker-chosen code without signing in—and exposure of sensitive process memory, which Wiz says can include passwords, tokens and API keys. Code execution has the web worker’s privileges; it does not automatically grant full administrator access to the machine. Research overview.
If you operate PHP, act before reading on. PHP’s October 21 security release fixes both issues. Install the appropriate fixed release or a vendor package with both fixes, then restart the affected services and workers. An application update alone is insufficient. Attack attempts are already being reported. PHP’s official announcement.
| PHP branch | First fixed upstream release |
|---|---|
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |
PHP also supplied minimal emergency source backports for 7.4, 8.0 and 8.1. These do not restore normal support for those branches. Older installations need a verified vendor backport, a correctly applied source fix, or an upgrade to a supported branch. Release and backport guidance.
Distribution packages often keep an older upstream number. Ubuntu 24.04’s fixed package, for example, is 8.3.6-0ubuntu0.24.04.13: the fix is backported, so “8.3.6” alone does not mean vulnerable. Check your distributor’s advisory, not just the version string. Ubuntu’s fixed packages.
Status on October 22
Checked October 22, 2026, 15:30 UTC. These reports change quickly; each is attributed to the party that made it.
- Attempts began before disclosure. Amazon Threat Intelligence recorded an exploitation attempt against its honeypots on October 17, four days before the release, and says it is unclear how the actor obtained exploit information. Further attempts followed in the hours before release; Amazon says it is unclear whether those would have succeeded against real systems. After release, it described PHP2Shell as “now being broadly exploited in the wild.” Amazon’s report.
- Volume is high; working exploits are less clear. Cloudflare says its WAF customers were protected by default from October 21, 03:02 UTC, and it observed attackers changing payloads to evade those rules. Cloudflare. watchTowr told SecurityWeek that the exploits being sprayed “either don’t work at all, test for timing-based differences, or crash the target.” SecurityWeek.
- No public confirmation of a successful compromise in the sources we checked. The PHP Foundation said its team found no functional exploit among the proofs of concept circulating at release. CISA had not observed exploitation when it issued its alert, and neither CVE was in its Known Exploited Vulnerabilities catalog (version 2026.10.21) when we checked it directly. Foundation; CISA alert.
- Fake exploits are circulating. JFrog reported fake proof-of-concept repositories and prank malware on GitHub, according to SecurityWeek. Do not run a downloaded exploit to “test” your server.
Failed attempts are not reassurance. Exploit quality usually improves after a release, and the attempts show that someone is already looking for vulnerable servers.
Internet-wide counts based on version banners need care. Censys reported about 1.57 million of roughly 1.58 million hosts with an identifiable PHP version as unpatched on October 21, per SecurityWeek. A banner cannot see distribution backports, and many servers hide the version entirely. The counts indicate scale, not a precise number of vulnerable sites.
Two failures, in plain English
Transcript of the 70-second explainer
Updating plugins doesn’t patch PHP, the engine underneath your site. These two PHP bugs can let attackers run code.
Memory is a workspace. A reference points to a place inside it. Normally, setup finishes before cleanup reads the data. Here, memory allocation failed. Setup stopped, but cleanup followed the reference into unfinished data.
The other bug crossed requests. One web request ended and its memory was freed. The worker kept an old reference. A later request on that same worker used it before reset.
A useful comparison: finish the data before exposing a reference. That’s a review idea, not PHP’s actual patch.
AI helped researchers investigate. PHP’s maintainers engineered and reviewed the fixes.
Update the PHP actually serving your site. Verify both fixes in its package, and restart its workers. Your terminal’s PHP may be different.
End card (no narration): Attack attempts began before the patch. Full guide, checks and sources: aihackers.net/php2shell.
A running PHP process called a worker handles a web request: one exchange between a browser and the server. The same worker can handle another request afterward.
Picture a desk and an index. Memory is the desk’s temporary workspace; an internal reference is an address pointing to data there. Here, “reference” means that internal link, not PHP’s language-level & feature. Initialization fills in a new structure so it is ready to use; freeing releases its memory for reuse.
The basic rule is that a routine following a reference must find valid state: data that is initialized and still belongs to that use. PHP2Shell breaks that rule in two ways.
1. Cleanup encounters unfinished data
During setup, some internal data became reachable before initialization finished. An out-of-memory failure could interrupt the operation, leaving cleanup to follow a reference into unfinished data. In desk terms, the index already points to a file, but the clerk has only half assembled it. Cleanup mistakes it for a finished file. This happens within one request.
2. A later request follows an obsolete reference
Request A’s memory is freed, but an old reference remains in the worker. An early routine in Request B on the same worker follows that reference before normal setup resets it. The workspace has been released for reuse: the old reference no longer identifies valid data. This is stale state—like keeping an index entry after discarding its file.
Inside the two fixes
Both advisories rate the issues 9.2 under CVSS 4.0. The score describes severity; it is not a measure of how many sites were exploited. Ratings differ by context: Red Hat rates both CVEs “Important” (CVSS 3 score 8.1) for its products, citing the precise out-of-memory condition and heap manipulation exploitation needs, and noting that standard RHEL deployments use PHP-FPM rather than mod_php. That is an assessment of one configuration, not a reason to wait. Red Hat on CVE-2026-109618; on CVE-2026-109619.
CVE-2026-109618: interrupted initialization
Technically, CVE-2026-109618 involves PHP’s out-of-memory handling. An allocation failure could invoke longjmp(), abruptly leaving the current operation. Some request data was already reachable but not fully initialized. Shutdown could then use that invalid state. Even an allocation unrelated to the unfinished structure could trigger the interruption.
Calif’s write-up gives a concrete instance: PHP’s hash-table insertion incremented its element counts before fully initializing the new entry, so an interruption at that moment left cleanup counting an entry that was never finished. Calif’s research account.
The fix changes the failure behavior: a soft out-of-memory condition is handled at the next safe point in the virtual machine; a higher hard limit terminates the process with _exit(). This prevents ordinary shutdown from walking through the inconsistent state.
The advisory documents remote code execution against Apache’s mod_php (PHP running inside the Apache web server), including before application code starts. PHP-FPM runs a separate pool of PHP workers and exits the child when request startup fails. The advisory’s FPM assessment is narrower: source analysis supports susceptibility, but it reports no complete FPM exploit. OOM advisory.
CVE-2026-109619: state survives its memory
In CVE-2026-109619, a worker retained references to request-owned memory after that memory was freed. A later request on the same worker could use the stale state before normal initialization reset it: a use-after-free.
How can a reference survive? A fatal error, including memory exhaustion, could interrupt the expected reset. A late, nonfatal warning could write a reference back into error state after cleanup had cleared it. The defect needs both a producer that leaves stale state and a later consumer that acts on it. The advisory confirms two consumers that run before normal initialization:
- Session upload progress, which runs before normal session initialization. It is enabled by default and needs no
session_start()call in the application. - INI diagnostics raised while applying per-request settings, such as
.htaccessorphp_valuedirectives on mod_php, orPHP_VALUEparameters a frontend passes to FPM.
On the producer side, fatal error backtraces on PHP 8.5 store request-owned state that shutdown never resets; that path is the confirmed code-execution case on mod_php.
The fix resets the wider affected state. This advisory confirms mod_php exploitation and a session-lifecycle route that works with a normal dynamic FPM pool, depending on a suitable application operation. Stale-state advisory.
OOM/FPM source discrepancy: the dedicated OOM advisory reports susceptibility from source analysis without a complete FPM exploit; the Foundation’s retrospective reports application-path FPM code execution under its OOM summary. We preserve this unresolved difference. Neither account establishes FPM immunity or uniform exploitation across deployments. Foundation retrospective.
If you can’t update today
PHP lists interim settings that “reduce exposure to specific attack paths but do not make an installation safe.” Only an update is a complete solution. CISA goes further: systems that cannot be updated immediately, and anything on PHP 8.1 or older, should be taken offline until patched. PHP’s mitigations; CISA alert.
If a short delay is unavoidable, the main settings from PHP and its advisories are:
| Setting | Reduces | Tradeoff or limit |
|---|---|---|
session.upload_progress.enabled = 0 | The confirmed session upload-progress route (CVE-2026-109619) | Breaks upload progress bars if the site uses them. Recommended even after patching when unused. |
fatal_error_backtraces = 0 (8.5 only) | The producer in the confirmed fatal-backtrace exploit | Does not cover other request-owned state. Less diagnostic detail in fatal errors. |
memory_limit = -1, enforced so applications can’t restore a limit | The controllable out-of-memory trigger (CVE-2026-109618) | Not complete: other allocation failures can still hit the old path. Memory exhaustion moves to the operating system and can kill workers. A container or cgroup limit can kill every worker at once unless each has its own group; PHP warns not to use RLIMIT_AS or RLIMIT_DATA. Revisit after updating. |
Conservative post_max_size (8M, or 32M with uploads) | Large request bodies used to exhaust memory | Not a reliable ceiling: a multipart request without a usable Content-Length can pass the check. Enforce the decoded body size and input-complexity limits at the frontend too; a declared-length or compressed-size limit alone is not enough. |
Apply these where they take effect before request parsing—php.ini, php_admin_value in the FPM pool, or server configuration—then confirm no pool, directory or application setting overrides them, and restart every worker. ini_set() and FPM .user.ini files do not work for this. Hiding errors with display_errors, error_reporting or @ does not help.
The settings do not cover every path. PHP also advises removing invalid or deprecated per-request settings that emit warnings before initialization, fixing attacker-reachable fatal errors and timeouts, and eliminating diagnostics emitted late in cleanup. The stale-state advisory adds pm.max_requests=1 on FPM if performance allows. Stale-state advisory; OOM advisory.
A WAF is a further layer, not evidence that the engine is fixed. Cloudflare’s rules apply automatically on the Free plan; on paid plans, Cloudflare asks customers to confirm the Managed Ruleset is deployed in block mode. Cloudflare.
After you update: known regressions
The fixes change deep engine behavior, and users have reported regressions in the first two days. As of our October 22 check of the php-src issue tracker:
- SimpleXML heap corruption (8.4.27, 8.5.12): a garbage-collection double free that can produce
zend_mm_heap corrupted, reproduced by several users. The issue was marked completed on October 22 with a referenced fix; no PHP release after 8.4.27 or 8.5.12 had been tagged when we checked. Issue #24488. - Hard memory limit exits (open report): some allocations that previously raised a catchable “Allowed memory size exhausted” error now end the process with exit code 137 at the new hard limit, reported as twice
memory_limitby default. Exit 137 here is PHP’s own_exit(), not necessarily the kernel’s out-of-memory killer. Hard-limit termination skips shutdown handlers, and in threaded deployments it can interrupt other requests in the same process. Issue #24492; Wiz. - Sessions deleted during uploads on 8.5.12 and 8.4.27 (open report): an upload-progress request can delete an entire stored session when a stored object has one of three reserved property names, even in a session PHP’s own serializer wrote. Issue #24493.
Do not roll back to a vulnerable release. If you hit one of these, track the issue, use a workaround only if maintainers document one, and install a release or vendor package that explicitly lists the regression fix. Test cleanup behavior and availability after upgrading, not just the version number.
Check for compromise
Updating every runtime and restarting its workers closes these vulnerabilities; it does not detect or remove an existing compromise. Amazon recommends starting investigations from October 17, not from the disclosure date. Its suggested checks:
- Review web server logs from October 17 for suspicious requests, including multipart POST requests containing
PHP_SESSION_UPLOAD_PROGRESS. Sites that legitimately use upload progress send this field too, so treat a match as a lead, not proof. - Look for unexpected process execution or file changes on web servers. CISA specifically flags PHP worker processes launching shells or downloading tools.
- Consider blocking multipart file uploads where the application allows it while you remain unpatched, after testing the effect.
Wiz cautions that these signals guide an investigation but do not establish exploitation, and their absence does not prove a system is unaffected. Memory disclosure can happen without running attacker code, and application logs may show little because the vulnerable paths run below the application. Wiz.
Our recommendation: if you establish or credibly suspect exploitation, assume the secrets that PHP process held—database passwords, API keys, session and signing keys—may be exposed. Rotate them and invalidate active sessions, rather than only replacing the binary.
What the AI contribution actually establishes
OpenAI attributes Calif’s discovery of a critical flaw to work using GPT-5.6 Sol through its Patch the Planet initiative. It also credits Wiz with independently discovering and reporting both vulnerabilities, and says PHP’s maintainers led the fixes and release. The same post announces subsidized access to OpenAI’s Daybreak security program, so it is both a coordination account and a product announcement. OpenAI’s coordination account.
Wiz’s account names Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol across discovery, exploit development and patch validation, and singles out Gemini 4’s contribution to exploit development and patch validation. Those reported roles establish no model ranking. Research overview.
Calif researcher Ryan Austin describes starting with PHP’s vulnerability history: he remembered a 2004 memory-limit bug and looked for “long-lost siblings.” He directed an agent toward allocation, fatal-error handling and shutdown, and it identified the hash-table ordering problem above. Calif then had the model generalize the finding into a SKILL.md review pattern, which surfaced the session upload-progress variant. His write-up does not name the model, and it is blunt about limits: “No model is simply capable of unearthing ‘all bugs’ with simple prompts.” Left to default variant analysis, he notes, models start from the newest, most prominent bugs and nearby code; they do not reliably reach obscure twenty-year-old exploitation primitives unless the researcher points them there. Calif’s research account.
The defenders’ side used AI too. PHP’s security team says AI helps it validate reports and sort a growing queue, but “the models don’t make the calls”: a person sets severity and writes or reviews every patch. How PHP handles reports.
Amazon draws the uncomfortable corollary. AI-assisted analysis makes it cheaper to turn a patch or advisory into a working exploit, so the window between disclosure and attack is shrinking: “more actors can act within hours or even minutes.” That is a general argument; none of the reports we checked establishes whether AI contributed to the attempts seen against PHP2Shell. Still, if capable models help defenders find bugs early, operators should expect less time between a fix and the first attack. Amazon’s report.
The useful pattern to take into ordinary engineering is expert hypothesis → agent investigation → evidence → reusable review pattern → human patch and review. A finding needs code locations, reachable behavior and enough evidence for someone else to challenge it.
For an authorized review of your own code, a bounded question might be: Can a failure leave state visible to code that assumes the operation finished? Ask the agent to trace the state change, the work that can fail, the initialization or reset that gets skipped, and the surviving reader. Require it to explain why the reader is reachable.
Then look for reasons the suspected bug is harmless: initialization finishes before any reference exposes the data; rollback restores the state before a reader sees it; the helper cannot fail in this context; or no relevant state or reader survives. The companion diagram shows one such control: initialize first, expose the reference afterward. Suspicious ordering alone does not establish a vulnerability.
Our downloadable review aid adapts this reasoning into a checklist. It is untested AIHackers guidance, not Calif’s original skill, a vulnerability detector, or a reproduced exploit. It requires a reachable failure path and consumer, plus evidence that rules out those controls.
Finding the flaw was only part of fixing it
A PHP core developer recognized the OOM concern during a 2024 Quarkslab audit follow-up. Fixes stalled over compatibility, performance, denial-of-service and extension tradeoffs, limited staffing and difficulty reaching agreement; the Foundation calls it “a structural failure.” It says August 11 reports from Calif and OpenAI, followed by further vectors and Wiz’s August 24 report, established the impact and made fixing it the priority. Maintainers, release managers and downstream package maintainers delivered the updates. Foundation retrospective.
The disclosure itself was disrupted. These are coordination events, separate from the two bug mechanisms:
| Time (UTC, 2026) | Reported event |
|---|---|
| October 17 | Amazon records a first exploitation attempt against its honeypots. |
| October 20, around 15:00 | CVE IDs circulate online with a wrong release time and a 10.0 score. |
| October 20, 19:30 | PHP pre-announces the release and brings it forward from October 22 to October 21. |
| October 20, around 20:00 | Calif mistakenly publishes a proof-of-concept video. |
| October 21, 03:02 | Cloudflare’s WAF protection is on by default for its customers. |
| October 21, 07:41 | Chainguard publishes fixed images before coordinated disclosure. |
| October 21, 14:00 | Coordinated release. |
Sources: Foundation, Amazon, Cloudflare. The concern with early fixed images was public clues appearing while other users still awaited updates, not early patching itself. This chronology establishes no compromise count.
Evidence can change priorities; people must still choose among imperfect fixes. The Foundation says it is moving the security team toward majority decisions and asking companies, hosts, distributions and governments for sustained funding.
Verify the system that serves the site
On managed hosting: ask the provider which package fixes both CVEs and whether every serving worker has been restarted onto it.
A useful completion record should identify the actual serving runtime and the package that fixed it. Treat the following as an operational checklist, not an exploitation test:
- Map the serving path. Identify the PHP service, container or hosting configuration used by each site. The shell command
php -vchecks the command-line installation, which may differ from the PHP service or container serving your website. - Verify the package evidence. Compare an upstream release with the table, or obtain the distributor’s advisory showing that its package contains both fixes. On Ubuntu,
apt list '?installed ?name(^php[0-9.]+$)'lists the installed interpreter packages to compare with its advisory. - Finish the rollout. Replace affected images or packages and restart the relevant services and workers; changing files on disk does not replace processes already running. Check every replica or pool, then verify the version or package identity through the serving environment and test ordinary site functions.
- Interpret checkers narrowly. OpenAI’s checker reads HTTP version headers or local CLI output. Its
OKmeans a version comparison passed, not that it independently inspected the patch. Hidden headers produceUNKNOWN, which is not evidence of safety, and backported packages can look vulnerable by version. Checker documentation.
Evidence boundary: this article is source-based reporting with an original conceptual explanation. AIHackers did not run the version checker, scan a deployment, reproduce an exploit or run a seeded review experiment. Exploitation reports, exposure counts and researcher demonstrations remain attributed claims. Status reflects sources checked on October 22, 2026, at 15:30 UTC.
Read next
- AI agent security incidents and what they establish: the other side of capable agents.
- Codex: tools, access and working boundaries: OpenAI’s checker ships as a Codex skill.
- Risks hub: what can break, leak or expose your data in AI tools.
- How AIHackers separates evidence from inference.