Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

[py3] Fixed #17040 -- ported django.utils.crypto.constant_time_compare.

This is a private API; adding a type check is acceptable.
  • Loading branch information...
commit 62954ba04c86c4cea3b17a872ba6a0837730e17d 1 parent 54899d8
@aaugustin aaugustin authored
13 django/utils/
@@ -24,6 +24,7 @@
from django.conf import settings
from django.utils.encoding import smart_bytes
+from django.utils import six
from django.utils.six.moves import xrange
@@ -81,15 +82,21 @@ def get_random_string(length=12,
def constant_time_compare(val1, val2):
- Returns True if the two strings are equal, False otherwise.
+ Returns True if the two bytestrings are equal, False otherwise.
The time taken is independent of the number of characters that match.
+ if not (isinstance(val1, bytes) and isinstance(val2, bytes)):

Breaks CSRF middleware in python 2.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ raise TypeError("constant_time_compare only supports bytes")
if len(val1) != len(val2):
return False
result = 0
- for x, y in zip(val1, val2):
- result |= ord(x) ^ ord(y)
+ if six.PY3:
+ for x, y in zip(val1, val2):
+ result |= x ^ y
+ else:
+ for x, y in zip(val1, val2):
+ result |= ord(x) ^ ord(y)
return result == 0
12 tests/regressiontests/utils/
@@ -6,7 +6,17 @@
import hashlib
from django.utils import unittest
-from django.utils.crypto import pbkdf2
+from django.utils.crypto import constant_time_compare, pbkdf2
+class TestUtilsCryptoMisc(unittest.TestCase):
+ def test_constant_time_compare(self):
+ # It's hard to test for constant time, just test the result.
+ self.assertTrue(constant_time_compare(b'spam', b'spam'))
+ self.assertFalse(constant_time_compare(b'spam', b'eggs'))
+ with self.assertRaises(TypeError):
+ constant_time_compare('spam', 'spam')
class TestUtilsCryptoPBKDF2(unittest.TestCase):
2  tests/regressiontests/utils/
@@ -6,7 +6,7 @@
from .archive import TestBzip2Tar, TestGzipTar, TestTar, TestZip
from .baseconv import TestBaseConv
from .checksums import TestUtilsChecksums
-from .crypto import TestUtilsCryptoPBKDF2
+from .crypto import TestUtilsCryptoMisc, TestUtilsCryptoPBKDF2
from .datastructures import (DictWrapperTests, ImmutableListTests,
MergeDictTests, MultiValueDictTests, SortedDictTests)
from .dateformat import DateFormatTests
Please sign in to comment.
Something went wrong with that request. Please try again.