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.

Medium severity Infrastructure Security Updated 2026-05-01

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

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

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