Security Tip: Validate Config at Boot

[Tip #126] Rather than checking for essential config when it's used, throw the checks in your Service Provider - you'll know about configuration failures before your users get a weird error.

Security Tip: Validate Config at Boot

A common pattern I've come across to ensure an application has been configured correctly is to throw an exception when a required key isn't set:

if (! config('app.magic.key'))
{
    throw new HttpException(
        statusCode: 500,
        message: 'Required magic key not configured!',
    );
}

These are typically found in one of three places:

  1. Right before the key is accessed / API is called.
  2. In the __construct() of the relevant Controller entry point.
  3. In a Global Middleware class.

However, the problem with options #1 and #2 is simple: it will only fail when a user goes to use the code!

This means the code will probably be deployed and the app running for minutes, hours, days, etc, before an error occurs. The resulting investigation and fix will take longer, and your user will be left with a weird error. 😔

Option #3 runs on all requests, so you'll notice pretty quickly, but now you're adding layers to your request processing - especially if you have a few checks. Plus, it only runs on web requests - you're forgetting queue jobs, console commands, broadcast auth, and potentially even your API, if you add it onto the web middleware group. It's not a great solution. 😑

I would like to propose a fourth option: Add it into your service provider!

If you do something like this:

class AppServiceProvider extends ServiceProvider
{
    // ...
    
    public function boot()
    {
        $this->enforceMagicKeyConfigured();
        // ...
    }
    
    protected function enforceMagicKeyConfigured()
    {
        if (! config('app.magic.key'))
        {
            throw new RuntimeException(
                statusCode: 500,
                message: 'Required magic key not configured!',
            );
        }
    }
}

The config value will be checked any time your app boots up, giving you instant feedback that something is wrong, and you can fix it before it affects your users.

Also, if your app runs any artisan commands during the build & deploy process, it will fail during that process, blocking the build.

For example, this happened to me recently:

Build failed with "Required magic key not configured!"

Cool trick, but how does this relate to security?

The other common pattern I see associated with this is code:

if (config('services.magic.key') == $request->token) {
    // do something sensitive
}

I'll leave you the exercise of figuring out how this could go horribly wrong...


If you found this security tip useful? 👍
Subscribe now to get weekly Security Tips straight to your inbox, filled with practical, actionable advice to help you build safer apps.

Want to learn more? 🤓
Upgrade to a Premium Subscription for exclusive monthly In Depth articles, or support my work with a one-off tip! Your support directly funds my security work in the Laravel community. 🥰

Need a second set of eyes on your code?
Book in a
Laravel Security Audit and Penetration Test today! I also offer budget-friendly Security Reviews too.

Finally, connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.