mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-25 06:48:01 -05:00
Use constant-time string comparison for auth.
This commit is contained in:
committed by
Neil Williams
parent
9344853401
commit
83058d48ce
@@ -1342,3 +1342,19 @@ def thread_dump(*a):
|
||||
% dict(filename=filename, lineno=lineno, fnname=fnname))
|
||||
sys.stderr.write('\t\t\t%(line)s\n' % dict(line=line))
|
||||
|
||||
|
||||
def constant_time_compare(actual, expected):
|
||||
"""
|
||||
Returns True if the two strings are equal, False otherwise
|
||||
|
||||
The time taken is dependent on the number of charaters provided
|
||||
instead of the number of characters that match.
|
||||
"""
|
||||
actual_len = len(actual)
|
||||
expected_len = len(expected)
|
||||
result = actual_len ^ expected_len
|
||||
if expected_len > 0:
|
||||
for i in xrange(actual_len):
|
||||
result |= ord(actual[i]) ^ ord(expected[i % expected_len])
|
||||
return result == 0
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ from r2.lib.db.userrel import UserRel
|
||||
from r2.lib.memoize import memoize
|
||||
from r2.lib.utils import modhash, valid_hash, randstr, timefromnow
|
||||
from r2.lib.utils import UrlParser, set_last_visit, last_visit
|
||||
from r2.lib.utils import constant_time_compare
|
||||
from r2.lib.cache import sgm
|
||||
from r2.lib.log import log_text
|
||||
|
||||
@@ -550,9 +551,9 @@ def valid_cookie(cookie):
|
||||
except NotFound:
|
||||
return (False, False)
|
||||
|
||||
if cookie == account.make_cookie(timestr, admin = False):
|
||||
if constant_time_compare(cookie, account.make_cookie(timestr, admin = False)):
|
||||
return (account, False)
|
||||
elif cookie == account.make_cookie(timestr, admin = True):
|
||||
elif constant_time_compare(cookie, account.make_cookie(timestr, admin = True)):
|
||||
return (account, True)
|
||||
return (False, False)
|
||||
|
||||
@@ -563,7 +564,7 @@ def valid_feed(name, feedhash, path):
|
||||
try:
|
||||
user = Account._by_name(name)
|
||||
if (user.pref_private_feeds and
|
||||
feedhash == make_feedhash(user, path)):
|
||||
constant_time_compare(feedhash, make_feedhash(user, path))):
|
||||
return user
|
||||
except NotFound:
|
||||
pass
|
||||
@@ -590,17 +591,21 @@ def valid_login(name, password):
|
||||
|
||||
def valid_password(a, password):
|
||||
try:
|
||||
if a.password == passhash(a.name, password, ''):
|
||||
# A constant_time_compare isn't strictly required here
|
||||
# but it is doesn't hurt
|
||||
if constant_time_compare(a.password, passhash(a.name, password, '')):
|
||||
#add a salt
|
||||
a.password = passhash(a.name, password, True)
|
||||
a._commit()
|
||||
return a
|
||||
else:
|
||||
salt = a.password[:3]
|
||||
if a.password == passhash(a.name, password, salt):
|
||||
if constant_time_compare(a.password, passhash(a.name, password, salt)):
|
||||
return a
|
||||
except AttributeError, UnicodeEncodeError:
|
||||
return False
|
||||
# Python defaults to returning None
|
||||
return False
|
||||
|
||||
def passhash(username, password, salt = ''):
|
||||
if salt is True:
|
||||
|
||||
Reference in New Issue
Block a user