Use constant time string comparisons for auth.
Fix bug 942644. Use constant time string comparisons when doing authentication to help guard against timing attacks. Change-Id: I88c4c5cd9edd9e5d60db07b6ae2638b74a2a2e17
This commit is contained in:
parent
85ee3aa9d5
commit
1f0798f4fb
@ -110,7 +110,7 @@ from time import gmtime, strftime, time
|
||||
from time import time
|
||||
from urllib import quote, unquote
|
||||
|
||||
from swift.common.utils import get_logger
|
||||
from swift.common.utils import get_logger, strcmp_const_time
|
||||
|
||||
|
||||
#: The size of data to read from the form at any given time.
|
||||
@ -442,7 +442,8 @@ class FormPost(object):
|
||||
attributes.get('expires') or '0'
|
||||
)
|
||||
sig = hmac.new(key, hmac_body, sha1).hexdigest()
|
||||
if sig != (attributes.get('signature') or 'invalid'):
|
||||
if not strcmp_const_time(sig,(attributes.get('signature') or
|
||||
'invalid')):
|
||||
return '401 Unauthorized', 'invalid signature'
|
||||
subenv['swift.authorize'] = lambda req: None
|
||||
subenv['swift.authorize_override'] = True
|
||||
|
@ -1117,3 +1117,23 @@ def listdir(path):
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
return []
|
||||
|
||||
|
||||
def strcmp_const_time(s1, s2):
|
||||
"""Constant-time string comparison.
|
||||
|
||||
:params s1: the first string
|
||||
:params s2: the second string
|
||||
|
||||
:return: True if the strings are equal.
|
||||
|
||||
This function takes two strings and compares them. It is intended to be
|
||||
used when doing a comparison for authentication purposes to help guard
|
||||
against timing attacks.
|
||||
"""
|
||||
if len(s1) != len(s2):
|
||||
return False
|
||||
result = 0
|
||||
for (a, b) in zip(s1, s2):
|
||||
result |= ord(a) ^ ord(b)
|
||||
return result == 0
|
||||
|
@ -850,6 +850,11 @@ log_name = %(yarr)s'''
|
||||
for v in utils.TRUE_VALUES:
|
||||
self.assertEquals(v, v.lower())
|
||||
|
||||
def test_strcmp_const_time(self):
|
||||
self.assertTrue(utils.strcmp_const_time('abc123', 'abc123'))
|
||||
self.assertFalse(utils.strcmp_const_time('a', 'aaaaa'))
|
||||
self.assertFalse(utils.strcmp_const_time('ABC123', 'abc123'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user