.ENV EXPOSURE CHECKER

Paste a URL. The scanner requests every common environment-file path, reads what your bundle inlined at build time, and probes config endpoints that hand back the whole environment as JSON.

CHECK FOR EXPOSED ENV FILES NOW

Enter your URL — we probe /.env and its variants, inspect the JS bundle for inlined environment variables, and test config endpoints that dump environment as JSON.

What is .env exposure?

A .env file is where an application keeps the values it must not publish — database connection strings, API secrets, JWT signing keys, SMTP passwords, webhook secrets. The convention works because the file stays on the server and is read at startup.

Exposure is when that file is reachable over HTTP. https://yoursite.com/.env returns 200, and every secret the app depends on is now a single request away. There is no exploitation involved: no injection, no bypass, no chained vulnerability. Someone typed a URL.

Two adjacent leaks matter just as much. Bundlers inline environment variables carrying a public prefix directly into shipped JavaScript, so a mislabeled secret becomes readable in the browser. And config endpoints — debug routes, health checks with details, /api/config — hand back environment data as JSON to anyone who asks.

Why this happens in AI-generated apps

AI coding tools — Lovable, Bolt, v0, Cursor, Replit — write a .env file early, because that is the idiomatic pattern in every training example. What they do not consistently do is separate “the project folder” from “what gets deployed.” When the deploy step copies the working directory, the .env travels with the code.

The bundler leak is more subtle and more common. A build fails because a variable is undefined in the browser. The fix that makes the error disappear is to add NEXT_PUBLIC_ or VITE_ to the name, and the model or the developer applies it without distinguishing between a public project URL and a service-role key. The build then succeeds and the secret is inlined into JavaScript that every visitor downloads. See the Token Leak Checker for what those inlined values look like once they land in the bundle.

Debug endpoints are the third path. A /api/debug or verbose /health route added while chasing a deployment problem is rarely removed, and framework debug modes stay on because nothing in the UI indicates they are.

The same deploy carelessness usually ships more than one artifact — see source maps and .git exposed, and OWASP Top 10 for AI-generated code for how these compound.

What the scanner checks

CANONICAL /.ENV

The plain /.env path — the request every commodity scanner on the internet already makes.

ENV VARIANTS

.env.local, .env.production, .env.development, and per-stage files that host dotfile rules often miss.

BACKUP COPIES

.env.bak, .env.save, env.txt, .env~ — ordinary filenames with no dotfile protection at all.

INLINED BUILD VARS

Values baked into the JS bundle by a public prefix, including secrets that got prefixed to silence a build error.

CONFIG ENDPOINTS

/api/config, /config.json, and runtime-config routes that return environment values as JSON.

DEBUG AND HEALTH ROUTES

Verbose /health, /api/debug, and framework debug pages that serialize the process environment.

ERROR PAGE LEAKS

Stack traces rendered in production that print environment values or connection strings alongside the trace.

ADJACENT CONFIG FILES

docker-compose.yml, .npmrc, wp-config.php, and CI files carrying credentials in the web root.

How it works

  1. Probe paths — every common environment-file name and variant is requested directly against your host.
  2. Load the app — we fetch your URL in a real headless browser and collect the JavaScript delivered to visitors.
  3. Inspect the bundle — inlined build-time variables are extracted and matched against known secret formats.
  4. Test config routes — config, debug, and health endpoints are requested to see whether they return environment data.
  5. Report — every reachable value is listed with its source URL, what it unlocks, and rotation steps.

Where environment values leak

Leak surface How it happens Severity
/.env reachable Project folder deployed instead of build output Critical — every value is readable
.env.production, .env.local Host dotfile rule matches only the exact name .env Critical
.env.bak, env.txt Backup copy left in the web root; not a dotfile, so no rule applies Critical
Prefixed secret in bundle NEXT_PUBLIC_ / VITE_ added to silence an undefined-variable error High to critical, depending on the key
/api/config JSON Runtime config endpoint serializing more than the client needs High
Verbose /health Health route extended with detail during debugging and never trimmed Medium to high
Framework debug page Debug mode left enabled in production, printing the environment Critical
Production stack trace Unhandled error rendered with connection strings in the frame data High
docker-compose.yml served Whole repo deployed; credentials sit in the compose file Critical
Committed .env in git File committed once, removed later, still present in history Critical — see the Source Map Exposure Checker

Common fixes

  • Rotate first, fix second. If a file was reachable, assume it was read — automated scanners request /.env against every host continuously. Rotate every value in it, not only the ones that look sensitive.
  • Store configuration in your host’s environment variable settings rather than a file inside the repository. Nothing that is not in the deployed directory can be served from it.
  • Deploy the build output directory only. Add .env* to .gitignore, .vercelignore, .dockerignore, and any host-specific ignore file.
  • Add a host rule denying every path that begins with a dot, plus explicit denies for env.txt and backup suffixes that a dotfile rule will not catch.
  • Audit every variable carrying a public prefix. If a value would be damaging in a stranger’s hands, it must not have that prefix — move the call behind a server route or edge function so the secret stays on the server.
  • Remove debug and verbose health endpoints from production builds, and confirm the framework’s debug mode is off. A health check should return status, not configuration.
  • Check git history. A .env that was ever committed remains in the objects even after deletion, and an exposed .git directory hands the whole history over.
  • Re-scan after each deploy. Environment handling changes every time someone debugs a build failure.

COMMON QUESTIONS

01
What is .env exposure?
A .env file holds the configuration your app is not supposed to publish: database URLs, API secrets, signing keys, SMTP credentials. Exposure means that file, or a copy of it, is reachable over HTTP from your deployed site — so anyone can fetch it with a single request and read every value in it.
Q&A
02
How does a .env file end up in the web root?
Almost always through the deploy step. Uploading the project folder instead of the build output, an rsync that copies everything, a Dockerfile with a broad COPY, or a static host whose root is the repository directory. The file was never meant to be served — it just happened to be sitting where the server serves from.
Q&A
03
Isn't a .env file blocked by default?
Some hosts deny dotfile paths, many do not, and the ones that do often only block the exact name. Copies like .env.backup, .env.production.local, env.txt, or .env.save are ordinary filenames with no special handling. The scanner checks the variants, not just the canonical name.
Q&A
04
What about NEXT_PUBLIC_ and VITE_ variables?
Those prefixes tell the bundler to inline the value into the JavaScript that ships to browsers. That is intended behavior for genuinely public values like a project URL. It becomes a leak when a secret gets the prefix — usually because the build failed with the variable undefined and adding the prefix made the error stop. Once inlined, the value is in the bundle for every visitor.
Q&A
05
What is a config endpoint dump?
An endpoint that returns application configuration as JSON — /api/config, /api/debug, /health with details, or a framework debug route left enabled. Some serialize process.env wholesale. Others reveal one variable at a time, which is enough when the one variable is a database URL.
Q&A
06
Do I need to rotate a key if the file was only reachable briefly?
Yes. Requests for /.env are commodity scanner traffic that runs continuously against every host on the internet. There is no window short enough to assume nobody looked. Treat every value in an exposed file as compromised and rotate all of them, not just the ones that look important.
Q&A
07
Is the scan safe to run on production?
Yes. It sends ordinary GET requests for public paths — the same traffic any crawler produces — and reads the JavaScript already delivered to visitors. Nothing is written, no authentication is attempted, and retrieved values are not stored.
Q&A
08
How do I fix an exposed .env?
Rotate every credential in the file first, before fixing the deploy — the file has already been read. Then move configuration into your host's environment variable settings instead of a file in the repo, deploy only the build output, and add a host rule denying all dotfile paths. Finally, check git history: if the file was ever committed, it is exposed there too.
Q&A

SCAN THE FULL APP, NOT JUST ENV

A reachable .env is one door. The VibeEval agent tests everything behind it — auth, RLS, and API behavior.

RUN FULL SCAN