Introduction: What Caused the Capital One Data Breach

In July 2019, Capital One disclosed that a hacker had accessed personal information belonging to approximately 100 million people in the United States and about 6 million in Canada. The exposed data included names, addresses, dates of birth, self-reported income, credit scores, credit limits, balances, and, for a smaller subset of victims, roughly 140,000 Social Security numbers and about 80,000 linked bank account numbers.

This was not a sophisticated zero-day attack by a nation-state. It was a cloud misconfiguration, discovered and exploited by a single former Amazon Web Services (AWS) employee. That detail is what makes this incident so valuable to study: the attack path is well documented, technically understandable, and entirely preventable with controls that most mature security programs already claim to have.

This article walks through what happened, why it happened — the root cause — and exactly which controls — mapped to recognized frameworks — would have prevented or limited the damage.

A note on sourcing: the facts below reflect what is publicly known from Capital One’s own 2019 breach disclosure, the US Department of Justice criminal complaint against the individual who carried out the intrusion, and subsequent regulatory action by the Office of the Comptroller of the Currency (OCC). No specific URLs were provided as research inputs for this article, so readers who want primary-source detail should search for Capital One’s official July 2019 press statement, the DOJ case filings related to the intrusion, and the OCC’s 2019 consent order against Capital One.

Timeline of the Capital One Data Breach

Timeline of the Capital One data breach from initial intrusion in March 2019 to disclosure and conviction

March 22–23, 2019 — An individual, later identified as a former AWS software engineer, exploited a misconfigured web application firewall (WAF) protecting a Capital One web application hosted on AWS. The flaw allowed a Server-Side Request Forgery (SSRF) attack, which tricked the WAF into making requests on the attacker’s behalf.

Through the SSRF, the attacker reached the AWS instance metadata service running on the underlying EC2 instance and retrieved temporary security credentials for an IAM role attached to that instance. That role had permissions far broader than the WAF needed to do its job — including the ability to list and read from a large number of Amazon S3 storage buckets.

Using those stolen credentials, the attacker enumerated and downloaded data from more than 700 S3 buckets containing customer data accumulated over several years, including information from credit card applications dating back to 2005.

March–July 2019 — The exfiltrated data sat largely unnoticed. Capital One’s own monitoring did not flag the activity at the time it occurred.

July 17, 2019 — A member of the public emailed Capital One’s responsible disclosure mailbox, alerting the company that data appearing to belong to it had been posted publicly on GitHub.

July 19, 2019 — Capital One’s security team confirmed unauthorized access had occurred and involved the FBI.

July 29, 2019 — The FBI arrested the suspect, and Capital One publicly disclosed the breach the same day, detailing the scope of affected customers and the nature of the exposed data.

Later proceedings — The individual was charged with wire fraud and computer fraud and abuse offenses and was convicted in 2022. Capital One separately reached an $80 million settlement with the OCC and a $190 million class-action settlement with affected customers.

Root Cause Analysis: Why the Capital One Breach Happened

The breach is best understood as a chain of smaller failures rather than one single flaw. Each link in the chain was necessary for the breach to succeed; removing any one of them would have broken the attack.

Flow diagram of the root cause chain in the Capital One breach from WAF misconfiguration to S3 data exfiltration

1. A Misconfigured WAF Enabled the SSRF Attack

The WAF sitting in front of a Capital One web application was configured in a way that allowed it to be coerced into making outbound requests to arbitrary destinations, including internal AWS infrastructure endpoints. This is the technical definition of an SSRF vulnerability: the attacker doesn’t connect directly to the internal resource, they get a trusted service to do it for them.

2. The AWS Instance Metadata Service Was Reachable and Unprotected

AWS EC2 instances expose a local metadata service (traditionally reachable at 169.254.169.254) that provides temporary IAM credentials to applications running on the instance, so they don’t need hardcoded secrets. At the time of this breach, the original version of this service (IMDSv1) accepted simple HTTP GET requests with no mandatory session token. An SSRF flaw that can reach this address can retrieve live, usable AWS credentials.

3. Excessive IAM Permissions Violated Least Privilege

This is arguably the most consequential failure. The credentials retrieved via the metadata service belonged to an IAM role with permissions well beyond what a WAF needs. It could list and read from a very large number of S3 buckets across the environment — a textbook violation of least privilege. A narrowly scoped role would have limited the blast radius even if the SSRF and metadata exposure both existed.

4. Insufficient Detection of Anomalous Data Access

Tens of millions of records were read and exfiltrated from storage over a period of time without triggering an alert that led to timely action. Effective logging and anomaly detection on S3 access patterns, API call volume, and data egress should have surfaced unusual ListBuckets and GetObject activity from a single role well before an external tipster had to notify the company.

5. Process and Governance Gaps Around Cloud Migration

Capital One was in the midst of a large-scale migration from on-premises data centers to AWS. Public regulatory findings pointed to gaps in the risk assessment and change-management processes that should have accompanied that migration — specifically, that security controls, firewall configuration reviews, and monitoring did not keep pace with the speed of cloud adoption. Migrating fast without correspondingly maturing cloud-specific security practices created the conditions for this failure.

This incident sits alongside other well-documented cases in our Lessons Learned series, including the Equifax 2017 breach, where a single unpatched component led to comparable exposure at scale — a useful comparison for any team building a root-cause review process.

Controls That Would Have Prevented or Limited the Breach

Each control below maps to a widely recognized framework and includes concrete implementation steps. Organizations formalizing these controls often align them to the NIST Cybersecurity Framework 2.0 implementation, which provides a maturity roadmap across Identify, Protect, Detect, Respond, and Recover functions.

Enforce IMDSv2 and restrict metadata access (CIS Control 4 – Secure Configuration; NIST CSF PR.PT)

AWS’s IMDSv2 requires a session token obtained via a PUT request before any metadata can be retrieved, which defeats simple SSRF-based credential theft.

Implementation steps:

  • Set the HttpTokens parameter to required on all EC2 instances to enforce IMDSv2 only.
  • Set a metadata hop limit (HttpPutResponseHopLimit) low enough to prevent requests from traversing proxies like a WAF.
  • Use AWS Config rules or a cloud security posture management (CSPM) tool to continuously detect and alert on any instance still allowing IMDSv1.

Apply least privilege to IAM roles (CIS Control 6 – Access Control Management; NIST CSF PR.AC)

No service should hold broader permissions than its function requires. Teams building or maintaining AWS environments benefit from structured AWS Security Training to ensure IAM, networking, and monitoring configurations are reviewed by people who understand the shared responsibility model in depth.

Implementation steps:

  • Scope IAM policies attached to infrastructure components (WAFs, proxies, application servers) to the specific S3 buckets, prefixes, and actions they actually need — never wildcard s3:* on Resource: *.
  • Use IAM Access Analyzer to identify roles with unused or overly broad permissions.
  • Require periodic (at minimum quarterly) access reviews for any role that can read production data stores.

Harden and continuously test WAF configuration (CIS Control 4; OWASP SSRF Prevention guidance)

A WAF is a control that itself needs configuration management and testing, not a "set and forget" appliance.

Implementation steps:

  • Apply SSRF-specific protections: block or strictly validate any server-side functionality that fetches URLs on behalf of a user or upstream request, and explicitly deny requests targeting link-local addresses such as 169.254.169.254.
  • Include SSRF test cases in regular penetration tests and in the WAF rule-change approval process.
  • Treat WAF rule changes like any other production change: peer review, staged rollout, and rollback plan.

Deploy continuous monitoring and anomaly detection on data access (CIS Control 8 – Audit Log Management; NIST CSF DE.CM)

The exfiltration generated detectable signal that went unnoticed for months. Pairing this monitoring with a regular internal vulnerability assessment helps confirm that S3 bucket permissions, IAM roles, and WAF rules haven’t drifted from policy between audit cycles.

Implementation steps:

  • Enable AWS CloudTrail for all accounts and S3 server access logging (or S3 data event logging in CloudTrail) on buckets containing sensitive data.
  • Enable Amazon GuardDuty, which specifically detects anomalous API behavior, including unusual ListBuckets and GetObject patterns, and instance credential exfiltration indicators.
  • Set alert thresholds for abnormal volume or velocity of data reads from a single role or principal, with a defined escalation path to a human analyst within a committed timeframe.

Govern cloud migration with formal risk assessment and change management (ISO 27001 Annex A.8/A.12; NIST CSF ID.RA, PR.IP)

Speed of adoption cannot outpace the maturity of the controls protecting what’s being adopted.

Implementation steps:

  • Require a documented security risk assessment before any new cloud workload handling sensitive data goes live, including explicit sign-off on IAM role scope and network exposure.
  • Maintain an inventory of all internet-facing services and the data stores they can reach, reviewed at a fixed cadence.
  • Establish a formal change advisory process for security-relevant infrastructure (WAF rules, IAM policies, network ACLs) with mandatory peer review.

Common Mistakes Organizations Still Make

  • Treating the WAF as a "deploy and forget" control. Many teams install a WAF, declare the compliance box checked, and never revisit its rule set as applications change.
  • Granting broad IAM permissions for convenience during development, then never tightening them before or after production launch.
  • Leaving IMDSv1 enabled on EC2 fleets years after IMDSv2 became available, often because legacy applications were never updated to use the token-based flow.
  • Under-investing in detection for data stores, focusing monitoring budget on network perimeter alerts while bulk reads from cloud storage go unreviewed.
  • No SSRF testing in routine penetration tests, even though SSRF has been a recognized top-tier web application risk for years.
  • Assuming cloud providers "handle security" for anything beyond the infrastructure layer, when configuration of IAM, storage permissions, and network exposure remains squarely the customer’s responsibility under the shared responsibility model.
  • No tested path for external vulnerability reports. Capital One’s responsible disclosure mailbox is actually what surfaced this breach — organizations that don’t have a monitored, responsive channel for this kind of tip lose valuable early detection.

For banks and other regulated institutions, the stakes are especially high — the controls above are foundational to any banking and financial services cybersecurity program operating in the GCC or globally.

Conclusion: A Checklist You Can Apply This Week

  1. Check whether any EC2 instances in your environment still allow IMDSv1; if so, migrate them to IMDSv2-only this week.
  2. Pull the IAM policy attached to every internet-facing component (WAF, reverse proxy, API gateway) and confirm it follows least privilege — no wildcard S3 or broad read access "just in case."
  3. Confirm CloudTrail and S3 access logging are enabled on every bucket holding customer or financial data, and that GuardDuty (or an equivalent anomaly detection tool) is active and alerting to a monitored channel.
  4. Add SSRF test cases to your next penetration test scope, specifically targeting any service that fetches or proxies URLs.
  5. Verify your organization has a monitored, documented responsible disclosure channel, and that a report sent to it today would reach someone who can act within hours, not weeks.
  6. Schedule a review of WAF rule changes made in the last 12 months — confirm each went through peer review and testing, not just a quick production push.

Free Resources

Chat WhatsApp
+971501254773