Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the purpose of safe_string_cmp?

Tags:

werkzeug

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.

like image 961
Rotkiv Avatar asked Dec 01 '19 23:12

Rotkiv


1 Answers

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.

like image 137
kaya3 Avatar answered Sep 16 '22 15:09

kaya3