# 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.

**Severity:** medium | **Category:** Infrastructure Security

---

## The Issue

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.

## Steps 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:cache

This 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.

## Verification

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.

