New to Flask and was going through a course that describes how to make a REST API.
Author of the course suggested using safe_str_cmp from werkzeug.security in the authentication chapter.
I'd appreciate if someone could help understand what is the purpose of that function and when/why it should be used.
The obvious algorithm to test for string equality is something like this:
def strings_equal(s1, s2):
if len(s1) != len(s2):
return False
for i in range(len(s1)):
if s1[i] != s2[i]:
return False
return True
However, there is a subtle problem with using this algorithm to compare password hashes. The return
from inside the loop makes the algorithm faster when the two strings have different characters near the beginning, and slower when they have the same characters near the beginning.
This makes the comparison vulnerable to a timing attack; by trying a password with a known hash and measuring the average time it takes for the password to be rejected, it is possible for the attacker to statistically determine how many of the same characters there are at the beginnings of both hashes. By trying a sequence of different hashes to successively discover one or two bytes of the real password hash at a time, the attacker can deduce a large portion of it, and then attempt to crack it locally.
The secure string comparison algorithm might look something like this:
# warning: example only! this hasn't been proven secure!
# don't use in real code!
def strings_equal(s1, s2):
if len(s1) != len(s2):
return False
result = True
for i in range(len(s1)):
# use & for non-short-circuiting
result = result & (s1[i] == s2[i])
return result
Since all password hashes using the same hashing algorithm should have the same length, this comparison ideally should always take the same amount of time to compare two hashes, preventing a timing attack. More generally, you should use a secure string comparison function any time you are comparing user input with any secret string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With