5

I read a couple articles on privacy/security but still cannot get a clear picture of the best practice to ensure that an attacker will not be able to access users' private information.

For storing passwords or other data that will be checked only to verify authenticity, I understand that hashing algorithms like SHA-256 are perfect candidates as the password itself doesn't need to be stored (or even known) on the server-side.

However in my case, in addition to the password, I allow users to store other secrets that the server needs to be able to decrypt for background work that will read these secrets to provide historical stats, without the user to be logged in. These "secrets" are usually api keys to external services, that could be dangerous if in the wrong hands.

A possible solution would have been to use the user session or cookies to store the secrets, but in addition to being subject to cookies or session hijacks, it requires the user to be logged in to work, and in my case I need the server to be able to decrypt and use the secrets for background tasks without the user being logged in.

So another solution would be to encrypt the secrets in the database using for example AES-256 and keeping the encryption passphrase outside the database. If the attacker gets access to the database, he cannot decrypt the user secrets. If the attacker gets access to the server's filesystem, he gets access to the passphrase, but not the DB... oh, wait a minute, why not the DB? If the attacker gets access to the server's filesystem, including config, he also gets access to the database as the connection strings are also in the config on the filesystem. So if the attacker gets access to the filesystem, he gets access to the passphrase AND the db...

I can't think of any solution to truly separate the passphrase from the db. Am I missing something? Is there any real solution to protect user secrets so that at least 2 different systems (DB / files) have to be hacked to get access the secrets, knowing that the server needs to be able to encrypt/decrypt the secrets without users help?

My project will be running in the cloud with nodejs as web server and mongodb as database and before opening it to the public I'd like to ensure it will be almost impossible for an attacker to retrieve the users secrets, which doesn't seem to be the case.

Edit: Instead of storing the passphrase in the config, I could actually pass it in the command when starting the web server (nodejs in my case). So instead of reading the passphrase from the flat config file, it reads it from the command-line. Doing that would ensure the passphrase is never written in a file (assuming I can disable the bash history) and is only in memory, which is harder to hack isn't it? The only drawback is that I need to manually start the server if it goes down, as starting automatically will start without knowing the passphrase (so I need to start it myself). But would it work? Is that a known and used practice?

Thomas
  • 153
  • 1
  • 5
  • 1
    If you're hacked, all the hacker needs is admin access to dump your RAM... not too hard. – KnightOfNi Jan 28 '14 at 23:29
  • 3
    SHA-256 is not a perfect candidate for hashing passwords. [Bcyrpt or pbkdf2 are appropriate for hashing passwords](https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords). – Todd Feb 07 '15 at 13:44
  • @Todd exactly. Bcrypt is efficient. – Shritam Bhowmick Oct 26 '16 at 06:16

1 Answers1

1

You're right that there isn't a great solution.

Yes, entering via CLI and storing in RAM is sometimes used, but dumping ram isn't too hard. There are hardware security modules that specialize in this scenario (research this term if this problem is important enough).

Generally speaking, it's best to store it in a folder which has its permissions very restricted, then focus on hardening the server so the attacker has to do two difficult things (exploit a service, then escalate privileges). Don't store it in the database or in a directory accessible to the web user.

Encrypting it using AES would be good. If the attacker can control the plaintext or observe the ciphertext in any scenarios you'll want to take much greater precautions to ensure it's implemented correctly.

Alex Lauerman
  • 445
  • 4
  • 8
  • 1
    Thanks Alex. I was not aware how easy it is to dump the RAM, very interesting, thanks. After checking a little further, I will go for a solution close to the protected folder but using environment variables, which seems to be the way to go in cloud environments. – Thomas Jan 30 '14 at 04:34
  • @Thomas, I'm guessing you have looked into this, but be sure the environment variables you're setting are not publicly accessible. It sounds like they are publicly accessible in linux, but not windows (user environment variables of course). http://stackoverflow.com/questions/12461484/is-it-secure-to-store-passwords-as-environment-variables-rather-than-as-plain-t – Alex Lauerman Jan 31 '14 at 02:26
  • Yes, I will use per-user config vars, which seems to be the way to go on the service I plan to use (example with S3 Key/Secret): https://devcenter.heroku.com/articles/config-vars – Thomas Jan 31 '14 at 05:26