Case study · Application security

From emergency patch to modern platform: securing a legacy PHP estate without a big-bang rewrite

A US specialty insurer ran its agent portal, quoting tools and dozens of marketing sites on PHP, some of it years out of support. When an actively exploited PHP flaw landed, nobody could say quickly where PHP was running. The goal was to close that exposure in days, then turn a one-off scramble into a platform that stays patched.

Case studyInsurance · United StatesSumanta Mukhopadhyay9 min read
#security#platform#architecture
CASE STUDY · CASE STUDY · APPLICATION SECURITY29 Oct 2026 · 05:20 GST
At a glance
SectorInsurance · United States
My roleFractional CTO and principal engineer
EngagementIncident response, architecture and delivery leadership
ScopeRuntime inventory, emergency patching, observability, golden images, phased modernisation
What changed
  • 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
PHP 8.x (supported releases)Apache HTTP ServerContainer golden imagesWeb application firewallOpenTelemetryKubernetesTerraformSoftware bill of materials

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

Edge
CDN and WAFvirtual patches while upgradingRouting facadeold and new behind one front door
Apps
Agent portalPHP, patchedQuotingmigrating route by routeMarketing sitesmoved to static
Platform
Golden PHP imagessupported releases onlyKubernetesrolling, reversible deploysTerraformreproducible environments
Visibility
Runtime inventoryversions, owners, exposureOpenTelemetrytraces from Apache and PHPSBOMper image
Governance
Patch SLAsby severity and exploitationExceptions registerowner and expiry
Inventory and images make patching routine; the facade makes modernisation gradual.

The data flow, end to end

  1. DiscoverScans, cloud APIs, image registries and DNS merged into one runtime list
  2. TriageEach runtime scored by version, internet exposure and business criticality
  3. ContainWAF rules and isolation for anything that cannot be patched today
  4. PatchRebuild on a fixed release from the golden image and roll out
  5. VerifyRescan, check logs for exploitation since fixes shipped, close the item
  6. ModerniseTrace the legacy app, then move routes behind the facade one by one
The same loop handles the next advisory; only the first run was an emergency.

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.

Zipkin trace view showing a request to an Apache HTTP Server with child spans for mod_proxy, mod_proxy_balancer and mod_dav handlers and their durations
Tracing at the web server shows which modules and routes each request touches, before any code changes. Source: OpenTelemetry blog, Debajit Das · CC BY 4.0

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

Security
  1. Advisory triage
  2. WAF virtual patches
  3. Exploitation log review
Platform
  1. Runtime inventory
  2. Golden images and rollout
  3. Patch SLAs in the pipeline
Product teams
  1. Confirm owners
  2. Tracing on legacy apps
  3. Route-by-route migration
Security bought time, platform made patching repeatable, product teams retired the legacy code.
Days 1 to 3Contain
  • Inventory sprint
  • WAF rules
  • Isolate unsupported runtimes
Week 1Patch
  • Golden images
  • Rolling upgrades
  • Exploitation review
Weeks 2 to 6See
  • Tracing on legacy apps
  • Automated inventory
  • Patch SLAs
Months 2 to 9Modernise
  • Routing facade
  • Route-by-route migration
  • Static marketing sites
The emergency took days; the platform that prevents the next one took months.

Key decisions and trade-offs

DecisionAlternativeWhy
Isolate unsupported runtimes immediatelyLeave them up behind the WAFNo security fixes are coming for those branches; a WAF is a stopgap
Golden images for all PHP appsPatch each server by handOne rebuild fixes every app; drift disappears
Trace before changing codeRead the code and guessProduction behaviour beats documentation that no longer exists
Strangler facadeBig-bang rewriteSmall, reversible steps with no quoting outage
Static hosting for marketing sitesKeep a PHP runtime per siteRemoves 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.

References
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
    Learn how to instrument Apache Http Server with OpenTelemetryOpenTelemetry blog (Debajit Das) · 27 May 2022
  6. 6
FAQ

Common questions

How do you find every PHP runtime in a large estate?

Combine sources: cloud and hypervisor inventories, container image scans, web server banners from external and internal scans, package manager data on hosts, and DNS records for forgotten sites. Reconcile them into one list with an owner per runtime, and refresh it automatically.

Is a web application firewall enough for an exploited PHP flaw?

No. A WAF rule can buy time while you patch, but it is a compensating control. The fix is upgrading to a patched release, or isolating anything that cannot be upgraded, as CISA advises for PHP 8.1 and older.

Why not rewrite the legacy PHP applications?

Big-bang rewrites of business-critical systems are slow and risky. The strangler fig approach puts a facade in front of the old system and replaces it route by route, so each step is small, testable and reversible.

Keep reading

Related

Open to advisory, fractional CTO & select builds

Let's talk about what you're building.

The fastest route is a free 30-minute call. Prefer to write? Send a message and I'll reply personally within two business days.

Start a conversation

How would you like to reach me?

Book a 30-min callFastest. Pick any open slot on my calendar.→ Write in GmailOpens a pre-filled draft in your browser.→ Use my email appOutlook, Apple Mail or your default client.→

I reply personally within two business days. Time zones from the Americas and Europe to the Middle East and Asia-Pacific.