IBM's Cost of a Data Breach Report 2024 found that cloud misconfiguration was the initial attack vector in 15% of breaches — statistically tied with phishing, and just one point behind stolen or compromised credentials at 16%. That figure has held roughly steady for years because the underlying mistakes are structural, not exotic: a storage bucket left public, an IAM role handed Action: *, a database provisioned without encryption, a security group opened to 0.0.0.0/0. The 2019 Capital One breach remains the clearest illustration of how these compound — a misconfigured WAF running on EC2 let attacker Paige Thompson issue server-side request forgery calls to the instance metadata service, which handed back temporary credentials for an over-privileged IAM role (ISRM-WAF-Role). Those credentials let her list and read more than 700 S3 buckets, exfiltrating roughly 106 million customer records. No zero-day was involved; every step exploited a configuration choice someone had already made. This post catalogs the six misconfiguration classes that show up most often in cloud environments, with the concrete queries and checks that surface each one before an attacker finds it first.
Why do public storage buckets keep happening?
Public buckets keep happening because cloud storage defaults have shifted over time, legacy buckets predate the safer defaults, and bucket policies are additive — a single overly broad statement can override tighter ACLs elsewhere. AWS made S3 "Block Public Access" the account-wide default for newly created buckets, and Google Cloud Storage similarly discourages allUsers/allAuthenticatedUsers IAM bindings, but neither retroactively locks down buckets created years earlier under looser defaults. The Capital One incident's actual data-access step was a public-storage failure in miniature: the compromised role could list and read buckets across the account rather than being scoped to the one workload it served. A detection query for this pattern checks, per bucket, whether public-access-block settings are disabled, whether the bucket policy contains a Principal: "*" statement without a matching Condition, and whether object ACLs grant AllUsers read — for example, an AWS Config rule query filtering s3-bucket-public-read-prohibited to NON_COMPLIANT, or an Access Analyzer for S3 finding with isPublic: true.
What makes over-permissive IAM roles so common?
Over-permissive IAM roles are common because wildcard policies are the path of least resistance during development, and almost nothing forces a team to tighten them once the workload ships. It's faster to attach "Action": "*" and "Resource": "*" to a new service role than to enumerate the six S3 actions and two DynamoDB actions it actually needs, and unless a review process catches it, that policy ships to production unchanged. The Capital One WAF role was over-provisioned in exactly this way: it had permissions far beyond what a web application firewall needs, which is why a single SSRF flaw turned into account-wide bucket access instead of a contained failure. A detection query here evaluates each role's attached and inline policies for statements combining a wildcard Action with a wildcard Resource and no Condition block, then cross-references CloudTrail's Event history (or an equivalent access-advisor report) for the same role's actually-used actions over the trailing 90 days — the gap between "granted" and "used" is the excess to trim.
How often is unencrypted data actually the root cause?
Unencrypted data is rarely the sole root cause of a breach, but it is consistently what turns a contained access failure into a disclosure event — Capital One's post-incident analyses specifically cited ineffective encryption on the exposed S3 data as one of the compounding failures alongside the metadata-service exposure and the over-provisioned role. A bucket or database that enforces server-side encryption doesn't stop an over-permissive role from reading it, but encryption-at-rest combined with strict key policies (requiring a specific KMS key and denying default AWS-managed keys) adds a second control an attacker must also defeat, and it's a control most CSPM and cloud-provider benchmarks — including the CIS AWS Foundations Benchmark — treat as a baseline requirement rather than optional hardening. A detection query flags S3 buckets without default encryption enabled, RDS instances with StorageEncrypted: false, and EBS volumes created before account-level default encryption was turned on; AWS Config's s3-bucket-server-side-encryption-enabled and rds-storage-encrypted managed rules cover both directly.
Why do open security groups and exposed metadata services persist?
Open security groups persist because 0.0.0.0/0 is the fastest way to unblock a developer during setup, and exposed instance-metadata services persist because IMDSv1 shipped as the default for years before AWS introduced IMDSv2's session-oriented, token-based hardening in 2019 specifically in response to SSRF-style abuse like Capital One's. A security group rule allowing inbound traffic from anywhere on port 22, 3389, or a database port is trivial to write and easy to forget about once the immediate need passes. A detection query for the first case lists every security group ingress rule with a CidrIp of 0.0.0.0/0 on a non-web port; for the second, it enumerates EC2 instances where the MetadataOptions.HttpTokens field is optional rather than required — the setting that determines whether IMDSv1's unauthenticated, non-token requests are still accepted at all.
How does Safeguard help surface these misconfigurations?
Safeguard's Data Security Posture Management (DSPM) connects directly to Amazon S3 and RDS to record exactly the posture signals this post covers — encryption status and public exposure, including access controls, public-access settings, bucket policy, storage encryption, and network accessibility — without ever storing the raw sensitive data it discovers in those stores. DSPM's exposure detection specifically flags stores that are public, unencrypted, over-shared, or reachable across a tenant, region, or account boundary, and fuses that with CIEM effective-permissions data so a finding names not just "this bucket is public" but which identities — including any external principal — actually have a path to it. Because a public, unencrypted store holding sensitive data ranks far above a private, encrypted, low-sensitivity one, teams get the same prioritization signal that would have flagged the Capital One pattern: an over-privileged role with a reachable, exposed path to a lot of data, ranked at the top instead of buried in a scan of thousands of findings.