Back to Blog
Cloud Security

The AWS Misconfiguration That Cost Capital One $80 Million

Capital One's breach wasn't a sophisticated attack—it was a simple firewall rule. Here's how to avoid becoming the next headline.

C
CodePhreak Security Team
January 5, 2026
5 min read

The AWS Misconfiguration That Cost Capital One $80 Million

In July 2019, Capital One discovered that 100 million customer records—credit applications, social security numbers, bank account details—were stolen from their AWS infrastructure. The breach made headlines worldwide and resulted in an $80 million fine.

The attack vector? A misconfigured web application firewall.

Not a zero-day exploit. Not advanced persistent threat actors. Not sophisticated malware. A firewall rule that shouldn't have existed.

If you're running infrastructure on AWS and you're not actively scanning for misconfigurations, you're one WAF rule away from being the next headline. Let me show you the mistakes that keep happening and how to catch them before attackers do.

What Actually Happened at Capital One

The breach was elegantly simple:

Step 1: Attacker found a Server-Side Request Forgery (SSRF) vulnerability in Capital One's web application.

Step 2: They exploited SSRF to query the EC2 metadata service:

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

Step 3: The metadata service returned temporary AWS credentials for an IAM role attached to the EC2 instance.

Step 4: That IAM role had overly permissive S3 access. Instead of read-only access to specific buckets, it had s3:ListBucket and s3:GetObject permissions on all S3 buckets.

Step 5: Attacker used those credentials to enumerate and download sensitive data from hundreds of S3 buckets.

The vulnerability was preventable at multiple layers:

  1. Application layer: SSRF vulnerability in web app
  2. Network layer: WAF misconfiguration allowed metadata access
  3. IAM layer: Overly broad permissions on EC2 role
  4. Storage layer: S3 buckets lacked additional access controls

Capital One failed at all four. One success at any layer would have prevented the breach. Instead, the attack sailed through like a hot knife through butter.

The Five AWS Misconfigurations Killing Companies

After analyzing hundreds of cloud breaches and running CSPM scans for dozens of organizations, these five misconfigurations appear again and again:

1. Public S3 Buckets (The Classic)

You'd think after all the headlines, nobody would leave S3 buckets public anymore. You'd be wrong.

The mistake:

# Check if bucket is public
aws s3api get-bucket-acl --bucket my-company-data

{
  "Grants": [
    {
      "Grantee": {
        "Type": "Group",
        "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
      },
      "Permission": "READ"  # ← Anyone on the internet can read this
    }
  ]
}

Real-world impact: In 2023, a healthcare company left patient records in a public S3 bucket for 14 months. They discovered it when security researchers notified them. By then, the data had been scraped by multiple parties. HIPAA violation fine: $4.75 million.

The fix:

# Block public access at bucket level
aws s3api put-public-access-block \
  --bucket my-company-data \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# Enable at account level (recommended)
aws s3control put-public-access-block \
  --account-id 123456789 \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

2. Overprivileged IAM Roles (The Capital One Problem)

Most IAM roles have way more permissions than they need. "We'll tighten them up later" becomes "we'll tighten them up never."

The mistake:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",        // All S3 actions
      "Resource": "*"          // On all resources
    }
  ]
}

This role can read, write, and delete every S3 bucket in your account. Is that really what your web application needs?

The fix (principle of least privilege):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-specific-bucket/uploads/*"
    }
  ]
}

Now the role can only read and write to the uploads/ prefix in one specific bucket. Even if compromised, the blast radius is contained.

3. Security Group "Allow All" Rules

Security groups are AWS's firewall. Too many look like this:

The mistake:

Inbound Rules:
  Type: All Traffic
  Protocol: All
  Port Range: 0-65535
  Source: 0.0.0.0/0  # ← The entire internet

This is the equivalent of "no firewall at all."

Real-world scan results: In a recent CSPM scan of 50 AWS accounts, 34% had at least one security group with 0.0.0.0/0 access on ports beyond 80/443. That's SSH (port 22), RDP (port 3389), and database ports wide open to the internet.

The fix:

# Audit security groups for overly permissive rules
aws ec2 describe-security-groups \
  --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]]'

# Lock down to specific IPs
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 22 \
  --cidr 203.0.113.0/24  # Your office IP range, not 0.0.0.0/0

4. Unencrypted Data at Rest

S3 buckets, EBS volumes, RDS databases—all can be encrypted at rest with one checkbox. Yet many aren't.

The compliance impact:

  • HIPAA requires encryption of ePHI at rest
  • PCI-DSS requires encryption of cardholder data
  • GDPR recommends encryption for personal data
  • SOC 2 Type II auditors will flag unencrypted data

The fix is trivial:

# Enable S3 bucket encryption by default
aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "AES256"
      }
    }]
  }'

# Enable EBS encryption by default (account-level)
aws ec2 enable-ebs-encryption-by-default

Cost of encryption? $0. Performance impact? Negligible. Excuse for not doing it? None.

5. Root Account Without MFA

If you're not using MFA on your AWS root account, you're one phished password away from complete account takeover.

The scary part: In 2023, AWS reported that 23% of root accounts still don't have MFA enabled. These are the accounts with unrestricted access to everything.

The fix (takes 2 minutes):

  1. Log in as root user
  2. Go to Security Credentials
  3. Click "Activate MFA"
  4. Scan QR code with authenticator app
  5. Never use root account again (use IAM users instead)

The 10-Minute AWS Security Audit

Want to know if you're vulnerable? Run these checks:

# 1. Find public S3 buckets
aws s3api list-buckets --query 'Buckets[*].Name' --output text | \
  xargs -I {} aws s3api get-bucket-acl --bucket {} | \
  grep -i "AllUsers"

# 2. Find overly permissive IAM policies
aws iam get-account-authorization-details \
  --filter Policy | jq -r '.Policies[] | 
  select(.PolicyDocument.Statement[].Resource == "*") | .PolicyName'

# 3. Find security groups open to 0.0.0.0/0
aws ec2 describe-security-groups \
  --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].{Name:GroupName,ID:GroupId}'

# 4. Find unencrypted S3 buckets
aws s3api list-buckets --query 'Buckets[*].Name' --output text | \
  xargs -I {} sh -c 'aws s3api get-bucket-encryption --bucket {} 2>/dev/null || echo "Unencrypted: {}"'

# 5. Check root account MFA
aws iam get-account-summary | jq '.SummaryMap.AccountMFAEnabled'

If any of these return results, you have work to do.

How CodePhreak Automates This

Manual AWS audits are tedious and error-prone. CodePhreak automates comprehensive cloud security posture management:

# Comprehensive AWS security scan
codephreak scan cspm --provider aws

# Results include:
# - Public S3 buckets
# - Overprivileged IAM roles/policies  
# - Insecure security groups
# - Unencrypted resources
# - Missing MFA on privileged accounts
# - CloudTrail logging gaps
# - Unused resources (cost optimization)

Output shows not just what's wrong but how to fix it:

❌ CRITICAL: S3 bucket 'customer-data' is publicly readable
   Impact: 47,283 files containing PII accessible to internet
   Fix: aws s3api put-public-access-block --bucket customer-data [...]
   
⚠️  HIGH: IAM role 'web-app-role' has overly broad S3 permissions  
   Current: s3:* on all resources
   Recommended: s3:GetObject on specific bucket only
   Policy diff: [View suggested policy]
   
⚠️  MEDIUM: Security group 'web-sg' allows SSH from 0.0.0.0/0
   Port: 22 (SSH) open to internet
   Fix: Restrict to office IP range or use Systems Manager Session Manager

What You Should Do Today

5 minutes:

  • Check if root account has MFA enabled
  • If not, enable it NOW (seriously, stop reading and do this)

15 minutes:

  • Run the 10-minute security audit commands above
  • Make a list of findings

1 hour:

  • Block public access on ALL S3 buckets (unless explicitly needed)
  • Review top 5 IAM policies for overly broad permissions
  • Lock down security groups to specific IP ranges

This week:

  • Enable encryption by default on S3 and EBS
  • Set up AWS Config to track configuration changes
  • Implement automated CSPM scanning

Don't wait for your Capital One moment. The tools to prevent these breaches are free and available today.

The Uncomfortable Reality

The Capital One breach didn't happen because security is hard. It happened because security wasn't prioritized until it was too late.

Every misconfiguration I listed above:

  • Takes < 5 minutes to fix
  • Costs $0 to implement
  • Has been well-documented for years
  • Still appears in most AWS environments

AWS gives you the tools to secure your infrastructure. Using them is your choice.

The question isn't whether you'll be targeted—it's whether your configurations will withstand the attack when it comes.


Scan Your AWS Infrastructure in 60 Seconds:

# Install CodePhreak
pip install codephreak-security-auditor

# Scan AWS (uses existing credentials)
codephreak scan cspm --provider aws

# Get HTML report with remediation steps
codephreak scan cspm --provider aws --output report.html

Get StartedAWS Security GuideGitHub

Try CodePhreak Security Auditor

Start scanning your code for vulnerabilities today. Free SAST, SCA, and secret detection included.

Get Started Free