JSTGTECH
← Back to blog

The 198M-voter S3 leak that still explains most breaches

4 min read

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.

Related posts