Uber — a breach and its cover-up
This is a real, named breach, and it's really two failures stacked on top of each other. In late 2016, two attackers found AWS credentials sitting in a private GitHub repository used by Uber's engineers, and used them to pull down personal data on 57 million riders and drivers — a secrets-management failure, and not even a novel one for Uber, which had suffered an almost identical GitHub-credential exposure two years earlier. What makes this case study belong in a DevSecOps course rather than just a breach-notification archive is what happened next: Uber's own security leadership paid the attackers $100,000, disguised the payment as a bug-bounty payout, made them sign non-disclosure agreements, and concealed the whole incident from regulators and the public for more than a year — while an earlier Uber data-security case was actively being negotiated with the U.S. Federal Trade Commission. The technical failure cost Uber a scanner it didn't run. The cover-up cost Uber's Chief Security Officer a federal criminal conviction.
Imagine you break a lamp at a friend's house. Instead of telling anyone, you pay the one person who saw it happen to keep quiet, and you even make them sign a note saying "nothing happened here." A year later, a new babysitter is cleaning the closet for a totally different reason and finds the broken lamp pieces stuffed in a bag. Now there are two problems: the broken lamp, which was an accident, and the note and the payoff, which weren't. Grown-ups — and courts — treat those two problems very differently, and the second one is usually worse.
The backdrop: a company that had already been burned by this exact mistake
☺ Like you're 10: This wasn't Uber's first time losing data because a secret key ended up somewhere it shouldn't have — it was the second time, using almost the same trick.
In September 2014, Uber discovered — during a routine internal audit, not through any attacker's tip — that an unauthorized party had accessed a database containing the names and driver's-license numbers of roughly 50,000 drivers. The access traced back to May 2014, and the root cause was mundane: an access key one of Uber's own engineers had used had ended up posted on GitHub, reachable by anyone who found it. Uber disclosed this publicly in February 2015. The U.S. Federal Trade Commission opened an investigation into Uber's data-security practices as a result, alleging in its eventual complaint that Uber had failed to reasonably secure sensitive rider and driver data and had overstated how closely it monitored employee access to that data. Uber and the FTC were still working through that case — it wasn't finalized until August 2017 — when the events on this page took place.
Hold that timeline in mind for everything that follows: the exact anti-pattern that caused the 2014 breach — a credential that belonged in a secrets manager instead ending up somewhere a repository could expose it — is the same anti-pattern that caused the much larger 2016 breach. Between the two incidents, Uber didn't close the gap; it just got unlucky in a bigger way the second time, while a federal regulator was already watching.
Link one: AWS credentials committed to a private GitHub repository
☺ Like you're 10: The key to a huge storage room was typed right into a file, and the file was kept somewhere people who shouldn't have had it eventually got in and found it.
Sometime around October 2016, two attackers — later identified in U.S. Department of Justice filings as Brandon Charles Glover and Vasile Mereacre — gained access to a private GitHub repository used by Uber's software engineers. Public reporting has never fully detailed exactly how the two got into that private repository in the first place; what is well documented, from Bloomberg's original 2017 reporting and the subsequent DOJ complaint against the pair, is what they found once inside: working AWS access credentials, hardcoded into the code rather than pulled from a secrets manager at runtime. Those credentials gave them a path to an Amazon Web Services account Uber used for backend data storage.
The shape of the anti-pattern — illustrative of what gets described in the public record, not a literal reproduction of Uber's actual repository contents — looks like this, and it's a pattern this course covers directly on secrets management and Static Analysis & Secrets Detection:
# A credential committed straight into application config, instead of fetched
# at runtime from a secrets manager — this is the shape of the anti-pattern,
# not a reproduction of Uber's actual file:
grep -rn "AWS_SECRET" .
config/production.rb:12: AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE"
config/production.rb:13: AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# Once an attacker has that pair, it doesn't matter that the repo was "private" —
# a live key is a live key, usable from any machine on the internet:
aws configure set aws_access_key_id AKIAIOSFODNN7EXAMPLE
aws configure set aws_secret_access_key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws s3 ls # enumerate whatever this key can reach
aws s3 sync s3:// ./loot Two things about this deserve emphasis. First, "private repository" is doing no real security work here — access control on the repo is a perimeter around the code, not around the secret embedded inside it, and once anyone with legitimate or stolen access can read the file, the credential is exposed to whatever that access lets through. Second, a pre-commit or pipeline-stage secrets scanner — gitleaks or TruffleHog are the two this course teaches directly — is built to catch precisely this pattern automatically, on every commit, whether the repository is public or private. Nothing about "private" makes a hardcoded key safe to skip scanning for.
It's tempting to read the 2014 breach (public GitHub) and the 2016 breach (private GitHub) as two different failure classes. They're the same failure class. A secret's exposure is bounded by everyone who can ever read the file it's in — across the repo's whole history, every engineer with access, every integration with read access, every future access-control mistake — not by whether the repository's visibility toggle currently says "public" or "private." The fix in both cases is the same: the secret shouldn't have been in a file under version control at all. See HashiCorp Vault for what "fetched at runtime instead" actually looks like in practice.
Link two: what those credentials reached — 57 million records, 600,000 license numbers
☺ Like you're 10: The stolen key didn't open one drawer — it opened the room where a huge share of the company's rider and driver information was kept.
Using the stolen credentials, Glover and Mereacre pulled data covering 57 million Uber users worldwide — riders and drivers combined — and, for a subset of roughly 600,000 U.S.-based drivers, something more sensitive still.
| What was exposed | Scope |
|---|---|
| Names, email addresses, and mobile phone numbers | ~57 million riders and drivers worldwide |
| Names and U.S. driver's-license numbers | ~600,000 U.S.-based Uber drivers |
| Social Security numbers, credit card numbers, bank account details, trip location or GPS history | According to Uber's own public statement, none of this was taken |
That last row matters for an accurate account of the incident: Uber's November 2017 public disclosure was specific that no Social Security numbers, credit card numbers, bank account information, or precise trip-location data were downloaded. This wasn't the maximally catastrophic version of an Uber data breach — no financial-account takeover risk, no continuous location-tracking exposure. It was still 57 million people's contact information and 600,000 people's government ID numbers, reachable because one set of AWS credentials shouldn't have existed outside a secrets manager in the first place.
The choice that turned an incident into a felony case: paying and concealing
☺ Like you're 10: Getting hacked is bad luck. Paying the hackers, lying about what happened, and hiding it from the people whose job is to check on exactly this kind of thing is a decision — and decisions have consequences bad luck doesn't.
Once Glover and Mereacre had the data, they contacted Uber directly and demanded payment to delete it and stay quiet — extortion, not a good-faith vulnerability disclosure. Uber's response was directed by its then Chief Security Officer, Joe Sullivan, a former federal prosecutor who had previously served as Facebook's first CSO. Sullivan's team arranged a $100,000 payment to the two attackers, routed through Uber's own HackerOne-hosted bug-bounty program so that, on paper, it resembled a routine maximum-tier bounty payout rather than what it actually was: money paid to make an active extortion attempt go away. As a condition of payment, the attackers were required to sign non-disclosure agreements that identified them in terms consistent with legitimate security researchers and included representations that no data had been taken or misused — statements that, per the subsequent DOJ complaint, were not true.
Uber did not disclose the breach to affected riders and drivers. It did not disclose it to state regulators, most of whom have laws requiring notification of exactly this kind of incident within a defined window. And — this is the detail that turned the story from "a bad breach response" into "a federal case" — it did not disclose it to the FTC, which was, at that exact moment, actively negotiating the consent order stemming from Uber's 2014 breach. According to the DOJ's later complaint against Sullivan, he had briefed the FTC on Uber's data-security practices only about ten days before learning of this new intrusion, and never went back to correct or update that testimony once he knew it no longer reflected reality.
Paying an extortionist is not, by itself, what created Uber's and Sullivan's legal exposure — organizations make ransom-payment decisions, however uncomfortable, under real-world pressure, and reasonable people disagree about when that's defensible. What created the exposure was disguising the payment, extracting false statements from the attackers, and withholding the truth from a regulator that was actively relying on Uber's representations to decide how to resolve an open case. The lie to the regulator, not the payment itself, is what a federal jury ultimately convicted on.
It's tempting to read this as one security executive making one bad call under pressure. Uber's own subsequent actions treat it as broader than that: when the concealment came to light, the company didn't just part ways with Sullivan — it also terminated Craig Clark, an in-house attorney who had been involved in structuring the response. A decision this consequential passed through more than one person's judgment on its way to "pay, sign NDAs, and say nothing" — which is exactly the kind of decision an organization needs an escalation path and a security-culture norm to interrupt, not just a policy that assumes any one individual will refuse on their own. See security culture & champions for what that escalation path is supposed to look like before a moment like this arrives.
Where the chain could have broken — mapped to this course
☺ Like you're 10: Five weak spots, five different fixes — and unlike a lot of breaches, this one has two completely separate categories of fix, not just one.
| Link | What actually happened | The control that breaks it | Covered on this site |
|---|---|---|---|
| 1. Credentials hardcoded in a repo | Working AWS access keys were committed into application code instead of pulled from a secrets manager at runtime | Centralized secrets management with short-lived, dynamically issued credentials — nothing long-lived to leave lying in a file | Secrets Management, HashiCorp Vault |
| 2. No automated scan caught it | Neither the 2014 nor the 2016 exposure was caught by an automated check before an outsider found it | Pre-commit and pipeline-stage secrets scanning that blocks a commit containing a credential pattern, run identically on every repo regardless of visibility | Static Analysis & Secrets Detection, gitleaks, TruffleHog |
| 3. One key reached a huge dataset | The compromised credential's access wasn't scoped to what the specific workload actually needed | Least-privilege IAM scoping, so a single leaked key's blast radius is a fraction of the data estate, not most of it | Workload Identity & Pipeline IAM |
| 4. The response was pay-and-hide, not investigate-and-disclose | Security leadership disguised an extortion payment as a bug bounty and extracted false NDAs instead of running a real incident-response process | A documented, rehearsed incident-response runbook with legal and compliance built in from the first hour — not improvised by whoever's closest to the decision | Incident Response & Forensics, Drill — Leaked Credential Triage |
| 5. Regulators and users learned over a year late | An active FTC matter and every applicable state breach-notification law went unmet for more than a year | Breach-notification obligations treated as a compliance control with defined deadlines and named owners, not a discretionary call made under pressure | Compliance & Governance |
The unraveling: a new CEO's audit, and a year-late disclosure
☺ Like you're 10: Nobody caught this because they were looking for it — a brand-new boss found it while cleaning up a completely different mess.
Travis Kalanick stepped down as Uber's CEO in June 2017, under pressure from investors over a string of unrelated controversies about Uber's workplace culture and business practices. Dara Khosrowshahi took over as CEO in August 2017. Within roughly three months of starting, and in the course of a broader review of Uber's outstanding legal and security issues, Khosrowshahi learned about the concealed 2016 breach. He ordered an investigation, terminated Sullivan and Clark, and disclosed the incident publicly in a company blog post on November 21, 2017 — more than a year after the intrusion itself.
Worth sitting with: the breach was not caught by a control. It was not caught by an audit process at Uber. It surfaced because leadership changed and the new leader's routine due diligence happened to turn it up. That's a genuinely fragile way for a concealed incident to eventually come to light, and it's a large part of why regulators treated the concealment itself as the more serious governance failure once they saw it.
The aftermath: the largest multistate breach settlement of its time, an amended FTC order, and a criminal conviction
☺ Like you're 10: The company paid a record-setting fine, the deal with the regulator got tougher, and — for the first time ever — a company's own top security person went to court and lost.
The consequences that followed track the same split as everything else in this case: one set for the underlying breach, and a much larger set for how it was handled.
| Consequence | What it was for |
|---|---|
| $148 million multistate settlement (September 2018), then the largest data-breach settlement ever reached with U.S. state regulators | Violations of state data-breach notification laws — the concealment, not the intrusion itself — resolved with all 50 states and Washington, D.C. |
| An amended, expanded FTC settlement (April 2018) | The FTC reopened its 2017 settlement after learning Uber had concealed the 2016 breach throughout the negotiation of that original case, adding requirements including independent, recurring assessments of Uber's data-security program |
| Criminal conviction of Joe Sullivan (October 2022) | Obstructing an FTC proceeding and misprision of a felony — a federal jury convicted Uber's former CSO on both counts, believed to be the first criminal conviction of a corporate security executive over how a breach was handled |
| Sullivan's sentence (May 2023) | Three years of probation and 200 hours of community service — no prison time; report current terms directly from primary sources if citing this for anything beyond a teaching example |
| Guilty pleas from Glover and Mereacre (October 2019) | Extortion conspiracy, covering both the Uber intrusion and a similar attack the same pair carried out against LinkedIn's Lynda.com platform |
Treat every dollar figure and every legal outcome above as the headline version of a real, still-referenced set of cases — as with any actively cited legal matter, verify current status directly from primary sources before relying on specifics for anything beyond a teaching example.
What doesn't transfer
☺ Like you're 10: A few things about this story are specific to exactly how it played out, and shouldn't be copied blindly into how you read it.
- Sullivan's conviction wasn't "any executive who mishandles a breach goes to prison." The specific facts mattered a great deal: an active FTC proceeding Uber was already party to, testimony given days before the new breach and never corrected, and false representations extracted from the attackers in writing. A breach handled badly without those specific aggravating facts is a different — and typically civil, not criminal — kind of exposure. Don't read this case as "any bug-bounty payment risks federal prison"; read it as what happens when a payment is deliberately disguised and a regulator is deliberately misled.
- Paying attackers isn't automatically the wrong call, in the abstract. Organizations do sometimes decide, under real pressure and with legal counsel, that payment is the least-bad option in an active extortion situation. What made this indefensible wasn't the payment — it was routing it through a program built for legitimate researchers, extracting false statements, and telling nobody who had a legal right to know.
- Uber didn't invent this failure mode, and didn't even learn from its own first instance of it. The 2014 GitHub-key exposure and the 2016 GitHub-key exposure share a root cause. That repetition is itself a lesson: a secrets-management gap that gets treated as a one-off incident, rather than fixed at the control level, doesn't reliably stay fixed just because it embarrassed the company once already.
- The published figures are the most consistently reported ones, not a live tally. The $148 million multistate figure and the 2022–2023 criminal-case outcomes are well documented as of this writing, but sentencing details, appeals, or additional state actions can move after a page like this is written. Verify current status before citing specifics.
Ellie the Elephant: A working AWS key, sitting in a file, in a repo — I don't care that the repo was marked private. I carry every secret and I never once set one down where a file could hold it instead of me.
Timmy the Turtle: And a scanner would have caught that key on the very commit that introduced it. This isn't a hypothetical control — gitleaks and TruffleHog exist specifically to catch this exact pattern, on every single commit, private repo or not.
Rocky the Raccoon: Here's the part that gets me — this is the second time. Same company, same "a key ended up in GitHub" story, two years apart. I don't need to be clever to find a gap nobody closed the first time.
Foxy: The technical part, sure — that's a bad day. What I can't let go of is the year after. Somebody decided "pay them, make them sign something, and say nothing" was a plan. That's not an incident response. That's a choice, made by people, that a real process should have interrupted.
Professor Owl: Which is exactly why this course treats "what do you do in the first 72 hours" as its own discipline, not an afterthought to the scan. The breach was bad luck compounding a known gap. The cover-up was a decision — and it's the decision that ended up in front of a jury.
Set this next to Capital One's 2019 breach for another case where an ordinary, well-documented control gap did the real damage, and against SolarWinds' supply-chain compromise for a breach where the technical sophistication was genuinely rare rather than routine. This one sits apart from both: the technical failure here was almost boring — a key in a repo, the kind of thing a five-minute pipeline scan catches — and the part that made headlines, cost $148 million, and put a CSO in federal court was entirely a decision about what to do next.
1. What was the root-cause anti-pattern behind both Uber's 2014 and 2016 breaches, and why does "the second repo was private" not actually distinguish the two failures? 2. What specifically did Uber's security team do with the $100,000 payment that turned it from an extortion payoff into a disguised cover-up? 3. Why did concealing the 2016 breach create criminal, not just civil, exposure for Joe Sullivan — what was the specific aggravating fact involving the FTC? 4. Which financial and legal consequence was larger for Uber — the direct cost of the breach itself, or the cost of concealing it — and what does that ordering suggest about where the real risk sat? 5. Name one specific automated control from this course that would have caught the technical failure before any attacker did.
Check your answers
- Both traced to a working access credential ending up somewhere a repository could expose it, instead of being issued dynamically from a secrets manager. "Private" only restricts who can browse the repo through normal access — it does nothing to stop a credential embedded in a file from being usable by anyone who obtains it through any means, including a compromised engineer account or, as in 2014, a repo whose visibility was itself the mistake.
- They routed it through Uber's own bug-bounty program so it would resemble a routine maximum-tier payout rather than an extortion settlement, and required the attackers to sign non-disclosure agreements containing false representations that no data had been taken or misused.
- Sullivan had briefed the FTC on Uber's data-security practices only about ten days before learning of the 2016 breach, as part of an active, ongoing FTC proceeding over the 2014 incident, and never corrected that testimony once it stopped being true — a federal jury convicted him of obstructing that FTC proceeding and of misprision of a felony (concealing a known felony from authorities).
- The cost of concealment was far larger: a $148 million multistate settlement plus an amended, expanded FTC order plus a criminal conviction, versus no comparably large penalty tied to the intrusion itself. The lesson this page keeps returning to: for Uber, mishandling the disclosure was measurably more expensive than the breach it was trying to hide.
- Any of: a pre-commit or pipeline-stage secrets scanner such as gitleaks or TruffleHog, which would have flagged the hardcoded AWS key at commit time regardless of the repository's visibility; or centralized secrets management (for example, HashiCorp Vault) issuing short-lived credentials at runtime instead of a long-lived key ever existing in a file to leak.