A single misconfigured deploy can put your database password, API keys, and source history one HTTP request away from anyone on the internet. The two classic offenders are a publicly readable .env file and a downloadable .git/ directory. Both happen constantly to indie and "vibecoder" projects when a static host or misconfigured server serves dotfiles it was never meant to expose. If you are about to launch a web app or store, this is one of the fastest, highest-impact things to verify — and you can answer "is my .env file exposed?" in seconds without touching your server.
What LaunchTrust checks
The exposed_files detector works entirely from the outside, the same way a stranger or a bot would. It reduces the page's final URL to its origin (scheme + host + port) and makes plain GET requests for three paths that should never be publicly served: /.env, /.git/HEAD, and /.git/config.
Crucially, a 200 OK response alone is not treated as a hit. Many single-page apps return a 200 with normal HTML for any unknown path, so a naive scanner would false-flag healthy sites. To avoid that, the detector reads the response body (capped at 20 KB) and only counts a path as exposed if the content actually matches the shape of that sensitive file:
/.envmust contain a real environment-variable line — an uppercase key followed by=, likeDATABASE_URL=..../.git/HEADmust contain a Git ref pointer such asref: refs/heads/main./.git/configmust contain a Git config section header such as[core]or[remote "origin"].
The three possible signals:
- Detected (severity: high) — at least one path responded with content that genuinely matches a sensitive file. This is a polarity-"risk" finding: unlike a privacy policy, it is something you do not want present. It means real config or repository internals are being served to the public.
- Not detected (info) — none of the three paths returned matching content at the scanned origin.
- Unable to determine — the scanner could not derive a valid origin from the page URL, so it could not run the checks.
One honest limit: the scan only probes these three paths at the page's own origin. It does not crawl for renamed files (.env.production, .env.local), backups, other config files, or .git on subdomains. "Not detected" means these common exposures were not seen — not that nothing sensitive is reachable anywhere on your infrastructure.
Why it matters
Leaked secrets are a cybersecurity problem first and a regulatory problem second — and both can sink a launch. A readable .env typically hands an attacker your database credentials, API keys, session signing secrets, and payment tokens, making account takeover, data theft, and fraudulent charges trivial. A downloadable .git/ directory is just as dangerous in a quieter way: tools can reconstruct your entire source tree and commit history from it, including secrets that were committed and "removed" later — they still live in history.
This also intersects with data-protection duties. If exposed credentials lead to personal data being accessed, that is the kind of unauthorized access that commonly triggers breach-notification obligations under regimes like the GDPR and equivalent rules elsewhere. App and platform reviewers also look unfavorably on obvious credential-hygiene failures. Closing these gaps before launch is far cheaper than handling an incident after it.
A concrete example
Here is what a genuinely exposed .env looks like when fetched over the open web. The values are masked — never paste real secrets anywhere:
DATABASE_URL=postgres://app:REDACTED@db.internal:5432/prod
STRIPE_SECRET_KEY=sk_live_...REDACTED
JWT_SECRET=REDACTED
The detector does not need the values to flag this — an uppercase-KEY= line in a body served at /.env is enough to mark the path as exposed. If you see anything like this when you load https://yourdomain.com/.env, treat every secret in it as compromised and rotate immediately.
How to address it
- Confirm the exposure yourself. Open
/.env,/.git/HEAD, and/.git/configon your domain in a browser or withcurl. If any returns real file content (not your app's HTML or a 404), it is exposed. - Rotate every secret before fixing the serving. If
.envwas readable, assume the keys are public. Rotate database passwords, API keys, signing secrets, and payment tokens now — patching the path does not un-leak what was already fetched. - Stop serving dotfiles at the web layer. On Nginx, deny
location ~ /\.; on Apache, block.envand.git; on a static host (Netlify, Vercel, Cloudflare Pages), ensure these files are never part of the published build. - Keep secrets out of the deploy artifact. Move configuration into your host's environment variables or a secrets manager so there is no
.envfile in the deployed directory to leak. - Add
.envand.gitto ignore and deploy-exclude lists. Ensure.gitignorecovers.env*, and that your build step never copies the.gitdirectory into the served root. - Re-scan after deploying the fix. Confirm the paths now return a 404 or are denied and that the signal flips to "not detected."
Check this in 30 seconds
Run your URL through the free LaunchTrust scanner. The exposed_files check fetches /.env, /.git/HEAD, and /.git/config from your origin, validates the response content, and tells you plainly whether each path is exposed — no install, no credentials, no changes to your site. It is the quickest way to answer "is my .env file exposed?" before strangers do it for you.
FAQ
Does a 200 response mean my .env is exposed? Not on its own. Many sites return 200 with normal HTML for unknown paths. LaunchTrust only flags /.env when the response body actually contains environment-variable content, so SPA "catch-all" pages do not trigger a false alarm.
My scan says "not detected" — does that mean I have no leaks? No. It means the three common paths at the scanned origin did not return matching content. It does not check renamed env files, backups, other config files, or .git on subdomains. Treat it as one cleared risk, not a clean bill of health.
Why is an exposed .git directory dangerous if I only pushed compiled code? Because .git carries your full history. Anyone who downloads it can reconstruct source and read every secret ever committed — even ones you later deleted, since they remain in past commits.
Does this prove my app meets the law? No. It surfaces a security signal — whether specific sensitive files are reachable — not a verdict. It is not legal advice or a certification, and a "not detected" result does not prove your app meets any law or store policy.
Compliance aid, not legal advice. LaunchTrust reports signals, not a verdict or certification.