Skip to content

Commit 93a8115

Browse files
authored
Avoid user-not-found timing attacks w/ dummy hash (#15)
Now that we have dropped passlib, this reimplements passlib's dummy verify feature to maintain the same security posture. See: https://github.com/StackStorm/st2-auth-backend-flat-file/pull/14/files/f1b09ea9a12f49c14b6572c15410506e57544672#r2341493677
2 parents 33b6711 + b58759a commit 93a8115

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

st2auth_flat_file_backend/flat_file.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636

3737
LOG = logging.getLogger(__name__)
3838

39+
# dummy pw is "testpassword" (used when user not found to avoid timing attacks)
40+
DUMMY_HASH_DATA = "$2y$05$Vhvhbk0SYN3ncn9BSvXEHunzztBWfrwqOpX1D0GhrFvM1TcADpKoO"
41+
3942

4043
class HtpasswdFile(object):
4144
"""
@@ -71,10 +74,10 @@ def _load_file(self):
7174
self.entries[username] = hash_data
7275

7376
def check_password(self, username, password):
77+
encode_local = locale.getpreferredencoding()
78+
pw = bytes(password, encoding=encode_local)
7479
if username in self.entries:
7580
hash_data = self.entries[username]
76-
encode_local = locale.getpreferredencoding()
77-
pw = bytes(password, encoding=encode_local)
7881
if hash_data.startswith("$apr1$"):
7982
LOG.warning(
8083
"%s uses MD5 algorithm to hash the password."
@@ -103,7 +106,8 @@ def check_password(self, username, password):
103106
)
104107
return compare_hash(crypt.crypt(password, hash_data), hash_data)
105108
else:
106-
# User not found.
109+
# User not found. Do a dummy hash to avoid timing attacks.
110+
_ = bcrypt.checkpw(pw, bytes(DUMMY_HASH_DATA, encoding=encode_local))
107111
return None
108112

109113

0 commit comments

Comments
 (0)