Fixed #22804 -- Added warning for unsafe value of 'sep' in Signer

Thanks Jaap Roes for completing the patch.
This commit is contained in:
David Wolever 2014-06-09 18:15:21 -04:00 committed by Tim Graham
parent 6bd8462380
commit 0d71349773
4 changed files with 33 additions and 1 deletions

View File

@ -38,15 +38,20 @@ from __future__ import unicode_literals
import base64 import base64
import datetime import datetime
import json import json
import re
import time import time
import warnings
import zlib import zlib
from django.conf import settings from django.conf import settings
from django.utils import baseconv from django.utils import baseconv
from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.deprecation import RemovedInDjango110Warning
from django.utils.encoding import force_bytes, force_str, force_text from django.utils.encoding import force_bytes, force_str, force_text
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
_SEP_UNSAFE = re.compile(r'^[A-z0-9-_=]*$')
class BadSignature(Exception): class BadSignature(Exception):
""" """
@ -150,8 +155,11 @@ class Signer(object):
def __init__(self, key=None, sep=':', salt=None): def __init__(self, key=None, sep=':', salt=None):
# Use of native strings in all versions of Python # Use of native strings in all versions of Python
self.sep = force_str(sep)
self.key = key or settings.SECRET_KEY self.key = key or settings.SECRET_KEY
self.sep = force_str(sep)
if _SEP_UNSAFE.match(self.sep):
warnings.warn('Unsafe Signer separator: %r (cannot be empty or consist of only A-z0-9-_=)' % sep,
RemovedInDjango110Warning)
self.salt = force_str(salt or self.salt = force_str(salt or
'%s.%s' % (self.__class__.__module__, self.__class__.__name__)) '%s.%s' % (self.__class__.__module__, self.__class__.__name__))

View File

@ -247,6 +247,9 @@ details on these changes.
* Support for the syntax of ``{% cycle %}`` that uses comma-separated arguments * Support for the syntax of ``{% cycle %}`` that uses comma-separated arguments
will be removed. will be removed.
* The warning that :class:`~django.core.signing.Signer` issues when given an
invalid separator will become an exception.
.. _deprecation-removed-in-1.9: .. _deprecation-removed-in-1.9:
1.9 1.9

View File

@ -974,6 +974,9 @@ Miscellaneous
``django.utils.feedgenerator.RssFeed.mime_type`` attributes are deprecated in ``django.utils.feedgenerator.RssFeed.mime_type`` attributes are deprecated in
favor of ``content_type``. favor of ``content_type``.
* :class:`~django.core.signing.Signer` now issues a warning if an invalid
separator is used. This will become an exception in Django 1.10.
.. removed-features-1.9: .. removed-features-1.9:
Features removed in 1.9 Features removed in 1.9

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import warnings
from django.core import signing from django.core import signing
from django.test import SimpleTestCase from django.test import SimpleTestCase
@ -112,6 +113,23 @@ class TestSigner(SimpleTestCase):
s = signing.Signer(binary_key) s = signing.Signer(binary_key)
self.assertEqual('foo:6NB0fssLW5RQvZ3Y-MTerq2rX7w', s.sign('foo')) self.assertEqual('foo:6NB0fssLW5RQvZ3Y-MTerq2rX7w', s.sign('foo'))
def test_valid_sep(self):
separators = ['/', '*sep*', ',']
for sep in separators:
signer = signing.Signer('predictable-secret', sep=sep)
self.assertEqual('foo%ssH9B01cZcJ9FoT_jEVkRkNULrl8' % sep, signer.sign('foo'))
def test_invalid_sep(self):
"""should warn on invalid separator"""
separators = ['', '-', 'abc']
for sep in separators:
with warnings.catch_warnings(record=True) as recorded:
warnings.simplefilter('always')
signing.Signer(sep=sep)
self.assertEqual(len(recorded), 1)
msg = str(recorded[0].message)
self.assertTrue(msg.startswith('Unsafe Signer separator'))
class TestTimestampSigner(SimpleTestCase): class TestTimestampSigner(SimpleTestCase):