TL;DR
- Researchers found over 12 million publicly accessible .env files exposing database passwords, API keys, and cloud credentials.
- The most common causes are misconfigured web servers, accidental git commits, forgotten deploy artifacts, and Docker misconfigurations.
- A single exposed .env file gave attackers access to 90,000+ cloud credentials in one large-scale extortion campaign.
- The fix is not just .gitignore. It is encrypted storage, access control, and treating .env files like the secrets they contain.
The numbers
In early 2026, security researchers published findings that should make every developer uncomfortable: over 12 million IP addresses were serving publicly accessible .env files. Not encrypted vaults. Not redacted examples. Real, live .env files containing database passwords, API keys, JWT signing secrets, and cloud provider credentials. Sitting on the open internet, waiting to be scraped.
The United States alone accounted for nearly 2.8 million of those exposed addresses. And separately, GitGuardian's 2026 State of Secrets Sprawl report found that 29 million secrets were committed to public GitHub repositories in the past year, with AI-service-related leaks surging 81% year over year.
These are not theoretical risks. These are credentials currently sitting in places where automated scrapers can find them in seconds. If you have ever deployed a web application, there is a non-zero chance that one of your .env files has been exposed at some point. This post breaks down how it happens, what attackers do with the data, and what you can do about it.
How .env files get exposed
The 12 million figure is not the result of one massive breach. It is the accumulation of millions of small, independent mistakes. Each one is easy to make, and most go unnoticed until it is too late.
Misconfigured web servers
This is the single largest category. A developer deploys a Laravel, Next.js, or Rails application. The .env file sits in the project root. The web server is configured to serve static files from that root, or the deny rules for dotfiles are missing. Now anyone who visits https://example.com/.env gets your database credentials in plaintext.
Most web servers (Nginx, Apache, Caddy) do not deny access to dotfiles by default. You have to explicitly add rules like location ~ /\. { deny all; } in Nginx. A forgotten rule, a config override, or a misconfigured reverse proxy is all it takes.
Accidental git commits
You add .env to .gitignore. Good. But then you run git add . before the gitignore is in place. Or you rename the file to .env.production and forget that gitignore only matches .env. Or a teammate commits it on a branch that gets merged before anyone notices.
Once a file enters git history, removing it from the current tree does not remove it from history. It remains accessible via git log and old commit hashes. For public repositories, that means it is permanently available to anyone. We covered this in detail in Stop Sharing Secrets on Slack, where we showed how chat-shared secrets persist in similar ways.
Forgotten deploy artifacts
CI/CD pipelines sometimes copy the entire project directory to a server, including the .env file. If the deploy target is a public web root, the file is now served over HTTP. Backup scripts that zip up project directories and store them in publicly accessible S3 buckets are another common vector. So are Docker images built with COPY . . that include the .env in the image layers.
Docker and container misconfigurations
A docker-compose.yml with env_file: .env pulls secrets into the container at build time. If that image is pushed to a public registry, the secrets are embedded in the image layers. Even a docker inspect on the running container can reveal environment variables to anyone with access. This is a particularly insidious vector because the .env file might be properly gitignored while the Docker image containing its contents is publicly available.
What attackers do with exposed .env files
An exposed .env file is not a theoretical vulnerability. It is an immediate, actionable credential dump. Here is what happens in practice:
- Automated scraping. Bots continuously scan IP ranges for common paths like
/.env,/.env.production,/.env.local, and/.env.backup. This is not targeted. It is industrial-scale harvesting. - Credential validation. Scraped keys are tested against AWS, GCP, Azure, Stripe, Twilio, SendGrid, and dozens of other services. Automated tools can validate thousands of keys per minute.
- Lateral movement. Database credentials from a
.envfile often grant access to the entire database, not just the application's tables. From there, attackers can exfiltrate user data, payment information, or other application secrets. - Cloud resource hijacking. AWS access keys from
.envfiles are used to spin up cryptocurrency mining instances, send spam through SES, or launch further attacks. The bill lands on your account. - Extortion. In the most sophisticated campaigns, attackers use the credentials to access cloud storage, exfiltrate data, delete the originals, and demand ransom. Palo Alto's Unit 42 documented one such operation involving over 90,000 leaked credentials.
The time window is minutes, not days. Researchers have demonstrated that AWS keys committed to public GitHub repos are discovered and exploited within minutes. Automated scanners run 24/7. By the time you realize a key has been exposed, it may already be in use.
Real incidents that started with a .env file
These are not hypothetical scenarios. Each of these incidents involved exposed environment variables as the initial attack vector.
The 90,000-credential cloud extortion campaign
Palo Alto Networks' Unit 42 team documented a large-scale extortion operation where attackers systematically scraped exposed .env files from the internet. They collected over 90,000 unique combinations of credentials, including AWS access keys, database connection strings, and OAuth tokens. The attackers used these credentials to access S3 buckets, exfiltrate data, and demand ransom. In many cases, the victims had no idea their .env files were publicly accessible.
Chainlit: AI framework leaking .env files
In early 2026, researchers discovered that Chainlit (a popular framework for building AI chat interfaces) had two high-severity vulnerabilities that allowed attackers to read arbitrary files from the server, including .env files containing API keys, database credentials, and internal network information. Any Chainlit deployment prior to version 2.9.4 was affected. This is a reminder that even well-maintained frameworks can introduce .env exposure as a side effect.
Supply chain attacks targeting .env
Multiple npm packages were discovered containing hidden code specifically designed to exfiltrate environment variables from the machines where they were installed. The malicious packages looked like legitimate DevOps utilities. Once installed, they would silently read the process environment (which includes any variables loaded from .env files) and send them to an external server. This attack vector is particularly dangerous because it bypasses all file-level protections. Even if your .env file is properly secured, if a malicious package reads process.env, your secrets are gone.
We wrote about similar risks in the context of AI coding agents in You Gave Your AI Agent Full Access. Did You Think About Your .env? and the broader security implications in Securing Your .env in the Age of Autonomous Code Agents.
Why .gitignore is not enough
The standard advice for .env security is: "add it to .gitignore." That is necessary, but it is nowhere near sufficient. Here is why:
- .gitignore does not protect against web server exposure. If your web server serves the project root, .gitignore is irrelevant. The file is accessible over HTTP regardless.
- .gitignore does not retroactively remove files. If the file was committed before the gitignore rule was added, it remains in history forever.
- .gitignore does not cover renamed files.
.env.production,.env.local,.env.stagingare often not covered by a simple.envpattern. - .gitignore does not prevent sharing. Developers still copy .env files through Slack, email, Notion, and shared drives. Each copy is an untracked, unaudited leak surface.
- .gitignore does not protect Docker images. A
COPY . .in a Dockerfile copies the .env into the image layer regardless of .gitignore.
The fundamental problem is that .gitignore is a source control tool, not a security tool. It was designed to keep your git index clean, not to protect secrets. Treating it as a security boundary is a category error that leads to the 12 million exposed files we are discussing.
The .env security checklist
If you are reading this and wondering whether your projects are vulnerable, here is a concrete checklist. Every item should be true for every project you maintain.
- Web server denies dotfile access. Your Nginx, Apache, or Caddy config explicitly blocks requests to any path starting with a dot. Test it:
curl -I https://yourdomain.com/.envshould return 403 or 404. - .gitignore covers all variants. Not just
.envbut also.env.*,.env.local,.env.production, and.env.backup. - Git history is clean. Run
git log --all --diff-filter=A -- .env*to check if any .env file was ever committed. If it was, rotate every credential in that file immediately. - Docker images exclude .env. Your
.dockerignoreincludes.env*. Verify withdocker historyor by inspecting image layers. - CI/CD pipelines use secret injection. Secrets are injected via your CI provider's secret store, not copied from .env files in the repo.
- No .env files shared via chat or email. If teammates need environment variables, they should pull them from an encrypted source, not receive them in a Slack DM.
- Secrets are encrypted at rest. Your
.envfile contents are encrypted before being stored anywhere outside your local machine. - Credentials rotate on a schedule. Even if nothing has been exposed, rotating keys quarterly reduces the blast radius of an undetected leak.
What proper .env management looks like
The checklist above covers the defensive basics. But the real fix is not more vigilance. It is better tooling. The reason 12 million .env files are exposed is not that developers are careless. It is that the default workflow for managing environment variables has no security built in.
Think about what we accept as normal: a plaintext file, sitting in a project root, containing every credential the application needs to function. No encryption. No access control. No version history. No audit trail. The only protection is a single line in .gitignore and the hope that nobody misconfigures a web server.
We wrote about this gap in Your Code is Versioned. Your Secrets Aren't. The fix is to treat .env files with the same rigor we apply to source code: encrypted, versioned, access-controlled, and synced through a dedicated tool.
That is exactly what SlickEnv does. Every variable is encrypted client-side with AES-256-GCM before it leaves your machine. The server stores ciphertext only. Every push creates an immutable version you can roll back to. Conflict detection prevents silent overwrites. And the entire workflow fits into three commands:
$ slickenv push # encrypt and sync your .env
$ slickenv pull # fetch the latest version
$ slickenv status # see what changedNo plaintext files on remote servers. No credentials in git history. No Slack DMs with API keys. If you want the full walkthrough, the getting started guide takes under two minutes. The security architecture page covers the encryption model in detail.
For teams evaluating their options, we also published a detailed comparison of SlickEnv vs Doppler vs dotenv-vault that covers pricing, encryption models, and workflow trade-offs.
Stop treating .env files as disposable
Twelve million exposed .env files is not a statistic about bad developers. It is a statistic about bad defaults. The .env file was never designed to be a security mechanism. It was a convenience for loading configuration during local development. Somewhere along the way, it became the de facto way to store production credentials, and nobody upgraded the security model to match.
The developers whose credentials are in that 12 million are not negligent. They are using the same workflow everyone uses. The problem is that the workflow itself is broken. Plaintext files with no encryption, no versioning, and no access control are not a viable way to manage secrets in 2026.
The best time to encrypt your .env files was before the first deployment. The second best time is now.
If you are still managing environment variables by copying plaintext files around, today is a good day to stop. Whether you use SlickEnv, a secrets vault, or any other encrypted workflow, the important thing is to stop treating your most sensitive credentials as disposable plaintext.
SlickEnv is free during beta. Every feature included, no credit card required. Install it, push your .env, and see encrypted sync in action. Get started in under 2 minutes.
