I see a timing attack in the list. It's fairly trivial to mitigate against this in the majority of languages nowadays [1] [2] [3] etc..
I presume this can also be mitigated by implementing rate limiting on your authentication endpoints, although that should also be implemented for other reasons.
That's still broken. They've just pushed the problem deeper. Now instead of having a timing attack on the number of operations in the compare, the timing attack is pushed to the number of bytes that is hashed by sha256. Also, this opens up a new avenue in that now hash collisions (as unlikely as they may be) would be considered equal.
This is considered best practice for languages where you can't trust your "constant time" comparison won't be optimized out from under you.
Performing a timing attack requires control of the bytes being compared. If you can control the bytes of the output of a SHA256 then there are some Bitcoin miners who will pay you a lot of money.
If you want to be over-the-top about it you can get some secure randomness and add it to the values being compared before hashing, and then attacker would have even less control over the bytes being compared.
You don't need to control every byte for this to be catastrophic. You can't decode every password like you can with the previous comparison, but if you can generate a rainbow table that contains the password you're trying to crack, you can just do a timing attack using the hashes instead. My intuition is that this might even require fewer attempts than the original comparison assuming a reasonable password length, but I haven't done the math.
Yes, this is true if you are talking about unsalted passwords, or if the attacker knows the salts. If there's an unknown salt, having the salted hash of a given plaintext input match the first few bytes of the target salted hash does not help you narrow the word list at all. If there is no salt, or the salt is public, then that's a case where you could append some ephemeral CS-PRNG output to both sides before hash-comparing... but probably better to fix the underlying issue.
I mean, it's funny to be far enough down the rabbit hole to be doing hash-compare. Then to say we wanted randomly keyed hash-compare is the final step. The nice thing is adding some random bytes imposes a fairly miniscule performance hit and it's purely computation, no additional storage. Probably still too slow to use for every comparison, but for constant-time critical comparison, it literally can't hurt.
https://github.com/rails/rails/commit/859ca4474e1608b83d6194...