Breachwire.riscent

Breach report

The .env harvest: 90,000 secrets scraped from exposed files, then cloud extortion

PWA & Startup BreachesHigh2024-08
The bottom lineUnit 42 documented an extortion campaign that scanned the internet for publicly exposed .env files, harvested over 90,000 environment variables including cloud, SaaS, and AI keys across 110,000 domains, then used them to break into cloud accounts and extort victims.
Category
PWA & Startup Breaches
Type
Named campaign (mass credential harvesting / extortion)
Date
2024-08
Severity
High
OWASP
Web A05 Security Misconfiguration
CWE / CVE
CWE-538

What happened

Palo Alto Networks' Unit 42 detailed a large-scale extortion operation that hunted for publicly exposed .env files — the plaintext configuration files apps use to hold secrets. The attackers scanned more than 230 million unique targets, hit exposed environment files across 110,000 domains, and extracted over 90,000 unique environment variables, of which about 7,000 belonged to cloud services and 1,515 to social-media platforms. Using the harvested cloud provider access keys, SaaS API keys, and database logins, they gained initial AWS access, exfiltrated data, deleted storage objects, and left ransom notes in the victims' own cloud storage containers.

Root cause

.env files are meant to stay on the server, never web-served. But many deployments place them inside a public web root or ship them with the frontend, so a request for /.env returns the secrets verbatim (CWE-538, exposure of information through a sent file). This is a signature failure of quickly-built and vibe-coded apps: the app runs because the secrets load, but nobody checks whether https://site/.env is reachable. One exposed file hands an attacker the keys to the entire cloud account.

How it would have been caught

A deploy-time check that requests /.env (and common secret paths) against the live site and asserts a 404/403, not the file contents, flips red the instant a build exposes it. A repository check that ensures .env is git-ignored and never bundled catches the source-side leak. The reproduction is one HTTP GET returning readable environment variables.

How to prevent it

  • Keep .env out of the web root and out of version control; serve nothing that returns secret files. Block dotfiles at the web server/CDN.
  • Load secrets from a secrets manager or the platform's environment injection, not a file shipped alongside the app.
  • Rotate any credential that has ever been web-reachable, and scope cloud keys to least privilege so one leak isn't total.

The Breachwire test (red → green)

Request /.env (and /.git/config, /config.json) against the deployed site and confirm it returns real credential values — the RED proof the secrets are internet-reachable. Move secrets out of the web root into injected environment/secret storage and block dotfile serving, then confirm the same requests return 404/403 with no secret content, and rotate the previously exposed keys.