minetest / minetest

Minetest is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.42k stars 1.98k forks source link

Passwords storage using SRP vulnerable to offline attack #6858

Closed Nhoya closed 3 years ago

Nhoya commented 6 years ago

As I can see here the player's password is stored in the database as sha1 of plainPassword+name

This end up to be a predictable entry (the player name) + password and a weak algorithm (SHA1)

You should consider migrating to something like Argon2

sfan5 commented 6 years ago

That's legacy compatibility code. We switched to SRP authentication over 2 years ago: 82e35edff52d88dcd64a9bfc9d2c4c93f1341b78

Nhoya commented 6 years ago

SRP is good against eavesdropping attacks the problem is that is not so good against offline attacks (to explain simpler: when you dump the database and can directly bruteforce the hash

sfan5 commented 6 years ago

the problem is that is not so good against offline attacks

could you expand on that?

Nhoya commented 6 years ago

Sure, SRP aim to block what are called Man In the Middle attacks, the problems is that if you have the database you can try a dictionary attack against the hashes https://crypto.stackexchange.com/questions/29771/weakness-of-srp-after-server-compromise

nerzhul commented 6 years ago

Yes we know old passwords are stored without salt. But it's in the compat code and will be removed in some years, we cannot upgrade it efficiently

Nhoya commented 6 years ago

@nerzhul The problem is not only for old password but for current passwords too, as i said to @sfan5 my suggestion is to change the actual SHA2+SRC to Argon2|bcrypt+SRC.

SHA2 is not so secure, has been already proved not secure against dictionary attacks and is weak against plain text attacks just because is not thought for password hashing

est31 commented 6 years ago

As the person who designed and implemented the SRP based authentication, who is to blame for this, let me say a few things:

I refute the claim that SHA2 is broken. It is a legitimate cryptographic hash function. If you have a truly random 18 character password of random characters, with each character representing 6 bits of entropy, you'd have 108 bits of entropy, which is far beyond any bruteforce capabilities even for SHA2. Bitcoin has a hash rate of about 2*10^19 double hashes per second, so you'd need to have the entire bitcoin network run 2 ^ (108 - 65 - 1) seconds on the task to crack such a password (-65 because log2(2*10^19) = about 64 and you need to add 1 bit as bitcoin calculates double hashes, and -1 because on average, you'll have found the password after computing half of the hashes), which is 139 thousand years. You can use the current SHA2 based scheme in a secure way, so it is not broken.

Maybe with "SHA2 [...] has already been broken" you are reffering to SHA1 having a collision? Collisions are irrelevant for use as password functions. The only relevant attack is the second preimage attack, and even MD5 stands strong here. SHA1 and SHA2 standing even stronger.

As @nerzhul pointed out, we are using salts (they are large, 128 random bits), so we are safe from the really evil stuff like rainbow attacks or being able to check the popularity of passwords.

The general "SHA2 is insecure for passwords" mantra is popular inside the security world, but you shouldn't just blindly repeat it, or exaggerate it. Every hash function proposed is vulnerable to offline attacks, including Argon2, PBKDF2, and scrypt. None of them is magically secure. The relevant difference between SHA2 and Argon2 is how many hashes one can compute per second when doing a brute force attack. E.g. with same resources, an attacker can compute 1 million SHA2 hashes in the same time that the attacker can compute one Argon2 hash. Maybe that time is one millisecond, maybe it is one microsecond, maybe a nanosecond, maybe even less. It all depends on the resources that the attacker has access to, but there is nobody preventing the attacker from mounting an attack onto Argon2.

What does that slowdown factor mean in practice? Let's assume that one character for passwords is 6 bits of entropy and that the attacker doesn't mount a dictionary attack. The very same argument applies for dictionary attacks as well, but it is more complex to be put into words so I let's assume a normal bruteforce attack, for the sake of the argument.

If the attacker can try one million as many passwords, it would mean that the password only needs to be 4 characters longer to have the same security level (4 6 = 24 bits -> 2^20 is about one million). With a slowdown factor of one billion, it is 5 characters (5 6 bits = 30 bits -> 2^30 is about one billion).

I'd argue that in practical settings, Argon2 wouldn't be able to get a slowdown factor over the current sha256 algorithm of more than a few ten million. Single cores of CPUs without any acceleration like intel sha extensions can compute less than 20 million sha256 hashes per second, so if Argon2 runs singlecore and is 2 million times as slow, you'd spend more than a tenth second to compute the Argon2 hash. If it runs on 10 cores, and takes the same time, the slowdown factor would be 20 million. A tenth second is a perceivable amount of time and probably you'd want less than that.

Also, the parameter choice for Argon2 is highly hardware dependent. Minetest is precisely the opposite. It is supposed to run on a large set of hardware, including computers and mobile devices. Players should be able to set up their account on their high powered computer, and log in on their smartphone without having to wait 10 seconds. So you'd have to set the parameter defaults to some minimum. Ideally, the parameters would be configurable with a clientside setting, and stored alongside the salt by the server.

Back in the day, I haven't added Argon2 or scrypt or anything else because I wasn't convinced of their advantages. I've since then come to a more moderate view on them, thinking that they do bring advantages but that applying them is in many cases not worth the hassle. In the usual "password being sent to server" use case, HSM's or SGX or similar are better solutions to the offline bruteforce use case, as these make bruteforce attacks completely impossible while not wasting CPU cycles on computing Argon2.

I have left Minetest and usually don't participate in discussions any more. I just wanted to give you an explanation/history lesson why I didn't do it myself back when I've implemented SRP. If you want to add Argon2, be my guest, but this is not like a big security leak or something.

Nhoya commented 6 years ago

First of all @est31 thank you so much for the great and really extensive explanation of the implementation reasons, i can agree with you on lots of points but in the real world the "true random" doesn't exists, and usually in the case of people using random generated passwords (and i think we all know that is a really low percentage) the real entropy is much much lower. My point against SHA2 is that is just a general purpose hashing algorithm, is not designed for passwords. I know that using this kind of algorithms will be a "great things" for slower computers because are really fast and don't waste much CPU but this is not a good point in case of offline attacks.

Again, thank you for explaining me your arguments i appreciate it

raymoo commented 6 years ago

@Nhoya

My point against SHA2 is that is just a general purpose hashing algorithm, is not designed for passwords.

This is false, SHA2 is designed as a cryptographic hash function. It is designed for passwords, just not them specifically.

raymoo commented 6 years ago

@Nhoya If you want to show that Argon / bcrypt would be more secure, then you need to demonstrate that the running time for a SHA2 dictionary attack would be at feasible levels. Without that, there is really nothing else to go off of.

Nhoya commented 6 years ago

@raymoo

This is false, SHA2 is designed as a cryptographic hash function. It is designed for passwords, just not them specifically.

Cryptographic hash function != designed for passwords

If you want to show that Argon / bcrypt would be more secure, then you need to demonstrate that the running time for a SHA2 dictionary attack would be at feasible levels. Without that, there is really nothing else to go off of.

1) https://medium.com/@davidtstrauss/stop-using-sha-256-6adbb55c608

2) https://security.stackexchange.com/questions/90064/how-secure-are-sha256-salt-hashes-for-password-storage

3) https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords (Note: this answer is from 2010)

4) https://security.stackexchange.com/questions/133239/what-is-the-specific-reason-to-prefer-bcrypt-or-pbkdf2-over-sha256-crypt-in-pass

5) https://security.stackexchange.com/questions/16354/whats-the-advantage-of-using-pbkdf2-vs-sha256-to-generate-an-aes-encryption-key

6) https://stackoverflow.com/questions/36444414/can-i-store-sha256-hashed-passwords-in-plain-text