I work on a few apps in rails, django (and a little bit of php), and one of the things that I started doing in some of them is storing database and other passwords as environment variables rather than plain text in certain config files (or in settings.py, for django apps).
In discussing this with one of my collaborators, he suggested this is a poor practice - that perhaps this isn't as perfectly secure as it might at first seem.
So, I would like to know - is this a secure practice? Is it more secure to store passwords as plain text in these files (making sure, of course, not to leave these files in public repos or anything)?
On a more theoretical level, I tend to think about levels for security in the following ways (in order of increasing strength) :
- No security. Plain text. Anyone that knows where to look, can access the data.
- Security by Obfuscation. You store the data (plaintext) someplace tricky, like an environment variable, or in a file that is meant to look like a configuration file. An attacker will eventually figure out what's going on, or stumble across it.
- Security provided by encryption that is trivial to break, (think caesar cipher!).
- Security provided by encryption that can be broken with some effort.
- Security provided by encryption that is impractical to break given current hardware.
- The most secure system is one that nobody can use! :)
Environment variables are more secure than plaintext files, because they are volatile/disposable, not saved;
i.e. if you set only a local environment variable, like "set pwd=whatever," and then run the script,
with something that exits your command shell at the end of the script, then the variable no longer exists.
Your case falls into the first two, which I'd say is fairly insecure. If you were going to do this, I wouldn't recommend deploying outside your immediate intranet/home network, and then only for testing purposes.
As mentioned before, both methods do not provide any layer of additional "security" once your system is compromised. I believe that one of the strongest reasons to favor environment variables is version control: I've seen way too many database configurations etc. being accidentially stored in the version control system like GIT for every other developer to see (and whoops! it happened to me as well ...).
Not storing your passwords in files makes it impossible for them to be stored in the version control system.
Anytime you have to store a password, it is insecure. Period. There's no way to store an un-encrypted password securely. Now which of environment variables vs. config files is more "secure" is perhaps debatable. IMHO, if your system is compromised, it doesn't really matter where it's stored, a diligent hacker can track it down.
Sorry I didn't have enough rep to comment, but I also wanted to add that if you're not careful, your shell might capture that password in it's command history as well. So running something like $ pwd=mypassword my_prog
manually isn't as ephemeral as you might have hoped.
It depends on your threat model.
Are you trying to prevent your users from sprinkling passwords all over their file systems where they are likely to be forgotten and mishandled? If so, then yes, because environmental variables are less persistent than files.
Are you trying to secure against something malicious that is directly targeting your program? If so, then no, because environment variables do not have the same level of access control that files do.
Personally, I think that negligent users are more common than motivated adversaries, so I'd go with the environment variable approach.