← Back to the Backup File Exposure Checker

Why backup files end up in web roots

A backup archive or SQL dump only becomes a problem when a production deployment leaves it publicly reachable. There are four common, independent ways that happens, and each has its own fix — fixing one does not fix the others.

1. A backup script writes its output into the served directory

A cron job or deploy hook that runs tar -czf backup.tar.gz . or mysqldump mydb > backup.sql from inside the web root writes its output right next to the site it is a copy of — servable like any other file the moment it lands.

# Wrong: backup written straight into the served directory
cd /var/www/myapp && tar -czf backup.tar.gz .

# Right: written outside the served tree entirely
mysqldump mydb | gzip > /var/backups/myapp/db-$(date +%F).sql.gz

2. A one-off manual backup gets left where it was made

"Let me zip the site before I deploy this change" is a real, common reason a backup.zip appears — made once, in the web root, purely for convenience, and then forgotten once the deploy went fine. Treat any backup made inside the deploy path as temporary: move it out or delete it the same day.

3. No server rule blocking backup extensions as a second layer

Defense in depth: even with the backup process fixed, a server or CDN rule that denies requests for common backup extensions means a stray copy — a one-off manual backup, a misconfigured mirror — is not actually reachable.

# nginx example
location ~* \.(zip|tar\.gz|sql|sql\.gz|bak)$ { deny all; return 404; }

# Apache example (.htaccess in the document root)
<FilesMatch "\.(zip|tar\.gz|sql|sql\.gz|bak)$">
  Require all denied
</FilesMatch>

4. Backups are kept as files at all, instead of a managed off-box service

A dedicated backup service or object-storage bucket with its own access controls never puts the file anywhere a web server could serve it in the first place — it is both safer and more reliable than any deploy-path convention.

If this checker already found an exposure

Fix the process cause first (steps 1–2 above), then treat every credential and secret that archive or dump's tables could hold as compromised and rotate it immediately — database passwords, API keys, session secrets, anything a config file or environment table inside the backup could have carried. Rotation is the only remedy once a backup has been served publicly, even once: there is no way to know for certain it was not already fetched by an automated scanner before you found it.

Run the Backup File Exposure Checker against your production URL to see which of these, if any, apply to your deployment right now. Only run it against a site you own or are authorised to test.