# Nine Files That Shouldn&#39;t Be Publicly Reachable On Any Website

Regardless of whether you run WordPress, Shopify, a static site, or a custom app, nine files commonly ship to production by accident and leak credentials, code history, or internal structure. Here&#39;s what each one is and how to block it.

Author: J.A. Watte
Published: April 21, 2026
Source: https://jwatte.com/blog/blog-universal-file-exposure/

---

Platform-specific hardening matters, but there's a class of file-exposure mistakes that happen on every platform regardless of tech stack. The Mega Security Analyzer now probes for these on every scan. This post covers why each one is a fail, what the leak reveals, and how to block it.

## 1. /.git/HEAD

The single most damaging deployment mistake. When the `.git` directory ends up in your webroot, attackers can download your entire source history using tools like `git-dumper` (which walks `.git/objects/` and reassembles the full repo). The damage: every commit, every branch, every secret you ever committed (even to a private branch, even if you later removed it), every commented-out credential.

Fix: your build pipeline should never publish the `.git` directory. Check your `.gitignore` for deploy paths. For Netlify / Vercel / Cloudflare Pages, the build output directory is what ships, so as long as `.git` isn't inside that folder you're fine. For traditional hosts, add a server rule:

```
RedirectMatch 404 ^/\.git
```

## 2. /.env

Your application's environment file. Contains database credentials, API keys, encryption secrets, third-party service tokens. If /.env returns a 200 with `KEY=value` style content, you've shipped your production secrets to anyone who asks.

Fix: never put `.env` in your webroot. For PHP + Apache: add to .htaccess:

```
<FilesMatch "^\.env">
  Require all denied
</FilesMatch>
```

If /.env is already exposed, rotate every secret in it immediately. Treat them as leaked.

## 3. /.DS_Store

The macOS Finder metadata file. Contains the names of every file in the directory, even deleted files still referenced in the Finder cache. When exposed publicly, attackers get a directory listing of your site's folder structure.

Fix: macOS developers need `.DS_Store` in their `.gitignore`. A global gitignore rule:

```
git config --global core.excludesfile ~/.gitignore_global
echo ".DS_Store" >> ~/.gitignore_global
```

## 4. /phpinfo.php

The classic "I'll just drop a phpinfo() to check my PHP config" file that developers forget about. Exposes PHP version, loaded modules, full environment variables (including database credentials), file paths, server OS, security-module settings. It's a roadmap for an attacker.

Fix: delete every `phpinfo.php` on every server the moment you stop debugging. Don't commit one ever.

## 5. /composer.json

PHP dependency manifest. Reveals exact package versions the site runs. An attacker cross-references against the CVE database to find known-vulnerable versions. Not a secret leak by itself but a precision tool for targeted exploitation.

Fix: Composer's `public` directory pattern keeps composer.json outside the webroot. If your host forces webroot = project root, deny via .htaccess:

```
<FilesMatch "composer\.(json|lock)$">
  Require all denied
</FilesMatch>
```

## 6. /package.json

Same problem as composer.json but for Node projects. Reveals your dependency tree. Modern deploys typically exclude package.json from the public bundle (Webpack, Vite, Rollup, esbuild all strip it), but older or misconfigured setups leak it.

Fix: your bundler's build output shouldn't include package.json. If yours does, deny via server rule.

## 7. /yarn.lock (and /package-lock.json)

Lockfiles pin exact versions of every transitive dependency. Exposing them is the more detailed version of exposing package.json. Attackers know not just "they run React 18" but "they run react@18.2.0 with react-dom@18.2.0 and scheduler@0.23.0." The CVE-matching gets more precise.

## 8. /backup.zip, /backup.sql, /db.sql

Whatever you called your last backup. Often named exactly this. Contains the entire site, the entire database, and every user record, session, password hash, and piece of user-submitted content. A single exposed backup file is the worst-case breach: the attacker now has your database and can run it against HIBP / rainbow tables offline.

Fix: never put a backup in your webroot. Store backups on a separate host with authenticated access (S3 + IAM, Backblaze B2 + app key, Wasabi). Never name them predictable names.

## 9. /.well-known/security.txt

The one positive exposure. This file, per RFC 9116, tells security researchers where to contact you when they find a vulnerability. Having it is a green signal: it says the organization has a responsible-disclosure path and takes security seriously.

Format:

```
Contact: mailto:security@yourdomain.com
Expires: 2027-01-01T00:00:00.000Z
Preferred-Languages: en
Canonical: https://yourdomain.com/.well-known/security.txt
```

Add it. Then renew the `Expires:` line annually.

## How to test your site

Run the [Mega Security Analyzer](/tools/mega-security-analyzer/) against your production URL. It probes all nine paths in parallel and flags any that return a 200 with matching content signatures. The tool also runs 3-probe consensus so edge-case caching behavior doesn't produce false positives.

## Why platform-specific audits miss these

Each platform's own audit focuses on platform-specific hardening (WordPress checks XML-RPC, Shopify checks OS 2.0 migration, etc.). Universal file exposure doesn't belong to any one platform — it's a deployment-pipeline mistake that happens regardless of tech stack. The Mega Security Analyzer runs them on every scan for exactly this reason.

## Related reading

- [Mega Security Analyzer](/tools/mega-security-analyzer/) — the tool that runs these universal probes
- [WordPress Hardening Exposures](/blog/blog-wordpress-hardening-exposures/) — the four WP-specific URLs that shouldn't be public
- [Modern Security Headers](/blog/blog-modern-security-headers/) — the HTTP-layer hardening that pairs with file-level hardening
- [Server-Side Audit Probes](/blog/blog-server-side-audit-probes/) — how the multi-probe architecture works

## Fact-check notes and sources

- `git-dumper` public tool (github.com/arthaud/git-dumper) documenting the .git exposure attack.
- OWASP Testing Guide: Configuration and Deployment Management Testing.
- RFC 9116 — A File Format to Aid in Security Vulnerability Disclosure.
- NIST SP 800-95 on general web application security hardening.

_This post is informational, not security-consulting advice. The probes run only against URLs you provide and submit; they respect robots.txt and rate-limit politely. Only scan sites you own or have explicit written authorization to test. Remediation of confirmed exposures is time-sensitive — rotate secrets and investigate access logs the moment you find a leak._


---

Canonical HTML: https://jwatte.com/blog/blog-universal-file-exposure/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/blog-universal-file-exposure.webp
