Laravel Writable Config Files: How to Set Read-Only Permissions on Configuration
Config files writable by the web server can be modified by an attacker who gains limited access. Set them to read-only to prevent configuration tampering.
The Problem
If your config/ directory or individual configuration files are writable by the web server user (www-data, nginx, etc.), an attacker who gains limited code execution — through a file upload vulnerability, deserialization attack, or compromised dependency — can modify your application configuration. They could change the database connection to their own server, redirect mail to their address, disable security features, or add their own service credentials.
How to Fix
-
1
Set config files to read-only
Make config files readable but not writable by the web server:
chmod 644 config/*.php chmod 755 config/# Verify ls -la config/ # Files should show -rw-r--r-- (644) # Directory should show drwxr-xr-x (755)The web server needs to read config files but never write them.
-
2
Set correct ownership
Config files should be owned by your deploy user, not the web server:
chown -R deploy:www-data config/# deploy user can read/write (for deployments) # www-data group can only read (for serving)This way, even if the web server process is compromised, it cannot modify configuration.
-
3
Use config:cache in production
Cached configuration is loaded from a single compiled file, reducing filesystem access:
php artisan config:cacheThis creates bootstrap/cache/config.php. In production, Laravel reads this cached file instead of scanning the config/ directory. This also provides a small performance benefit.
Run php artisan config:cache as part of every deployment.
How to Verify
Check file permissions:
find config/ -type f -perm -o+w
This should return no results. Also verify the web server user cannot write:
sudo -u www-data touch config/test.php 2>&1
# Should output: Permission denied
Run php artisan stackshield:scan --check=SS057 to verify.
Prevention
Set permissions in your deployment script. Use config:cache to minimize filesystem access. Never run artisan commands as the web server user in production. Include permission checks in your deployment pipeline.
Frequently Asked Questions
What about .env — should it be read-only too?
Yes. The .env file should be 600 (owner read/write only) or 640 (owner read/write, group read). The web server needs to read it (or it is read once during config:cache), but it should never be writable by the web server process.
Does config:cache make config files completely unnecessary?
No. The config files are still needed for: (1) generating the cache (config:cache reads them), (2) local development (where you typically do not cache config), and (3) re-caching after .env changes. Keep them in your deployment but with read-only permissions.
Related Security Terms
Related Guides
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.
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.
Laravel Debug Mode in Production: How to Disable APP_DEBUG and Stop Leaking Secrets
APP_DEBUG=true in production exposes stack traces, environment variables, and database credentials to anyone who triggers an error. Here is how to disable it safely and verify the fix.
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