SecureBlockLog inStart a pentest
Vulnerability Repository
HighMisconfiguration

Backup File Exposure

Backup and temporary files left in web-accessible directories expose full application source code, database dumps, and configuration secrets to unauthenticated attackers.

CVSS 7.5CWE CWE-530OWASP A05:2021 — Security Misconfiguration

Description

Backup file exposure occurs when files created during development, editing, or archiving operations are left in web-accessible directories and served by the web server as static content. Unlike the original executable files (.php, .py, .rb), backup copies with altered extensions are not processed by the application runtime — they are served as raw plaintext, revealing their full source content to anyone who requests them.

CWE-530 — Exposure of Backup File to Unauthorised Control Sphere describes this class of issue. It arises from editor behaviour (vim creates .swp files, emacs creates filename~ files), manual backup habits (cp config.php config.php.bak), deployment processes that archive files before updating them, and automated backup tools that write to the document root.

This vulnerability is classified under A05:2021 — Security Misconfiguration because the web server is correctly serving files it can find — the misconfiguration is that backup files were left where the web server can find them, or that the server is not configured to block non-productive file extensions.

How It Works

An attacker discovering a PHP application at https://example.com/ will systematically probe for predictable backup filenames:

# Using ffuf to fuzz backup extensions on discovered filenames
ffuf -u https://example.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/Common-PHP-Filenames.txt \
     -e .bak,.old,.orig,.backup,.save,.swp,.~,_backup,.copy

# Target examples
https://example.com/index.php.bak         → full PHP source
https://example.com/config.php~           → database credentials
https://example.com/wp-config.php.old     → WordPress admin creds
https://example.com/.wp-config.php.swp    → vim swap file (parseable)

Database dump files are particularly valuable targets:

# Common database dump locations
https://example.com/backup.sql
https://example.com/db_backup_2024-01-15.sql.gz
https://example.com/dumps/production.sql

A single mysqldump file can contain the entire application database including hashed (or worse, plaintext) user passwords, all PII, and application configuration stored in the database.

Web archive files are another high-value target. Administrators sometimes create tarballs of the application before a deployment:

https://example.com/backup.tar.gz
https://example.com/site_backup.zip
https://example.com/www.tar.bz2

These can contain the full application tree including .git history, .env files, and private TLS keys.

Impact

  • Source code disclosure — backup copies of active PHP, Python, or Ruby files expose application logic, hardcoded secrets, and internal API structures.
  • Database credential exposure — configuration backup files almost always contain database connection strings with plaintext credentials.
  • Full data compromise — SQL dump files expose the entire database contents without requiring any SQL injection or authentication bypass.
  • Private key exposure — application archives may include TLS private keys, SSH keys, and code-signing certificates.
  • Chained exploitation — source code review from backup files identifies injection points, hidden admin paths, and validation bypasses that would otherwise require extensive black-box testing to discover.

Detection

  1. Run a backup extension wordlist scan — use ffuf or feroxbuster with -e .bak,.old,.orig,.backup,.save,.swp,.tmp,.copy against all discovered filenames, not just the web root index.
  2. Fuzz for archive files — combine common archive names (backup, dump, db, database, site, www, the domain name without TLD) with extensions .zip, .tar.gz, .tar.bz2, .tgz, .7z.
  3. Test for vim and emacs swap files — request .filename.swp, filename~, #filename# for every known source file.
  4. Check database dump extensions — request .sql, .sql.gz, .dump, .dmp variants at /, /backup/, /dumps/, /db/, and /tmp/.
  5. Verify HTTP response codes and content-type — a 200 response with Content-Type: text/plain or application/octet-stream for a PHP filename variant is a confirmed finding.

Remediation

Configure the web server to block non-productive extensions. In Nginx, use a location block to return 403 for backup patterns:

location ~* \.(bak|old|orig|backup|save|swp|tmp|sql|dump)$ {
    deny all;
    return 403;
}

Implement allowlist-based file serving. Rather than blocking specific extensions, configure the server to only serve whitelisted extensions (html, js, css, png, jpg, woff2) and deny everything else by default.

Move backup operations outside the document root. All backup files, database dumps, and deployment archives must be written to directories not accessible by the web server — for example, /var/backups/ rather than /var/www/html/backups/.

Add backup patterns to .gitignore and deployment exclude lists. Prevent backup files from being inadvertently deployed alongside application code.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping