I work for a healthcare company that emphasizes security, due to the sensitivity of the data that we work with. Recently, we've been doing a lot of auditing (internal and external) of our current "stack" to ensure that we're compliant with various client requirements.

One recent topic of discussion is around environment variables. We use the dotenv gem, so we're storing many of these variables in a .env file (ignored in git) on the web server. These variables include our database credentials, SMTP credentials, and various API keys.

When certain leadership learned that such credentials were stored on the web server in plain-text they expressed concern. That concern has sparked discussion around encrypting those variables. I see the merits of encryption and it would certainly be valuable for protecting our API keys and the like. However I question the value it offers for protecting the data stored on our DB server (which is ultimately the biggest concern)... what we're talking about here is a malicious user gaining access to our web server. Unless I'm missing something, that user could still open a rails console, which will load the application, handling decryption of the credentials, and allow them to query the DB using our models (Patient.all, for example). It just seems to me that if our web server is compromised we're hosed regardless of whether we encrypted those variables. Am I right about that?

Assuming that I am, how do I respond to this inquisition with something more concrete than "well, that's just how Rails works" (with regards to being able to open a connection to the DB via rails c)?


What matters here is a question of threats and of defense lines. The threats I can imagine are:

  • a vulnerability in the web server allows an attacker to read files from the web application folders
  • a vulnerability in the web server allows an attacker to read the environment variables of the application
  • a vulnerability in the web server allows an attacker to execute arbitrary commands on behalf of the legitimate app
  • a vulnerability in the server (independantly of the web application) allows an attacker to gain access to the server

Then, you have 2 possible defense lines (ideally you should combine both)

  1. reduce the exposition risk

    • ensure that the web application stack is consistenly patched
    • ensure that the web application is hidden behind a reverse proxy: this can help to ensure that only HTTP requests to acceptable URLs can reach the server - the URL rewriting of the proxy can map incoming URLs to a subpath to guarantee that no URL at root can be received
    • ensure the datacenter is correctly protected behind a firewall and all servers follow best practice rules (limited admin accesses, only required ports open, etc.)
  2. reduce the possible consequences of a successful attack

    • setup log analyzis to detect illicit access and reduce to time window of an attack
    • If the attacker could read the environment variable - but cannot execute any command - ensure that the database server is not reachable from the outside of the datacenter
    • if the data is highly sensitive, you can even protect access to the database even if the web application server was compromised by using an API requiring a previous client authentication and pass the client token to a service appplication server that can do authorization controls. The full defense becomes here:

      external_firewall - reverse_proxy - web_server - internal_firewal- application_server

Encryption on the server can only be obfuscation, because the decryption key must be accessible somewhere. It can only harden the task for the attacker, but will not be able to block him.


The problem you've got is that environment variables can leak in some circumstances that are less serious than an attacker actually getting interactive shell access to your host (a good article describing some of the possible risks is "Environment Variables Considered Harmful for Your Secrets" . Also storing secrets in plain text can present risks of an attacker getting access to the unmounted disk, from backups or similar.

As one example, I'm presuming that you backup the .env file in some way, so there's a risk of unauthorised access to that backup.

One things that you consider looking at is a "secrets management" solution to help manage things like this. Things like Hashicorp Vault or, if you're using Docker, you could use Docker secrets


You're right to consider those other methods of entry into the unencrypted data. However, often attackers don't gain full access to a server, but only partial, and that is the real thing that this would protect against. For instance, there might be a vulnerability in your app that allows an attacker to view a dump of all the environment variables available to the app (something akin to an unprotected phpinfo(), but for Rails); that would give them access if the environment variables are unencrypted, but place a roadblock if they're encrypted.

Thinking through various scenarios to come up with exactly what you're actually protecting against is a great way to evaluate any proposed security feature. These sorts of "protect against an attacker who can only do this one limited thing, but not this other thing" improvements can sometimes be useful, but sometimes provide a lot of complexity for essentially no real-world benefit; writing out your assumptions makes it a bit clearer and easier to evaluate whether it makes sense for your organization or not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.