Security Tip: Store Sensitive Config in .env!

[Tip #3] Laravel's config files are great, but don't forget to put sensitive values (i.e. secrets, passwords, tokens, etc) in your .env file!

Security Tip: Store Sensitive Config in .env!

Laravel provides a robust configuration system. All you need to do is create a .php file in config/ and put an array inside. You can then access the config values anywhere inside your application like this:

$value = config('counter.maximum');

These config files are committed into your version control of choice, and pushed around the world. Plus, if it’s Open Source (or in a public repo), it’ll be there for the world to see. Even if it’s not in a public repo, it’s still going to be there - potentially forever.

Herein lies the problem: Config values committed into version control will live on with the source code. If they are sensitive, this is a HUGE security risk.

If a hacker somehow gains access to your repo - maybe through a miss-configuration, or you’re open sourcing your app, or they hack into one of your other servers with access to your repos - then they can access your code, and they can find your keys…

If they find the keys to your billing platform, can they issue charges or refunds? What about your client data backups store on an S3 bucket somewhere? It’s all bad news from here…

Always store your sensitive config values in a .env file, where it won’t be checked into version control.

Basically, you just need to do this:

>> .env

    BILLING_KEY=5d98c468b5e832e52f2e8d9b31702395b303433d

>> config/services.php

    'billing' => [
        'key' => env('BILLING_KEY'),
    ],

>> app/SomeFile.php

    $service = new Service(config('services.billing.key'));

It may take a few minutes the first time you do it, mostly due to naming, but you’ll find it becomes automatic pretty quickly. You may need to share common local dev values around internally, and configure your deployment scripts to populate .env (or use system-wide env vars), but from a security point of view, the pain is most definitely worth it.

💡
Oh and while you’re at it, make sure your .env file is included in your .gitignore, so it won’t be checked into Git accidently!

(Thanks to David Heremans for this reminder.)

As a guide, some of the config values you will need to secure include:

  • usernames
  • passwords
  • keys (API, encryption, etc)
  • environment specific values
  • internal URLs
  • port numbers

Basically, anything that is unique or not supposed to be publicly accessible.

Don’t believe me?

It happens all the time, and not just with open source projects. Keys are stored in code, which is committed into git, and the repository (or code dump) inevitably ends up on GitHub in a public repo.

It’s such an important problem that GitHub automatically scan public repositories for anything they can identify as a secret: https://docs.github.com/en/code-security/secret-scanning, and AWS have a tool you can use prevent committing secrets too: https://github.com/awslabs/git-secrets.

You can also search for secrets in your repos yourself, which is a great proactive step to take. Check out Security Tip #30: Finding Secrets.


Found this security tip helpful? Don't forget to subscribe to receive new Security Tips each week, and upgrade to a premium subscription to receive monthly In Depth articles, or toss a coin in the tip jar.

Reach out if you're looking for a Laravel Security Audit and Penetration Test or a budget-friendly Security Review, and find me on the various socials through Pinkary. Finally, don't forget to check out Practical Laravel Security, my interactive security course.