Breach report
Capital One: SSRF to cloud metadata to 106 million records
What happened
In 2019, a former cloud engineer, Paige Thompson, breached Capital One and accessed the records of approximately 106 million credit-card applicants in the United States and Canada. The intrusion itself occurred on March 22–23, 2019; Capital One discovered it on July 19 and disclosed it on July 29. The stolen data included names, addresses, and dates of birth, along with roughly 140,000 U.S. Social Security numbers, about 80,000 linked bank account numbers, and around one million Canadian Social Insurance Numbers.
The attack chained a web-application flaw to a cloud-privilege escalation, and it became the canonical example of how a single server-side request forgery can unravel an entire cloud estate. Capital One faced an $80 million regulatory penalty and hundreds of millions in total costs.
Root cause
The attacker exploited a server-side request forgery (SSRF, CWE-918) in a misconfigured web application firewall that had been granted overly permissive IAM permissions. SSRF let the attacker coerce the server into querying the AWS EC2 instance metadata service (IMDS), which returned temporary IAM credentials. Those credentials — far broader than the WAF actually needed — were then used to list and read customer data from cloud storage. In the 2025 OWASP Top 10, SSRF is folded into Broken Access Control, and this breach is why: a request the server should never have made granted access it should never have had.
How it would have been caught
An IAM audit would have flagged the WAF role's excessive permissions long before exploitation. SSRF-specific testing sends requests whose destination is attacker-chosen and confirms the server will fetch internal-only endpoints such as the metadata IP. A reproduction coerces the app into reading the metadata service and confirms live credentials come back.
How to prevent it
- Enforce IMDSv2, which requires a session token and blocks the simple SSRF-to-metadata pattern.
- Apply least-privilege IAM roles so a compromised component cannot reach unrelated data.
- Validate and allow-list the destinations of any server-side outbound request; never let user input choose the target host.
- Alert on metadata-service access from application code that has no legitimate reason to call it.
The Breachwire test (red → green)
Point the vulnerable endpoint's server-side request at the cloud metadata IP and confirm it returns live IAM credentials usable to read storage — the RED control. Enforce IMDSv2 and destination allow-listing, replay the same request, and confirm the metadata call is rejected and no credentials leak, while legitimate outbound requests still succeed.