In Depth: Storing Environment Variables Safely
[InDepth#17] Let's dive deep into the wonderful world of storing environment variables safely, looking at the different options Laravel supports and some "industry best practices".
#1 → Exposed API Keys & Passwords
#2 → Missing Authorisation
#3 → Missing Content Security Policy (CSP)
#4 → Missing Security Headers
#5 → Insecure Function Use
#6 → Outdated & Vulnerable Dependencies
#7 → Cross-Site Scripting (XSS)
#8 → Insufficient Rate Limiting
#9 → Missing Subresource Integrity (SRI)
#10 → Insufficient Input Validation & Mass-Assignment Vulnerabilities
Environment Variables (or env-vars) can be configuration values, API keys, encryption keys, admin emails, service (i.e. database, cache, etc) credentials, secrets, tokens, flags, etc, or really anything else you need to define in that specific environment, or that shouldn’t live in committed code. Some environment variables are highly sensitive and need to be protected, while others are only there so they can be easily defined and changed.
In Laravel, environment variables are stored by default in the .env
file, and loaded automatically by the framework. You access them using the env()
helper method, typically only within your config/*.php
files.
Now it’s easy to stop here and say “always put your sensitive variables in your `.env`
file” and be done2, but that’s nowhere near the end of the story.
What if…
- You accidently committed secrets into your code?
- You need to track changes to secrets over time?
- A third-party tool requires environment variables but doesn’t provide a way to securely manage them?
- You want to store secrets in a dedicated secrets manager with hardware-level encryption?
- Someone manages to read your
.env
file? - Someone tells you
.env
files aren’t secure?
As you can see, there is a lot more to this topic than merely using a .env
file! So let’s dig into it, and answer each of those questions! (There is a summary at the end.)
Note, I’ve written about environment variables and secrets many times. I’ll link through to older articles as we go, or you can find the full list at here.
Terminology: I’ll be using the term “secrets” throughout this article to refer to anything sensitive you’d store in your .env
file, such as API keys, encryption keys, database and cache credentials, etc.