PHP's emergency releases on 21 October changed the immediate job for maintainers. There was now a fix to deploy for PHP2Shell, the pair of critical remote-code-execution vulnerabilities tracked as CVE-2026-109618 and CVE-2026-109619. The less convenient work was establishing which runtime actually served each application and whether the processes handling requests had received that fix.

That distinction matters during a noisy security week. A successful package installation is an event you can record. A repaired production service is a conclusion that needs a little more evidence.

What the emergency release fixed

The PHP security announcement identifies four fixed upstream releases:

Supported branch PHP2Shell security release
PHP 8.5 8.5.12
PHP 8.4 8.4.27
PHP 8.3 8.3.36
PHP 8.2 8.2.35

These are the relevant security-release milestones, not a reason to prefer one application branch over another without checking compatibility. Distribution packages can include backported fixes, so a vendor's advisory and complete package revision belong beside the upstream version in the deployment record.

The first flaw concerns what happens when PHP runs out of memory while internal request data is only partly initialized. Its upstream advisory explains that an abrupt exit can leave invalid state for request cleanup to consume. The confirmed HTTP exploit targets Apache's mod_php, including a path reached before application code begins.

That last detail changes the conversation about application-level protection. An application's own login check cannot provide a boundary for code that runs before the application starts. The runtime and its request-processing environment have to be included in the exposure assessment.

The same advisory describes PHP-FPM as susceptible on source analysis while distinguishing that assessment from a demonstrated complete exploit for that particular SAPI. That is a useful example of precise reporting: evidence for one configuration does not establish every other configuration's exploitability, and a missing demonstration does not establish safety.

The second bug crosses a request boundary

CVE-2026-109619 concerns stale global state. A persistent worker can retain a reference to memory owned by an earlier request. If that memory is released without the reference being safely cleared, a later operation may consume the stale value before normal initialization replaces it.

The advisory separates the operation that leaves state behind from the operation that later uses it. That helps explain why a quick test of one upload form is a poor inventory of the problem. The relevant behaviour can involve request initialization, errors, sessions and the lifecycle of the worker itself.

It also explains why worker replacement belongs in the completion criteria. When an advisory says to restart workers after a configuration change, that is part of applying the change. A file edited on disk does not demonstrate what every already-running process is using.

For a hypothetical deployment, imagine a fixed image has been built and pushed while the service continues running the preceding image digest. The build ticket can truthfully say “complete.” The exposed service still needs a deployment, verification and a record of the resulting running artifact. The distinction is ordinary release engineering with a much shorter deadline.

The exposure window began before the public announcement

Amazon Threat Intelligence reported an exploitation attempt in its MadPot telemetry dated 17 October, four days before the public release. It also described additional attempts before the embargo lifted on 21 October. Amazon explicitly said it was unclear whether those attempts would have succeeded against real-world systems.

That is evidence about observed attempts and their timing. It does not tell us how the actors obtained their information, and it does not establish a count of successfully compromised organisations. An investigation should preserve those distinctions while using the earlier date to decide which records to examine.

CrowdSec's five-day report, covering 21–25 October, counted 1,187 source IP addresses sending requests matching its PHP2Shell patterns. Its discussion of limited evidence for mass exploitation describes its observation window and methodology. Blocked matching requests are not a census of infections across the internet.

The operational conclusion does not depend on choosing the louder headline. The upstream project has released security fixes, and there is evidence of hostile-looking attempts before disclosure. Patching and investigation can proceed together without inventing a more certain global picture.

Keep the 23 October follow-up attached to the ticket

PHP subsequently published an informational session-upload-progress advisory. It described an unusual combination in which an application configures one session serializer and changes it to php at runtime before starting the session, while upload progress remains enabled. The project recommended disabling session upload progress for that situation pending the regular bugfix release, identifying a separate follow-up as CVE-2026-115560.

That does not erase the significance of the 21 October fixes. It means a responsible response records both the emergency update and any applicable subsequent guidance. “We patched PHP2Shell” is too coarse if it hides which advisory, package revision and application configuration someone actually checked.

Give the next maintainer a useful completion record

I would want a short record linking each exposed service to its web-serving PHP runtime, installation source, fixed-package evidence and running process or image. Include the time workers were replaced, the check confirming the intended deployment and any temporary settings with an owner and review date.

Add the investigation window separately. An updated runtime tells you something about current exposure; historical logs and host evidence address whether anything happened beforehand. Mark uncertainty where the retained evidence cannot answer the question.

The useful final handover is concrete enough for another maintainer to inspect. It identifies the service, the repaired runtime and the remaining follow-up. That is how an emergency release becomes a finished piece of maintenance instead of another optimistic sentence in a ticket.

Anime avatar of Jules Navarro
About the author

Software maintenance writer

I'm based in Wellington, New Zealand. I write about code review, maintainer time and the cost of shipping things nobody understands.

A thought worth keeping?