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.
Database backup files and application archives are created regularly as part of responsible operations: before major deployments, as scheduled jobs, or as manual safeguards before maintenance windows. The problem arises when developers create these backups in the public/ directory for convenient download, or when automated backup tools write to a location that is web-accessible. A single .sql file left in the wrong directory is often more damaging than a typical SQL injection vulnerability — it provides the entire database in one download.
Automated scanners specifically target backup file patterns. Security researchers and attackers maintain wordlists containing thousands of common backup naming patterns: backup.sql, dump.sql, db_backup.sql.gz, site.zip, backup_2024.tar.gz, database_export.sql. These names are derived from the defaults of popular backup tools, phpMyAdmin exports, and common developer naming conventions. Scanners test these paths against every domain they discover, continuously. A file with a predictable name in a predictable location will be found.
Real data breaches have resulted directly from exposed backup files. An organization's entire database — user records, passwords, payment data — can be downloaded in seconds once the URL is known. The attacker does not need to exploit any vulnerability in application code; they simply fetch the URL. This makes backup file exposure arguably more severe than many code-level vulnerabilities because the entire data layer is compromised immediately upon discovery. The solution is categorical: backups must never be written to any web-accessible directory.
The Problem
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.
How 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.zipFor 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>
How to Verify
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.
Related Guides
Laravel .env File Exposed: How to Block Public Access and Rotate Leaked Credentials
Your Laravel .env file is publicly accessible, leaking database credentials, APP_KEY, and API keys. Block it in Apache and Nginx, then rotate every compromised secret.
How to Fix an Exposed .git Directory
Your .git directory is publicly accessible, allowing attackers to download your entire source code and commit history. Fix it now.
Laravel File Permissions: How to Fix World-Writable Files and Secure Your Filesystem
Files with 777 or 666 permissions let any user on the server read, write, or execute them. Set restrictive permissions to prevent unauthorized modification.
Is your Laravel app exposed right now?
34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.