.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
- Probe paths — every common environment-file name and variant is requested directly against your host.
- Load the app — we fetch your URL in a real headless browser and collect the JavaScript delivered to visitors.
- Inspect the bundle — inlined build-time variables are extracted and matched against known secret formats.
- Test config routes — config, debug, and health endpoints are requested to see whether they return environment data.
- 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
/.envagainst 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.txtand 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
.envthat was ever committed remains in the objects even after deletion, and an exposed.gitdirectory hands the whole history over. - Re-scan after each deploy. Environment handling changes every time someone debugs a build failure.
Related tools and guides
- Token Leak Checker — fingerprints the actual key formats found in bundles and env dumps.
- Source Map Exposure Checker — the same deploy mistake usually ships
.gitand.mapfiles too. - CORS Misconfiguration Checker — check whether the endpoints reading that config are readable cross-origin.
- JWT Security Checker — an exposed signing secret makes every token in your app forgeable.
- Supabase RLS Checker — confirms whether a leaked database URL actually grants data access.
- Firebase Scanner — Firestore rules, auth, and storage bucket checks.
- Vibe Code Scanner — full security scan of a deployed AI-generated app.
- Free Security Self-Audit — manual checklist that pairs with automated scanning.
- Source maps and .git exposed pattern — the deploy failure mode behind most env leaks.
COMMON QUESTIONS
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.