- A complete, automatically refreshed inventory of PHP runtimes and owners
- Exploited versions patched or isolated within the federal remediation window
- Request tracing on legacy apps before any code was changed
- A golden image and pipeline that keep every PHP app on a supported release
- Legacy quoting functions moved behind a facade and retired one route at a time
Anonymised composite. Client names, identifying details and confidential figures are withheld; public facts are cited in the references.
The situation
A specialty insurer in the United States had grown its digital estate over fifteen years. The agent portal and quoting tools ran on PHP, alongside dozens of marketing and campaign sites built by agencies, a document-generation service, and vendor appliances that embedded PHP without anyone realising. Some runtimes were current; others were several releases out of support.
Why now. On 26 October 2026, CISA added two PHP remote code execution flaws, known as PHP2Shell, to its Known Exploited Vulnerabilities catalog and gave US federal agencies days to remediate13. Researchers reported successful exploitation in the wild2. For a regulated insurer, the first question from the board was simple: are we exposed? The honest answer was "we don't know yet", and that was the real problem to solve.
What had to be true
- Exposure closed within days: every affected runtime patched to a fixed release or isolated.
- One trustworthy inventory of PHP runtimes, versions and owners, refreshed automatically.
- No outage for agents during quoting hours.
- Visibility before change: know what each legacy app actually does in production before touching it.
- A durable fix, so the next advisory is routine work, not a crisis.
Architecture
The data flow, end to end
- DiscoverScans, cloud APIs, image registries and DNS merged into one runtime list
- TriageEach runtime scored by version, internet exposure and business criticality
- ContainWAF rules and isolation for anything that cannot be patched today
- PatchRebuild on a fixed release from the golden image and roll out
- VerifyRescan, check logs for exploitation since fixes shipped, close the item
- ModerniseTrace the legacy app, then move routes behind the facade one by one
The patched releases (8.5.12, 8.4.27, 8.3.36 and 8.2.35) were available from 21 October2. Anything on PHP 8.1 or older could not simply be patched, because those branches no longer receive security fixes4; CISA's advice for such systems was to take them offline until they could be upgraded1.
The hard part: changing systems nobody fully understood
The quoting tool had no tests and few people who knew it well. Before upgrading or migrating anything, the team added request tracing at the web server. The OpenTelemetry module for Apache HTTP Server records each incoming request as a trace, with spans for the modules involved, so you can see what the server is doing without changing application code5.

A few weeks of traces showed which routes agents actually used, which were dead, and which called downstream systems. That turned an unknown monolith into a ranked list of routes to move.
The first deliverable of any legacy modernisation is a map of what the system really does in production. Traces give you that map for free.
With that map, quoting functions moved behind a routing facade one route at a time, the strangler fig approach6: new services took over a route, traffic shifted gradually, and the old code path was removed once unused. More on the observability side in OpenTelemetry Collector deployment patterns.
How it ran
- Advisory triage
- WAF virtual patches
- Exploitation log review
- Runtime inventory
- Golden images and rollout
- Patch SLAs in the pipeline
- Confirm owners
- Tracing on legacy apps
- Route-by-route migration
- Inventory sprint
- WAF rules
- Isolate unsupported runtimes
- Golden images
- Rolling upgrades
- Exploitation review
- Tracing on legacy apps
- Automated inventory
- Patch SLAs
- Routing facade
- Route-by-route migration
- Static marketing sites
Key decisions and trade-offs
| Decision | Alternative | Why |
|---|---|---|
| Isolate unsupported runtimes immediately | Leave them up behind the WAF | No security fixes are coming for those branches; a WAF is a stopgap |
| Golden images for all PHP apps | Patch each server by hand | One rebuild fixes every app; drift disappears |
| Trace before changing code | Read the code and guess | Production behaviour beats documentation that no longer exists |
| Strangler facade | Big-bang rewrite | Small, reversible steps with no quoting outage |
| Static hosting for marketing sites | Keep a PHP runtime per site | Removes dozens of attack surfaces entirely |
What I'd do again, and differently
Again: inventory first, then golden images, then tracing before touching code. Differently: put patch SLAs and the exceptions register in place before an emergency, not after. The scramble was mostly the cost of not knowing what was running. For the incident-review side, see running useful postmortems, and for the week's context, tech news for 29 October.
If your estate has systems nobody can fully map, my work with US companies and technical due diligence pages explain how I approach it, or analyse your challenge and bring the result to a call.
- 1CISA warns of PHP bug exploitation attempts, gives federal agencies days to patchThe Record · Oct 2026
- 2CISA confirms PHP2Shell under attack as researchers clock successful exploitsThe Register · 27 Oct 2026
- 3
- 4
- 5Learn how to instrument Apache Http Server with OpenTelemetryOpenTelemetry blog (Debajit Das) · 27 May 2022
- 6StranglerFigApplicationMartin Fowler