What happens when your .env file is publicly accessible
A .env file ends up publicly accessible through one of three pathways. The most common is an accidental git commit: a developer adds a key to a local .env file, forgets to check .gitignore, and runs git add .— the file is now in the repository's history permanently, even if they delete it in the next commit. The second pathway is deployment into a public/ directory: some hosting configurations or build scripts copy files into the static assets folder, and a misconfigured build step can pull .env into public/.env, where it is served as a static file at a predictable URL. The third is a misconfigured web server: Nginx or Apache serving a directory without proper file-type restrictions will serve any file it can read, including dotfiles, if someone requests them directly by URL.
What is inside a typical .env file for an AI-built app determines the blast radius of its exposure. At minimum, it contains a database connection string with embedded credentials — full read and write access to your database. It almost certainly contains third-party API keys: Stripe for payments (which means an attacker can create charges, issue refunds, or read your customer list), OpenAI or Anthropic for AI features (which means an attacker can run queries at your expense until your billing limit is hit), and Resend or SendGrid for email (which means an attacker can send arbitrary email from your domain). It likely contains a Supabase service role key, an auth signing secret that allows forging user sessions, and possibly a webhook signing secret. Each of these keys gives an attacker a different set of capabilities — and they have all of them at once when they get the full file.
The window between exposure and exploitation is measured in minutes, not days. Automated scanners run continuously against GitHub, against known hosting platforms, and against common URL patterns. The paths /.env, /.env.local, /.env.production, /.env.backup, and dozens of variations are probed constantly by bots that have no target in mind — they simply scan everything they can find and collect whatever credentials they encounter. These credentials are then either used immediately (OpenAI keys for running inference, Stripe keys for creating charges) or sold in bulk on credential markets. By the time you notice unusual activity in your billing dashboard, the key has often been in circulation for hours.
The real-world blast radius of a leaked Stripe secret key is a maxed billing account and potentially chargeback liability. The blast radius of a leaked Supabase service role key is every row in every table in your database — readable, modifiable, and deletable with no authentication required. The blast radius of a leaked authentication signing secret is that an attacker can forge valid session tokens for any user, including administrators, and log into your app as any account they choose. A leaked OpenAI API key typically results in thousands of dollars in charges within hours, because the keys are used to run inference at scale. These are not theoretical worst cases — they are the documented outcomes of incidents that happen regularly.
To check whether your .env file is currently exposed, run a curl request against your own domain: curl -I https://yourdomain.com/.env. A 200 response is a critical finding that requires immediate action. Also check /.env.local, /.env.production, and /.env.backup. For repository exposure, search your git history with git log --all --full-history -- ".env" to see if the file was ever committed. GitHub Secret Scanning will send you alerts if it detects known key patterns in your public repository.
The fix is layered. Add .env* to your .gitignore immediately and verify it with git check-ignore -v .env. Store all production secrets in your hosting platform's environment variable system — Vercel, Railway, Render, and most others have a secrets management UI that keeps values out of your codebase. Rotate every key that has ever been in a publicly accessible location: generate new keys in each service's dashboard, update your production environment, and confirm the old keys are revoked. If you use GitHub, enable the "Secret scanning" setting in your repository security settings to get automatic alerts when known key patterns appear in future commits.