# Laravel Backup Files in Public Directory: How to Find and Remove Exposed Archives and Dumps

> Database dumps, .zip archives, and .sql backups in your public directory are downloadable by anyone. Move them out of the web root immediately.

**Severity:** high | **Category:** Infrastructure Security

---

## The Issue

Backup files left in the public directory — database dumps (.sql, .sql.gz), archives (.zip, .tar.gz, .bak), and old file copies (.php.bak, .env.backup) — are directly downloadable by anyone who guesses or discovers the URL. Database dumps contain your entire database: user records, passwords, payment data, and application secrets. Attackers use automated tools to scan for common backup filenames like backup.sql, db.sql.gz, site.zip, and .env.bak.

## Steps to Fix

### 1. Find backup files in public directories

Search for common backup file patterns:

find public/ -name '*.sql' -o -name '*.sql.gz' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.bak' -o -name '*.backup' -o -name '*.old' -o -name '*.dump' -o -name '*.db'

Also check for copies of sensitive files:

find public/ -name '.env*' -o -name '*.php.bak' -o -name 'composer.json' -o -name 'composer.lock'

Check the project root too — some web server configs serve from the wrong directory.

### 2. Remove or move backup files

Delete backup files from public directories:

rm public/backup.sql.gz
rm public/site-backup.zip

For backups you need to keep, store them outside the web root:

# Move to storage (not publicly accessible)
mv public/backup.sql.gz storage/app/backups/

# Or use Laravel's backup package
composer require spatie/laravel-backup
php artisan backup:run
# Stores backups in storage/app/backups/ by default

### 3. Block backup file extensions in your web server

Add a rule to block common backup extensions:

Nginx:
location ~* \.(sql|sql\.gz|bak|backup|old|dump|db|tar\.gz)$ {
    deny all;
    return 404;
}

Apache (.htaccess):
<FilesMatch "\.(sql|bak|backup|old|dump|db|tar\.gz)$">
    Order allow,deny
    Deny from all
</FilesMatch>

## Verification

Test common backup URLs:

curl -s -o /dev/null -w '%{http_code}' https://yourapp.com/backup.sql
curl -s -o /dev/null -w '%{http_code}' https://yourapp.com/db.sql.gz
curl -s -o /dev/null -w '%{http_code}' https://yourapp.com/site.zip

All should return 404. Run php artisan stackshield:scan --check=SS058 to scan for backup files.

## Prevention

Never create backups in the public directory. Use spatie/laravel-backup or similar tools that store backups in storage/ or S3. Block backup file extensions at the web server level. Add a deployment check that scans public/ for backup files.

---

## Frequently Asked Questions

### Can attackers really find my backup files?

Yes. Automated scanners test thousands of common backup filenames (backup.sql, dump.sql, site.zip, etc.) against every domain they discover. These scans run continuously. If the file exists, it will be found.

### Where should I store database backups?

Use storage/app/backups/ (not publicly accessible), S3 with restricted access, or a dedicated backup service. Never store backups on the web server itself long-term — they take up space and create exposure risk. Rotate old backups automatically.

### What if I need to transfer a backup file to a team member or support provider?

Use a time-limited, signed URL from S3 or another object storage service. Generate a pre-signed URL with a short expiration (15 minutes), share that URL, and the recipient downloads directly from S3 without the file ever being placed in a web-accessible path. In Laravel: Storage::temporaryUrl($path, now()->addMinutes(15)) generates these for S3-compatible disks.

### Can I protect backup files in public/ with web server rules instead of moving them?

You can add Nginx or Apache rules to block backup file extensions, and you should as defense-in-depth. But web server configuration can be overridden, misconfigured, or bypassed. The correct approach is to never place backup files in public/ in the first place. Block backup extensions as an additional safety net, not as a replacement for proper storage location.

### Should I encrypt database backups?

Yes, always. Use openssl enc -aes-256-cbc or GPG encryption before uploading backups to storage. The spatie/laravel-backup package supports encryption via the "encryption" option in config/backup.php. Even if an attacker gains access to your backup storage (S3, FTP), encrypted backups are useless without the decryption key.

