Incidents & Vulnerabilities
Equifax breach (2017) — how an unpatched Apache Struts flaw leaked 147M people
In 2017, ~147M people's data leaked from Equifax. The cause: a known, already-patched Apache Struts flaw (CVE-2017-5638 / CVSS 9.8) left unapplied on a public system, plus an expired monitoring cert that hid exfiltration for 76 days. Defenses: asset inventory, patch SLA, machine monitoring.
We read real public incidents not as news reruns, but through "how would you defend against this". This article is based on public records (regulators, official statements, the Apache Software Foundation, reporting), cited at the end.
- Target
- Equifax (major US credit bureau)
- Disclosed
- Sept 7, 2017 (intrusion May–Jul / detected Jul 29)
- Class
- Intrusion via an unapplied known CVE (Apache Struts RCE) + exfiltration
- Scale
- ~147M people in the US (names, SSNs, DoB, addresses; some card numbers)
- Root cause
- neglected known CVE + missing asset inventory + a detection gap (expired cert)
- Main fixes
- patch SLA, asset inventory, machine monitoring, healthy detection
What happened (plainly)
Equifax ran an online portal where consumers dispute their credit information. The Apache Struts component it was built on had a serious flaw allowing arbitrary code execution from outside (CVE-2017-5638).
The fix shipped the same day the flaw was published (March 7, 2017). But the target system was left unpatched. Two months later the attacker exploited the known vulnerability, moved laterally through the network, and exfiltrated personal data at scale.
Worse, the device that monitored the traffic was down for a long time due to an expired certificate, so the anomalous exfiltration went undetected for 76 days. The moment the certificate was renewed on July 29, the suspicious traffic appeared. The mechanism for noticing had been switched off.
The cause was not a sophisticated attack but a patch that wasn't applied
The vulnerability used here was public worldwide and already patched. It wasn't the attack's sophistication but the lack of an operation to close known risks within a deadline that caused the damage. This happens the same way for solo developers and organizations.
Each stage of the attack and how to stop it
What matters is that this was a five-step chain, and each step had a place to stop it. Read it as "where it could have been stopped", not as an attack recipe.
① A known CVE is published (fix released same day)
⊘ stop: machine-detect CVEs that match you
② A public system is left unpatched
No view of where Struts ran, so it was missed.
⊘ stop: asset inventory + patch SLA (deadline)
③ Intrusion via RCE
Arbitrary code execution through the unpatched vulnerability.
⊘ stop: least privilege; a WAF only as backup
④ Lateral movement across a flat network, bulk exfiltration
Weak segmentation let one breach reach broad data.
⊘ stop: network segmentation limits how far one breach can reach
⑤ Undetected for 76 days (expired monitoring cert)
The device for noticing was switched off.
⊘ stop: routine cert/monitoring health checks
Disclosed timeline
2017-03-07
CVE-2017-5638 is published; a fix is released the same day.2017-03–
An internal advisory goes out, but the target system stays unpatched.2017-05–07
The attacker exploits the unpatched vulnerability and exfiltrates data.2017-07-29
Right after the monitoring certificate is renewed, suspicious traffic is detected.2017-09-07
Public disclosure; ~147M people affected.2019-07
Settlement of up to ~$700M with the FTC, CFPB, and states (largest of its kind).
Root cause: more than one missed patch
End it at "they forgot the patch" and it repeats. In truth several layers failed in sequence.
As it was (at the time)
- Neglected a known CVE (fix existed, not applied to a public system)
- No asset inventory (couldn't tell where the component ran)
- A flat network (allowed lateral movement and data spread)
- A detection gap (monitoring down on an expired certificate)
As it should be (prevention)
- Patch SLA: a deadline from publish to apply, prioritizing KEV / high CVSS
- Asset inventory: machine-track dependencies and where they run
- Network segmentation: limit how far a single breach can reach
- Healthy detection: routinely verify certs and monitoring are working
Patching is an ongoing process, not a one-off task
What matters isn't "fix it someday" but having a deadline (SLA): apply within N hours/days of publish. And to not miss targets, a machine must know what runs where. Rely on memory and, like Equifax, an unpatched system gets left behind.
Preventing it in your environment
Priority-ordered fixes that work at any scale, anchored on one thing: don't neglect a published CVE.
Keep an asset inventory (what runs where)
List your dependency libraries and which services/containers run them. Equifax's biggest problem was missing a target system. Judge by the version actually running.
Set a patch SLA (deadline from publish to apply)
Decide "apply critical CVEs within N days of publish" up front. Prioritize KEV (being exploited) and high CVSS. A deadline makes neglected fixes visible.
Let machines monitor (don't chase by hand)
Chasing CVEs manually is impossible. Check lockfiles with Dependabot (GitHub) or osv-scanner, and auto-notify only the CVEs that match you. See how to build dependency monitoring.
Have isolation and detection (in case an attack gets through)
Segment networks to limit lateral movement and detect anomalous bulk exfiltration. Include checking that monitoring and certificates are working in operations. Monitoring that is switched off detects nothing.
This site does this itself
This site keeps its own dependencies under CVE monitoring, exactly as written here. We apply Equifax's lesson ourselves: close known vulnerabilities with a process that doesn't depend on people remembering. Replace "fix it someday" with "fix it within a deadline, with machine help".
Sources (public records)
The facts here are based on the following public information, focused on defensive lessons — not reproduction steps or payloads.
- Apache Software Foundation, "Media Alert: Equifax Data Breach Due to Failure to Install Patches" (2017) — news.apache.org
- Equifax, "Releases Details on Cybersecurity Incident" (2017) — investor.equifax.com
- CFPB/FTC/states settlement announcement (2019) — consumerfinance.gov
- CSO Online, "Equifax data breach FAQ" — csoonline.com
Read next
- Glossary: What is a CVE · What is CVSS · What is RCE
- Defense: Machine-monitor dependencies (patch operations)
- Incident: Capital One — SSRF leaked 100M+
FAQ
QWhat was the root cause of the Equifax breach?
Not a novel, sophisticated attack, but a 'known, already-patched vulnerability (Apache Struts CVE-2017-5638 / CVSS 9.8) left unapplied on a public system'. They also couldn't tell where the component ran, and a monitoring device was down due to an expired certificate, so exfiltration went unnoticed for 76 days.
QThe patch existed — why wasn't it applied?
Per public records, the fix shipped the same day the flaw was published (March 7, 2017). An internal advisory went out, but the patch wasn't applied to the target online-dispute system. An inadequate asset inventory (no clear record of where the component ran) meant the system was missed.
QIs there a lesson for small projects?
Yes. Regardless of scale, the same three points hold: don't neglect known CVEs, know whether that component is in your dependencies, and let machines monitor so nothing is missed. Chasing CVEs by hand is impossible, so let Dependabot or osv-scanner monitor them.