
PHP2Shell: What Happened, Why It Happened, and What to Do Now
A sourced investigation of PHP2Shell: the two critical PHP flaws, reported attacks, emergency patches, prevention lessons, and steps for potentially affected sites.
The immediate answer
The PHP security emergency unfolding on October 21, 2026 concerns PHP2Shell, two critical vulnerabilities in the PHP runtime: CVE-2026-109618 and CVE-2026-109619. Both can enable unauthenticated remote code execution under exploitable conditions. PHP has released fixes. If you operate a PHP website, verify the PHP runtime actually serving its requests and update it immediately. A WordPress, Drupal, or plugin update alone is not the same operation. PHP's release advisory
For operators in a hurry: establish an owner for every PHP deployment, apply a verified fixed package or image, replace old running workers, and investigate suspicious activity independently of patching. If you cannot remediate an exposed application promptly, consider isolating it from public access. That isolation recommendation is also present in the European agencies' joint statement.
This is a developing incident, not a completed forensic history. This article is a publication-day assessment dated October 21, 2026, Eastern Time. It separates maintainer-confirmed behavior, researchers' demonstrations, providers' observations, and my own engineering recommendations. It does not claim to have tested an exploit or investigated a victim organization. The diagrams are original explanatory illustrations, not screenshots of attacks or measurements of compromise.
What actually happened, and what remains unproven
Calling this “the PHP hack” compresses several different events into one phrase. Researchers established serious flaws in PHP. Maintainers coordinated emergency fixes. Exploit demonstrations and public attention accelerated. Providers began deploying defenses, while some operators temporarily withdrew services.
These categories matter because each answers a different question:
| Evidence category | What it establishes | What it does not establish |
|---|---|---|
| A vulnerable version is installed | A remediation or vendor-validation task exists | That an attacker reached the installation |
| A researcher demonstrates execution | A particular setup can be exploited | That every deployment is equally exploitable |
| A security provider sees attack traffic | Attempts are reaching monitored infrastructure | That every attempt succeeded |
| A service goes offline | Availability changed | Whether the cause was compromise or precaution |
| Forensic evidence confirms attacker activity | A specific system was compromised | The total number of victims worldwide |
Cloudflare says it observed attacks against its customers and changes to payloads intended to evade protection. It says its PHP2Shell protections became available by default for customers using its free or paid WAF at 03:02 UTC on October 21. Those are the provider's observations and protection claims, not a census of successful breaches. Cloudflare's incident report
Wiz reports demonstrating unauthenticated code execution against the WordPress, Drupal, and Joomla container images it tested. It also describes memory disclosure and multiple variants grouped under the two CVEs. This is significant evidence of practical exploitability, but a demonstration against a named application's deployment does not mean that application's own code introduced the flaw. Wiz Research
There are also documented precautionary outages. Email-alias service addy.io says it took its website and web application offline while updating, then restored them; email delivery continued. Its explanation describes a protective shutdown, not a confirmed intrusion. addy.io's account
I could not establish a reliable global victim count from the primary sources reviewed. Claims that a percentage of “the internet was hacked” confuse technology adoption with confirmed compromise. We also should not infer a particular criminal group, motive, or data-theft campaign without evidence tying it to an intrusion.
The disclosure timeline
The PHP Foundation traces early signs to 2024 audit follow-up, before a concrete execution path was established. It attributes delays to resource constraints and difficult compatibility decisions. Reports from Calif, OpenAI, Wiz, and others later clarified the impact. PHP Foundation retrospective
| Date | Documented development |
|---|---|
| 2024 | Early signs of the OOM problem emerge during audit follow-up. |
| August 2026 | Concrete reports clarify the impact and intensify remediation. |
| October 20 | CVE identifiers circulate; PHP issues advance notice. |
| October 21 | Emergency releases and technical advisories become public. |
The Foundation describes leaked identifiers, an accidentally published demonstration, and premature distributor images. The planned October 22 release moved forward. This article reports that account without independently adjudicating participants' responsibility. Foundation disclosure account

Figure 1. A deliberately coarse timeline. Sources: the Foundation account above and the release notices below. It shows sequence, not the duration of confirmed malicious activity.
The pre-announcement scheduled release for 14:00 UTC, or 10:00 a.m. EDT. Publication-day summaries differ on the precise earlier availability time: CERT-EU records 13:30 UTC; ENISA records 13:40 UTC. The defensible statement is that fixes became available October 21, before the announced deadline, rather than presenting one minute as universally settled. PHP advance notice, CERT-EU, ENISA
Why these vulnerabilities are unusually consequential
PHP runs on the server. It processes requests and executes application code before sending a response to a browser. A problem in that runtime can therefore sit underneath many unrelated products. The UK NCSC explicitly tells organizations to inventory PHP throughout their infrastructure, including appliances and third-party services that bundle it. NCSC alert
The important architectural question is where the security boundary sits. An application login protects application actions after the application can enforce that login. It cannot reliably protect a vulnerable runtime operation that happens earlier. Likewise, a protection implemented inside PHP depends on PHP safely reaching that protection.
This is why I would challenge the reassuring statement “our admin page requires multifactor authentication.” MFA remains valuable, but it answers a different question. The relevant question here is whether untrusted network input can reach vulnerable PHP processing at all.
CVE-2026-109618: interruption during partially initialized state
PHP's OOM advisory explains that longjmp() can abort processing after an allocation failure while internal request data is only partly initialized. Cleanup can then consume invalid state. It documents unauthenticated remote execution on Apache mod_php, including before application code runs. The fix changes OOM handling to defer a soft failure to a safe execution point, with a hard exit at a higher threshold. Maintainer OOM advisory
A useful conceptual model is an interrupted handoff: one part of the engine has made a structure reachable, but has not finished making it safe for another part to use. Cleanup assumes the handoff completed. This analogy explains the lifetime problem; it is not a description of a payload.
CVE-2026-109619: a later request uses yesterday's pointer
The second advisory describes request-owned memory that is freed while a reusable worker retains references to it. An operation in a later request can consume that stale state before normal initialization replaces it. Exploitation requires a suitable producer and consumer, with requests reaching the same worker. The advisory confirms remote execution through session-lifecycle paths on both mod_php and PHP-FPM. Maintainer stale-state advisory
Think of a reusable worker as a desk used for successive jobs. Clearing the old paperwork is not enough if the desk still contains instructions to use an old location. That location may now contain something else. The mistake is not simply “too much traffic”; it is treating an invalid reference as trustworthy state.

Figure 2. Simplified models of the two maintainer advisories. The sculptural forms illustrate lifecycle stages, not a runnable exploit or a complete list of variants.
Configuration differences affect the path, not the patch obligation
The PHP project explicitly includes PHP-FPM, mod_php, CGI, FrankenPHP, and LiteSpeed in its warning. It assigns the highest risk to mod_php. PHP release advisory
There is a publication-day documentation inconsistency worth preserving: the OOM advisory says a complete FPM exploit was not demonstrated for that SAPI, while the Foundation's narrative says OOM-related FPM execution was confirmed through application paths. The separate stale-state advisory clearly confirms an FPM session-lifecycle exploit. FPM must not be treated as safe. Exact demonstration claims should name their CVE and source. OOM advisory, Foundation account, stale-state advisory
Who is affected, and which versions contain fixes?
Both issues are rated CVSS v4.0 9.2, Critical. A severity score is not a probability that your server has been compromised. The supported-branch remediation thresholds published for this incident are: CERT-EU advisory
| PHP branch | First upstream release with these fixes |
|---|---|
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |
Earlier builds in each branch require remediation or a verified vendor backport.

Figure 3. Publication-day patch reference. Source: CERT-EU. These are minimum fixed releases for this incident, not a recommendation to avoid later security updates.
PHP also supplied minimal source backports for 7.4, 8.0, and 8.1. That exceptional assistance does not restore normal upstream support. Distribution and commercial support packages may use their own revision numbers, so compare the complete package revision with the vendor's advisory rather than rejecting or accepting it solely from the upstream-looking number. PHP's update instructions
PHP's published lifecycle gives branches two years of active support followed by two years of security support. An emergency fix is therefore a reason to review the next upgrade deadline, not to reset your support assumptions. PHP support policy
Wiz traces affected code as far back as PHP 5.4, while describing different requirements across variants. Treat legacy systems as an inventory priority; do not interpret “our version is old” as immunity. Wiz technical research
For embedded products, consult the vendor and the NCSC-NL coordination repository. A missing product entry is not evidence of safety. Record the vendor's actual determination, its date, and the affected product version.
Our take: could this have been prevented?
The honest answer has three parts. Runtime design and security governance could have reduced the chance or duration of the vulnerability. Deployment controls could have reduced exposure. Containment could have reduced damage after exploitation. None supports a claim that an individual administrator could have patched an unavailable release.
The following is my engineering analysis, not a claim that these measures were tested against every PHP2Shell variant.
What AI changes, and what it does not
Wiz describes frontier AI as helping researchers turn difficult, longstanding engine flaws into practical demonstrations. That is a claim about the research process; it does not establish that these defects were originally written by AI or that every malicious attempt is AI-operated. Wiz's research account
My interpretation is that faster discovery increases the value of a fast, reliable response system. A tool that finds more defects does not automatically supply the maintainers, compatibility decisions, distribution coordination, or deployment capacity needed to remove them. Defenders should measure time to a verified fix, not celebrate report volume as though it were the same outcome.
Nor should “AI found it” become a reason to skip validation. A security report still needs reproducibility, a clear affected configuration, an impact assessment, and a reviewed correction. The useful investment pairs better discovery with the human and operational capacity to act on credible findings.
1. Treat exceptional control flow as part of the security model
Most application tests ask whether valid input produces the correct output. Runtime tests also need to ask what remains true when execution stops at the worst possible point. Allocation failure, timeout, error callbacks, shutdown hooks, and worker reuse deserve explicit attention.
For systems with manual memory management, I would make ownership and initialization invariants reviewable: who owns a structure, when it becomes visible, which exit paths can interrupt its construction, and who may still reference it after teardown. Fault injection should deliberately fail allocations across those transitions. Sanitizers and fuzzing can help reveal violations, but passing a test campaign cannot prove that all memory-safety defects are absent.
A useful review exercise is to walk each lifecycle backward. If cleanup runs now, what does it assume has already happened? If a second request starts now, what state does it inherit? That method targets the kind of boundary error illustrated here without needing a weaponized reproduction.
2. Give difficult security decisions an escalation deadline
When every proposed fix has compatibility or availability costs, consensus can become a waiting room. My recommendation is to assign one accountable decision owner, require written tradeoffs, set a deadline for escalation, and reserve engineering capacity for high-impact unresolved risks.
The goal is not to pretend that maintainers can fix everything instantly. It is to prevent “we cannot agree on the least harmful change” from silently becoming a long-term security policy. An organization that depends on an open-source runtime should fund maintenance and review capacity as part of its operating cost.
3. Make emergency rollout a rehearsed product capability
A team should be able to answer where PHP runs, who can update it, how a fixed build enters production, how old workers are retired, and what proves completion. Those answers should exist before a headline arrives.
I would rehearse a runtime update using a small representative deployment, then expand with observable health checks. The rollback plan must be explicit: reverting to a known-vulnerable runtime may restore availability while reopening the security exposure. A better fallback may be isolation or a reduced service built on a verified fixed image.
4. Reduce what the PHP process can reach
Successful code execution has the privileges and access of the compromised process; it is not automatically root access to every connected system. That distinction creates a concrete design opportunity. Use narrowly scoped database accounts, separate service identities, limited filesystem write access, and restricted network paths.
For example, a public content site should not need a database credential that can administer every tenant. A web container should not need a mounted container-engine socket. A content upload directory should not become an unrestricted program-execution location. These are examples of reducing consequences, not assertions about what happened to a particular victim.

Figure 4. Original defensive threat model. Orange paths show possible access if a process is compromised. They do not assert lateral movement, root access, or data theft in this incident.
What to do if you think you are impacted
Run two tracks together: remove the vulnerability and determine whether it was used. Do not make one the completion criterion for the other.
Step 1: identify the real runtime and the accountable operator
Start with public websites, but include internal tools, staging sites, old subdomains, disaster-recovery instances, containers, and appliances. For each deployment, record its hostname, environment, owner, web-server integration, PHP version, package revision or image digest, and exposure path. The NCSC's guidance includes both infrastructure inventory and monitoring vendors for bundled-PHP updates. NCSC alert
With authorized shell access, these read-only commands provide a starting point:
php -v
php --ini
They report the invoked command-line binary and its configuration. They do not prove that Apache, an FPM pool, another container, or every node behind a load balancer is using that binary. PHP documents both switches in its command-line reference. Its configuration documentation also explains that configuration loading depends on how PHP runs.
Use authenticated administration or deployment inspection to establish the web runtime. Avoid leaving a public diagnostic page online: phpinfo() can reveal configuration, paths, headers, and environment information. PHP's phpinfo documentation
On managed hosting, ask for a precise answer: “Which package revision fixes both CVEs on my account, when was it deployed, and have all serving workers been replaced?” A generic message that the provider is monitoring the situation is not evidence that your instance is patched. WordPress explicitly tells site owners to check with their host and update PHP. WordPress security notice
Step 2: patch what is running, not just what is stored
My recommended completion record contains the old revision, the fixed revision, the deployment time, the worker replacement time, and the verification result. Keep one record per independently deployed service rather than a single checkbox for the whole estate.
For containers, rebuild or select a verified fixed image and redeploy the application. Updating the host's PHP package does not establish what is inside an image. Cloud.gov's incident instructions specifically distinguish its PHP buildpack from customer-managed container images and tell the latter group to update and redeploy. Cloud.gov guidance
For long-running workers, verify replacement rather than assuming that a package installer did it. PHP's configuration-loading behavior explains why editing a file alone is insufficient for server modules. PHP configuration lifecycle
Then check login, sessions, uploads, scheduled processing, and the application's main business transaction. These are practical smoke checks, not exploit tests. Verify every replica and the images used for future scale-out, or the next restart may reintroduce an old build.
Step 3: if patching is blocked, contain exposure deliberately
Prefer restricting access before requests reach PHP. A maintenance page rendered by the vulnerable application is a poor isolation boundary. Use the load balancer, reverse proxy, network controls, or an independently served static page, and account for alternate hostnames and direct-origin access.
The official configuration workarounds are partial. In abbreviated form, they include administratively enforcing memory_limit=-1 for the OOM path, disabling session upload progress before parsing, and disabling fatal_error_backtraces on PHP 8.5 for a specific stale-state path. Workers must be restarted. The advisory warns that underlying allocation failures and other variants remain possible; RLIMIT_AS and RLIMIT_DATA are inappropriate substitutes. CERT-EU mitigation details
Do not turn those settings into an unattended “fix everything” script. Removing PHP's normal memory ceiling changes availability risk. Request limits must be evaluated against real application behavior and the frontend's handling of decoded data. Use the linked vendor instructions for the full conditions, and assign an expiry and patch owner to temporary measures.
A WAF can buy time, but it is a separate control. Cloudflare itself says customers should still patch. Confirm that the applicable rules are enabled and that requests cannot bypass the protected entry point. Cloudflare guidance
Step 4: investigate evidence of exploitation
Begin by preserving the information you will need to reconstruct events. That can include proxy and web-server logs, PHP errors, host process telemetry, authentication events, outbound connections, deployment history, and relevant cloud audit records. Record collection time and timezone, protect the originals, and restrict access to evidence that contains sensitive data.
Elastic's PHP2Shell detection discussion emphasizes behavior such as unexpected processes launched by web services and suspicious follow-on execution. Those are useful investigative signals, but a detection rule needs the appropriate telemetry and can have blind spots. Elastic Security Labs
My recommended investigation questions are:
- Did a PHP or web-server worker start an unexpected shell, interpreter, or downloader?
- Did executable files, configuration, scheduled tasks, or administrator accounts change outside a known deployment?
- Did the service make unusual outbound connections or access secrets it normally leaves untouched?
- Do memory errors, worker crashes, or unusual requests correlate with those stronger signals?
- What evidence is missing because logging was disabled, incomplete, or already rotated?
A memory error by itself is not proof of intrusion. A suspicious request by itself is not proof of successful execution. Conversely, a quiet access log does not prove no compromise: it may not contain request bodies, process activity, or evidence from an alternate route.
Step 5: if compromise is suspected, recover trust
Escalate to the incident-response owner or a qualified responder. Isolate affected systems while balancing evidence preservation and ongoing harm. Avoid casually wiping or rebooting a suspected host before deciding whether volatile evidence is needed; do not leave an active intrusion connected merely to collect more logs.
For confirmed compromise, my recommendation is to rebuild from trusted sources after evidence collection, fix the entry path, and evaluate every credential accessible to the affected service. Rotate or revoke exposed secrets from a clean administrative environment. Consider database credentials, API tokens, service identities, signing keys, and sessions according to what the investigation establishes. Patching a runtime does not remove an attacker's separate persistence or invalidate a copied secret.
This workflow follows the broad separation of detection, response, and recovery in NIST SP 800-61 Revision 3; the PHP-specific operational checklist here is my synthesis. Decisions about customer notification, contractual duties, or regulatory reporting should go through the organization's incident and legal teams using the actual facts and applicable jurisdiction.

Figure 5. An original response checklist. Remediation and investigation proceed in parallel; a completed update is not a forensic clearance.
What this means for website owners and ordinary visitors
If you own a website but someone else manages its hosting, forward the two CVE identifiers and request instance-specific confirmation. Ask whether their response covers the origin, all PHP versions assigned to your account, and any staging or secondary sites. If they cannot provide a safe update path, discuss temporary isolation and a supported migration rather than relying on the fact that the homepage still works.
If you only visit a website, you cannot patch its server from your browser. An outage or maintenance banner does not establish that your personal information was stolen. Follow the operator's official security communications and any account-specific instructions. Do not install a “PHP repair” utility offered by a random message or submit credentials to an unsolicited emergency-checking page.
If an operator confirms credential or session exposure, follow its reset instructions through the legitimate site and address reused passwords on other services. This is contingent advice for confirmed or credibly suspected exposure, not a claim that every visitor to a PHP site now needs an emergency reset.
The lesson I would carry into the next incident
PHP2Shell makes a familiar operational weakness visible: a team may know its application very well while having a poor account of the runtime underneath it. The useful outcome is not simply a newer version number. It is a defensible chain of evidence from advisory, to affected asset, to fixed deployment, to verified running service, with a separate answer about possible intrusion.
My standard would be straightforward: name the owner, prove the revision, verify the workers, preserve the evidence, and state what remains unknown. That is a much stronger response than either minimizing a serious flaw or describing every vulnerable site as already breached.
For more context on how I approach implementation and operational tradeoffs, see my development background and the projects behind this portfolio.
Sources and reporting method
Primary sources were preferred over social posts and secondary headlines. Source statements were checked on October 21, 2026, Eastern Time. The list below is a reading trail; citations beside individual claims identify their basis. Source pages can change after publication. Differences in release timing and FPM demonstration language are explicitly retained above rather than silently reconciled.
- PHP Security Team. (2026, October 21). Critical remote code execution vulnerabilities: update now. Release scope, fixed versions, and update guidance.
- PHP maintainers. (2026, October 21). RCE via OOM corruption, GHSA-w8hw-w9fx-j79w. CVE-2026-109618 technical advisory.
- PHP maintainers. (2026, October 21). RCE via stale global state, GHSA-6wmf-4rv5-p3rp. CVE-2026-109619 technical advisory.
- The PHP Foundation. (2026, October 21). Today's PHP Security Release, and How We're Strengthening PHP Security. Maintainer-side history and disclosure account.
- PHP Security Team. (2026, October 20). Upcoming Critical PHP Security Release. Advance notice.
- CERT-EU. (2026, October 21). Security Advisory 2026-018. Severity, versions, and mitigation conditions.
- ENISA and partner agencies. (2026, October 21). Joint statement on critical PHP vulnerabilities. Coordinated operational advice.
- UK National Cyber Security Centre. (2026, October 21). Critical security issue affecting PHP. Inventory, monitoring, and isolation guidance.
- Tzadik, S., Tamari, S., Ohfeld, N., & Schwartz, T. (2026, October 21). PHP2Shell technical research. Wiz's discoveries and demonstrations.
- Molteni, D., Jones, D., & Nandwani, K. (2026, October 21). Cloudflare deploys protections against php2shell. Provider observations and WAF claims.
- addy.io. (2026, October 21). Why addy.io went offline. First-party account of a precautionary outage.
- Blackbourn, J. (2026, October 21). Critical PHP Security Release. Guidance for WordPress site owners.
- Cloud.gov. (2026, October 21). Action required: Critical PHP vulnerabilities. Buildpack and container remediation responsibilities.
- Elastic Security Labs. (2026, October 21). Assessing detection coverage for PHP2Shell. Behavioral detection considerations.
- NCSC-NL. (2026). PHP2Shell coordination repository. Evolving third-party product information.
- PHP documentation. Supported versions, command-line options, configuration loading, and phpinfo. Runtime-verification background.
- Nelson, A., Rekhi, S., Souppaya, M., & Scarfone, K. (2025). NIST SP 800-61 Revision 3. General incident-response framework, not a PHP2Shell advisory.
Share this article

Ryan VerWey
Full-stack developer, Army veteran, and founder of Echo Effect LLC. His experience timeline documents current Ratespedia CTO work, Department of War contractor work, and prior Army service. More about Ryan or see the work.
Recommended Reading

Application Integration and Security at Full Sail University
Review Application Integration and Security at Full Sail, covering Python, authentication, vulnerability scanning, containers, and secure deployment.

Enterprise AI Is Not About Tokens. It Is About Control.
Analyze Alex Karp's CNBC interview through enterprise AI control, market positioning, competitors, data boundaries, audit trails, and learning loops.

Publish First, Syndicate Later: Automating Dev.to Without Losing SEO Credit
Automate Next.js portfolio blog syndication to Dev.to with images, four tags, a three-day delay, and canonical URLs.