mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #19980: Signer broken for binary keys (with non-ASCII chars).
With this pull request, request #878 should considered closed. Thanks to nvie for the patch.
This commit is contained in:
		| @@ -76,7 +76,8 @@ def base64_hmac(salt, value, key): | ||||
|  | ||||
| def get_cookie_signer(salt='django.core.signing.get_cookie_signer'): | ||||
|     Signer = import_string(settings.SIGNING_BACKEND) | ||||
|     return Signer('django.http.cookies' + settings.SECRET_KEY, salt=salt) | ||||
|     key = force_bytes(settings.SECRET_KEY) | ||||
|     return Signer(b'django.http.cookies' + key, salt=salt) | ||||
|  | ||||
|  | ||||
| class JSONSerializer(object): | ||||
| @@ -148,9 +149,9 @@ class Signer(object): | ||||
|  | ||||
|     def __init__(self, key=None, sep=':', salt=None): | ||||
|         # Use of native strings in all versions of Python | ||||
|         self.sep = str(sep) | ||||
|         self.key = str(key or settings.SECRET_KEY) | ||||
|         self.salt = str(salt or | ||||
|         self.sep = force_str(sep) | ||||
|         self.key = key or settings.SECRET_KEY | ||||
|         self.salt = force_str(salt or | ||||
|             '%s.%s' % (self.__class__.__module__, self.__class__.__name__)) | ||||
|  | ||||
|     def signature(self, value): | ||||
|   | ||||
| @@ -36,10 +36,13 @@ def salted_hmac(key_salt, value, secret=None): | ||||
|     if secret is None: | ||||
|         secret = settings.SECRET_KEY | ||||
|  | ||||
|     key_salt = force_bytes(key_salt) | ||||
|     secret = force_bytes(secret) | ||||
|  | ||||
|     # We need to generate a derived key from our base key.  We can do this by | ||||
|     # passing the key_salt and our base key through a pseudo-random function and | ||||
|     # SHA1 works nicely. | ||||
|     key = hashlib.sha1((key_salt + secret).encode('utf-8')).digest() | ||||
|     key = hashlib.sha1(key_salt + secret).digest() | ||||
|  | ||||
|     # If len(key_salt + secret) > sha_constructor().block_size, the above | ||||
|     # line is redundant and could be replaced by key = key_salt + secret, since | ||||
|   | ||||
| @@ -2,6 +2,7 @@ from __future__ import unicode_literals | ||||
|  | ||||
| import time | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core import signing | ||||
| from django.http import HttpRequest, HttpResponse | ||||
| from django.test import TestCase | ||||
| @@ -62,3 +63,18 @@ class SignedCookieTest(TestCase): | ||||
|                 request.get_signed_cookie, 'c', max_age=10) | ||||
|         finally: | ||||
|             time.time = _time | ||||
|  | ||||
|     def test_signed_cookies_with_binary_key(self): | ||||
|         def restore_secret_key(prev): | ||||
|             settings.SECRET_KEY = prev | ||||
|  | ||||
|         self.addCleanup(restore_secret_key, settings.SECRET_KEY) | ||||
|  | ||||
|         settings.SECRET_KEY = b'\xe7' | ||||
|  | ||||
|         response = HttpResponse() | ||||
|         response.set_signed_cookie('c', 'hello') | ||||
|  | ||||
|         request = HttpRequest() | ||||
|         request.COOKIES['c'] = response.cookies['c'].value | ||||
|         self.assertEqual(request.get_signed_cookie('c'), 'hello') | ||||
|   | ||||
| @@ -105,6 +105,12 @@ class TestSigner(TestCase): | ||||
|             self.assertRaises( | ||||
|                 signing.BadSignature, signing.loads, transform(encoded)) | ||||
|  | ||||
|     def test_works_with_non_ascii_keys(self): | ||||
|         binary_key = b'\xe7'  # Set some binary (non-ASCII key) | ||||
|  | ||||
|         s = signing.Signer(binary_key) | ||||
|         self.assertEquals('foo:6NB0fssLW5RQvZ3Y-MTerq2rX7w', s.sign('foo')) | ||||
|  | ||||
|  | ||||
| class TestTimestampSigner(TestCase): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user