The 198M-voter S3 leak that still explains most breaches
Most S3 exposure incidents don’t require a zero-day, a phishing email, or
even much skill — just someone who knows how to type an S3 URL into a
browser. In June 2017, UpGuard security researcher Chris Vickery found
exactly that: a bucket named dra-dw — “Deep Root Analytics Data
Warehouse” — sitting fully public on the open internet, no password and no
authentication anywhere in front of it. Inside was 1.1 terabytes of data on
nearly every registered voter in the United States: 198 million records
with names, dates of birth, home addresses, phone numbers, and modeled
ethnicity and religion scores, compiled by contractors working for the
Republican National Committee (Gizmodo, UpGuard). Deep Root Analytics had, in
UpGuard’s account of the incident, simply set the bucket’s permissions to
public instead of private (CyberScoop). That’s a 2017 incident — old
enough that AWS has since shipped several generations of guardrails
specifically built to prevent it — and yet the identical failure mode, a
bucket flipped to public and found by a researcher scanning the internet
rather than by the company that owns it, keeps showing up in breach
reports nearly every year since. That’s the real story here: not one
incident, but a misconfiguration class that refuses to die.
Root cause
S3 buckets are private by default. Getting one exposed takes a deliberate
(if often thoughtless) action, and over a decade of these incidents the
paths to that action have stayed remarkably consistent. Legacy ACLs are
the classic one: S3’s original access-control-list model lets you grant
read or write access to predefined groups, and two of those groups are
routinely confused for “my organization” when they actually mean “the
entire internet” or “any authenticated AWS account on the planet” — not
your customers, not your team, literally anyone with an AWS account.
Bucket policies cause the same damage a different way: a policy meant to
scope access to a specific role or CloudFront distribution gets written
with a wildcard principal ("Principal": "*") or an overly broad condition
that accidentally satisfies for anonymous requests too. And a large share
of real-world exposures trace back to third-party tooling — backup
utilities, data pipelines, static site generators, BI exports — that
defaults to a public bucket because it’s the path of least resistance for
the vendor’s quickstart guide, and nobody revisits the setting once it
works. None of these require malice. They require a permission model with
more than one way to say “public” and no default nudge toward noticing
you’ve done it.
Blast radius
The Deep Root leak wasn’t found by Deep Root. It was found by a
third-party researcher running broad scans for open cloud storage, who
stumbled onto a predictable Amazon subdomain,
dra-dw.s3.amazonaws.com (UpGuard). That’s the pattern across
nearly every S3 exposure story of the last decade — Verizon’s exposed
customer call records via a third-party vendor, Dow Jones’s 2.2 million
subscriber records, Accenture’s exposed API keys and credentials — the
company almost never discovers its own leak. It’s found by a security
researcher, a journalist, or occasionally a criminal, all of whom have the
same tooling: internet-wide bucket-name scanners that turn “is this bucket
public” into a solved, automatable question. Once a bucket is enumerable,
the blast radius is everything in it, immediately, with no exploit chain
required — the exposure is the vulnerability. For Deep Root that meant PII
on 198 million Americans sitting downloadable for at least several days
before Vickery’s report reached the company and the bucket was locked down
(CyberScoop).
Remediation
AWS’s answer to this exact failure mode is S3 Block Public Access,
launched in November 2018 specifically in response to years of incidents
like this one — it’s a set of four switches, settable at the bucket or the
whole-account level, that override any ACL or bucket policy trying to
grant public access, so a misconfigured policy simply can’t take effect
(AWS). As of April 2023, AWS made this the default for every new bucket and
disabled ACLs by default account-wide, which closes off the legacy-ACL
path that caused Deep Root’s leak unless someone deliberately opts back
in. Layer on top of that: IAM Access Analyzer for S3, which
continuously flags buckets reachable from outside your account or
organization, including via cross-account bucket policies that Block
Public Access alone won’t catch; an AWS Config rule
(s3-bucket-public-read-prohibited / s3-bucket-public-write-prohibited)
that continuously evaluates every bucket against the policy you’ve set,
rather than only at creation time; and an SCP at the AWS Organizations
level denying any principal from disabling Block Public Access or
attaching a public bucket policy in the first place, so an individual
account or a rushed engineer can’t quietly opt back into exposure.
Finally, turn on CloudTrail S3 data events (off by default, since
they’re high-volume) for buckets holding anything sensitive — object-level
GetObject logging is what tells you whether an exposure window was ever
actually accessed, versus merely theoretically reachable, which matters
enormously for incident scoping and breach-notification decisions.
The bigger lesson
This misconfiguration has been headline news since at least 2017 — Verizon, Dow Jones, Accenture, WWE, Pentagon contractor INSCOM, and Deep Root Analytics all made the same mistake within about a twelve-month stretch — and it’s still a recurring line item in breach reports today, years after AWS built free, one-click guardrails specifically to stop it. The reason isn’t that the fix is hard; it’s that S3’s original design let “public” be an opt-in property of individual objects and policies, which means it only takes one wrong click, one stale ACL, or one default-public third-party tool to undo. Block Public Access flips that assumption: it makes private the property you have to fight to escape, at the account level, instead of the property you have to remember to defend at the object level. Every org still running without Block Public Access enforced by SCP, without Access Analyzer alerting, and without Config rules gating drift is one misclick away from being next month’s version of this story.
Join the discussion
Comments for this post live on social — reply to the thread.
Related posts
Cloud roundup: macOS Screen Sharing bug now under attack
A patched macOS Screen Sharing flaw is being exploited to plant crypto miners, a Windows Defender bypass has no fix yet, and EC2 gets built-in app health checks.
Cutting NAT gateway costs with VPC endpoints that actually help
How gateway and interface VPC endpoints replace NAT gateway traffic for AWS API calls, what they cost instead, and which traffic still has to go through NAT.
Cloud roundup: S3 finally names the policy that denied you
AWS S3 access-denied errors now name the exact policy ARN, Client VPN gets a scriptable CLI, and OpenAI ships authorized offensive-security models on Bedrock.