How to Fix an Exposed Laravel Storage Directory
Your Laravel storage directory is publicly accessible, exposing logs, cache files, and uploaded data. Learn how to restrict access.
The Problem
An exposed storage directory allows attackers to access your application logs (containing error details and potentially sensitive data), session files, cache data, and user-uploaded files that should be private. The storage directory contains framework-generated files and user uploads that were never intended to be publicly accessible. Automated scanners regularly check for exposed Laravel storage paths.
How to Fix
-
1
Verify your document root
The most common cause of an exposed storage directory is an incorrect document root. Your web server must point to /public, not the project root:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>With the correct document root, the storage directory is outside the web-accessible path and cannot be accessed directly.
-
2
Remove or secure the storage symlink
The php artisan storage:link command creates a symlink from public/storage to storage/app/public. Only files in storage/app/public should be web-accessible.
Check what the symlink points to:
{{ trim($paragraph)); ?>It should point to ../storage/app/public, not ../storage. If it points to the wrong location, recreate it:
{{ trim($paragraph)); ?>Never store private files in storage/app/public. Use storage/app/private/ for sensitive uploads.
-
3
Block direct access to storage paths
Add web server rules to block access to storage directories that should not be public. In Nginx:
{{ trim($paragraph)); ?>In Apache .htaccess:
{{ trim($paragraph)); ?>This ensures only public/storage (the symlink to storage/app/public) is accessible.
-
4
Serve private files through a controller
For files that require authentication, serve them through a Laravel controller instead of direct file access:
{{ trim($paragraph)); ?>if (!file_exists($fullPath)) { abort(404); }
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>
How to Verify
Check that storage directories are not accessible:
curl -I https://yourdomain.com/storage/logs/laravel.log
curl -I https://yourdomain.com/storage/framework/sessions/
curl -I https://yourdomain.com/storage/app/
All should return 403 or 404. Only public/storage files (user-uploaded public assets) should return 200.
Prevention
Always use the correct document root. Store sensitive files in storage/app/private/ and serve through authenticated controllers. Never store user uploads in a publicly accessible directory without access controls. Use StackShield to monitor for exposed storage paths.
Frequently Asked Questions
What sensitive data is in the storage directory?
The storage directory contains: application logs with error details and stack traces (storage/logs/), session data for all users (storage/framework/sessions/), compiled Blade templates (storage/framework/views/), cached configuration (storage/framework/cache/), and uploaded files (storage/app/). Logs are especially dangerous as they may contain user data, API responses, and exception details.
Is the public/storage symlink safe?
The symlink from public/storage to storage/app/public is safe by design. Only files you explicitly place in storage/app/public are accessible. The risk comes from storing sensitive files in the public directory or having the wrong document root that exposes the entire storage directory.
Related Guides
How to Fix an Exposed .env File in Laravel
Your Laravel .env file is publicly accessible, exposing database credentials and API keys. Learn how to block access and secure your secrets.
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.
How to Fix Directory Listing Enabled on Your Web Server
Directory listing is enabled on your web server, exposing file structures and sensitive files to anyone. Learn how to disable it.
Detect This Automatically with StackShield
StackShield continuously monitors your Laravel application from the outside and alerts you when security issues are found. No installation required.
Start Free Trial