3
votes

Thinking about how big sites usually have you log in, there seems to be a point in time where company servers have your password in memory in plain text. Is this true, and is it safe?

This is something like how most big sites have you log in:

  1. Enter password in browser
  2. Encrypt password in-browser using asymmetric encryption public key
  3. Send password to site
  4. Decrypt password using asymmetric encryption private key
  5. Hash password using one-way hashing algorithm (and salt)
  6. Compare hashed password to similarly hashed password in database
  7. If hashes match, successful log in. Otherwise, failed log in.

Look between steps 4 and 5

  1. Decrypt password using asymmetric encryption private key

    4.5. Briefly have some variable server-side with plain text password

  2. Hash password using one-way hashing algorithm (and salt)

This means that while the whole hashing scheme is to prevent an attacker from gaining access to passwords EVEN IF the server is compromised, a skilled hacker could get at it anyway.

Is there something I missed? More importantly, is there a safer alternative?

3
Need any more help with this? If so I'll update my answer.SilverlightFox
@SilverlightFox If you wouldn't mind adding some more information, I'd definitely appreciate it. My real area of focus here is security even on a compromised machine.TheEnvironmentalist
Sure, done. Please let me know if you need anything further.SilverlightFox
@TheEnvironmentalist Afaik. security is about preventing attackers to compromise the server. If they are in, it is only a matter of time before they can read your passwords. You cannot protect memory. All you can do is setting user privileges properly and try to detect the intruders in time. Note this is only my layman impression, probably others know this better.inf3rno

3 Answers

3
votes

Yes it is "safe" since whatever is in memory is in your server's memory and should not be able to be read externally.

Safe is in quotes as everything is relative and the risk level depends on your perceived threat model - i.e. what threats are you trying to defend against?

The much publicised Heartbleed bug allowed attackers to retrieve items from servers' memory in 64KB chunks. However, the strategy here is to have a vulnerability management (patching process) in place rather than coding round these types of problems.

Regarding encrypting passwords - this is something you should rely on HTTPS for rather than encrypting them on the client in Javascript. When they arrive on your server store and compare them in hashed format using a slow algorithm such as bcrypt, scrypt or pbkdf2. Also use cookies marked with the secure & http only flags, implement a HSTS policy and you should be good to go on the password storage and transmission front.

CERT's advice regarding handling sensitive data in memory is here.

The parts most relevant to your question are:

  • Disable memory dumps.
  • Do not store sensitive data beyond its time of use in a program.
  • Do not store sensitive data in plaintext (either on disk or in memory).
  • If you must store sensitive data, encrypt it first.
  • Securely erase sensitive data from disk and memory.

This means that while the whole hashing scheme is to prevent an attacker from gaining access to passwords EVEN IF the server is compromised, a skilled hacker could get at it anyway.

Remember that having a secure system does not only mean you need to have secure coding practises and secure infrastructure. This is because you can never have 100% security. Part of the puzzle that this would be missing is any form Intrusion Detection/Prevention (IDS/IPS). This takes the view that systems will be compromised at some point, so rather than trying to prevent every conceivable type of attack, you instead detect it, allowing you to take appropriate immediate action. This would cover you in the event that an attacker managed to compromise your system and started to harvest credentials as they arrive during the login process.

1
votes

You're correct. The remote attacker would have to change the code though. This can be easily done for PHP, but not so for compiled languages. Obfuscated PHP code also has a place in hindering the attacker in their endeavor.

Sometimes even compiled or obfuscated code cannot stop the attack when the attacker is one of the developers.

Note that multi-party communication and zero-knowledge proofs can be probably subverted in the same way when used for user authentication. I don't think there is really an alternative besides making it really hard for the attacker to break into your server.

0
votes

This is something like how most big sites have you log in

Actually, I have never seen any sites encrypt the password client-side. Encrypting on the client and then decrypting it on the server gains absolutely nothing. That's what SSL certificates are for. Almost all sites I've ever seen in my life just send the password in plain text to the server and then hash it there (we hope).

If you are trying to prevent the server from ever having the plain text password in memory, you could hash it client-side and then hash the hash on the server. Just keep in mind that when you hash a password on the client, the hash actually becomes the password.