AWS Security7 min read

    Anatomy of a Real AWS Breach: Capital One, 2019

    Tarek Cheikh

    Founder & AWS Cloud Architect

    On July 29, 2019, Capital One announced that a former Amazon Web Services engineer had accessed personal information belonging to approximately 100 million people in the United States and approximately 6 million in Canada, one of the largest data breaches ever tied to a single cloud misconfiguration. The unauthorized access itself had happened months earlier, on March 22 and 23, 2019. It was only surfaced when an external researcher reported it through Capital One's responsible disclosure program on July 17, and the company confirmed the incident on July 19.

    This is worth studying in detail because it isn't a story about a sophisticated zero-day. Every step in the chain is a well-understood AWS misconfiguration class, still common today, and every step is individually preventable with a specific, checkable control.

    What Was Actually Compromised

    Per Capital One's own public statements, no credit card account numbers or login credentials were compromised, and over 99% of Social Security numbers were not exposed. What was accessed was the largest category of information Capital One held on consumers and small businesses who had applied for credit card products between 2005 and early 2019: names, addresses, zip and postal codes, phone numbers, email addresses, dates of birth, and self-reported income.

    The Attack Chain, Step by Step

    1. A Misconfigured Web Application Firewall

    The entry point was a misconfigured web application firewall (a ModSecurity WAF) running on an EC2 instance in front of one of Capital One's applications. The misconfiguration allowed a Server-Side Request Forgery (SSRF) attack: the attacker could get the WAF to make requests on their behalf to internal AWS infrastructure it should never have been able to reach.

    2. An Unauthenticated Metadata Service

    The SSRF was pointed at http://169.254.169.254, the EC2 Instance Metadata Service (IMDS). At the time, Capital One's instance was using IMDSv1, the original version of this service, which answers simple HTTP requests with no authentication at all. Querying /iam/security-credentials/ on IMDSv1 hands back the live temporary credentials for whatever IAM role is attached to the instance, to anyone who can reach it. That's exactly what the SSRF let the attacker do.

    3. An Over-Privileged IAM Role

    The credentials retrieved belonged to an IAM role with far broader permissions than the WAF instance actually needed, including the ability to list and read from a large number of S3 buckets across the account. This is the step that turned a server-side request forgery bug into a data breach of this scale: the role wasn't scoped to only the resources that specific application required.

    4. Mass S3 Access

    With those temporary credentials in hand, the attacker enumerated and pulled data from more than 700 S3 buckets, the volume that produced the eventual exposure of roughly 100 million people in the US and 6 million in Canada.

    The Specific Checks That Would Have Caught This

    Every link in this chain maps to a distinct, well-known, checkable control:

    • IMDSv2 enforcement. AWS's newer metadata service version requires a session token obtained via a PUT request before any credential can be read, which a basic SSRF payload can't easily replicate. Enforcing IMDSv2 (and disabling IMDSv1 entirely) closes this specific path outright.
    • Least-privilege IAM roles. An instance role scoped only to the exact S3 prefixes and actions that specific application needs turns "read 700 buckets" into "read nothing useful," even if credentials are somehow still exposed.
    • WAF and network configuration review. The root misconfiguration was catchable through a straightforward review of the WAF's own request-handling rules, before it ever became an SSRF vector.
    • Anomalous access pattern detection. A role that normally touches a handful of buckets suddenly enumerating and reading from 700+ is a detectable behavioral anomaly, not just a policy problem.

    None of these are exotic. They're the same class of checks a continuous cloud posture scan runs by default, IAM policy scope, IMDS version enforcement, S3 access patterns, checked continuously rather than discovered by an external researcher months after the fact.

    Sources: the dates, scope, and affected-data figures above come from Capital One's own official press release and investor disclosure (July 29, 2019) and its published incident FAQ. Capital One's own statements describe only "a specific configuration vulnerability" exploited by "a highly sophisticated individual," they don't themselves detail the WAF, SSRF, IMDS, or IAM mechanics. The technical attack-chain breakdown above is sourced from the US Department of Justice's criminal complaint in United States v. Paige A. Thompson and independent technical analysis published by Appsecco.

    Go Deeper: The State of AWS Security 2026

    This article is just the start. Get the full picture with our free whitepaper - 8 chapters covering IAM, S3, VPC, monitoring, agentic AI security, compliance, and a prioritized action plan with 50+ CLI commands.

    AWS SecurityIAMS3 SecuritySSRFIMDSv2Case StudyCSPM

    KloudSec, built by the team behind Toc Consulting

    See AWS Security checked automatically, continuously

    What you just read is a manual, one-time check. KloudSec runs this and 400+ more automated checks across 90+ AWS services, continuously, agentless, live in about 5 minutes.

    Try KloudSec free

    Toc Consulting: AWS Security & Cloud Architecture

    Want expert help with AWS Security?

    Our team helps engineering teams secure and architect AWS the right way: assessment in week one, a prioritized action plan in week two.