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".
Greetings my friends! In an entertaining coincidence1, the top issue I encounter when doing security audits falls perfectly onto a scheduled “In Depth” week, so we’re going to dive deep into #1 → Exposed API Keys & Passwords. This was an unsurprising winner of the top 10, and something I’ve talked about a lot. It’s essential that developers know how to handle environment variables safely, so let’s dig into it!
Top 10 Security Issues in Laravel Security Audits:
#10 → Insufficient Input Validation
#9 → Missing Subresource Integrity (SRI)
#8 → Insufficient Rate Limiting
#7 → Cross-Site Scripting (XSS)
#6 → Outdated & Vulnerable Dependencies
#5 → Insecure Function Use
#4 → Missing Security Headers
#3 → Missing Content Security Policy (CSP)
#2 → Missing Authorisation
#1 → Exposed API Keys & Passwords
🛡️ Thinking about a Laravel Security Audit and Penetration Test this year? I’m now booked out until October and have limited time available in November and December… Book in now before it’s too late! 🕵️
Looking to learn more?
⏩ OWASP Security Tip: A07:2021 – Identification and Authentication Failures
▶️ OWASP In Depth: A05:2021 – Security Misconfiguration
Storing Environment Variables Safely
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.
Committed Secrets into Code?
Keep reading with a 7-day free trial
Subscribe to Securing Laravel to keep reading this post and get 7 days of free access to the full post archives.