Security Tip: Only Use env() Within Config Files

[Tip #79] It may be tempting to reach for env() outside your config files, but you may be introducing subtle bugs, or exposing your app to compromise...

Security Tip: Only Use env() Within Config Files

Laravel 11's new skeleton reduces the number of default config files down, and shifts more options directly into the .env file (which we've covered before). As a side effect of this, you might find yourself creating more config options within .env, or even just reaching for the values you've stored in .env more.

If you do need to use the values within your .env file, you need to ensure you only use the env() function within your config/*.php files!

It may be tempting to use env() throughout your app (I've seen it used a lot in Service classes!), and it will usually work fine during development, but the problem comes when your code hits production...

If your config is cached in production, i.e. by running the php artisan config:cache command, then your application will compile your config, including any variables from .env into a cache file, and only load that during requests. Any env() calls throughout the app will return null, because the variable doesn't exist.

This can break things entirely, introduce subtle bugs, or even expose your app to compromise... consider this code:

if ($request->token === env('APP_API_TOKEN')) {
    // do sensitive stuff
}

If config is cached and the user passes an empty string, Laravel will convert it to null, which results in null === null, and the token is completely bypassed!

As was pointed out by Martin Krisell in the comments, this comparison should done using the hash_equals() method instead of the strict equals (===). Not only will hash_equals() protect against timing attacks, but it also requires string inputs, making this harder to exploit.


🥷
Looking to dive deeper into Laravel security? Check out Practical Laravel Security, my hands-on security course that uses interactive hacking challenges to teach you about how vulnerabilities work, so you can avoid them in your own code!
🕵️
Want me to hack into your app and tell you how I did it, so you can fix it before someone else finds it? Book in a Laravel Security Audit and Penetration Test!