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!
👉 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! 🕵️
✨ Worried about your app being hacked? Book in a Laravel Security Audit and Penetration Test! I can find the vulnerabilities before a hacker does, and help you fix them! 🕵️
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 world1. 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 repos2 - 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 gotta 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 naming3, 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!4
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.
To finish up, I saw this Tweet:
The thread is worth reading to see all the senior devs jumping in to talk about when they've done this. I’ve sure I’ve done it before too!
It’s an easy mistake to make, and one we need to learn from.
Most likely via GitHub.
You may have bigger problems in this scenario though…
Which can be the hardest part of the whole process!
Thanks to David Heremans for the reminder to check this too.