summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2010-12-23 03:46:37 +0000
committerAlex Gaynor <alex.gaynor@gmail.com>2010-12-23 03:46:37 +0000
commitd5d8942a160685c403d381a279e72e09de5489a9 (patch)
treeb7d2913cebc75957628593e39a903575ee45d54a
parent85207a245bf09fdebe486b4c7bbcb65300f2a693 (diff)
Fix a security issue in the auth system. Disclosure and new release forthcoming.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15034 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/auth/tests/tokens.py11
-rw-r--r--django/contrib/auth/urls.py4
-rw-r--r--django/utils/http.py7
3 files changed, 19 insertions, 3 deletions
diff --git a/django/contrib/auth/tests/tokens.py b/django/contrib/auth/tests/tokens.py
index e9e90493be..9211e062f1 100644
--- a/django/contrib/auth/tests/tokens.py
+++ b/django/contrib/auth/tests/tokens.py
@@ -50,3 +50,14 @@ class TokenGeneratorTest(TestCase):
p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
self.assertFalse(p2.check_token(user, tk1))
+
+ def test_date_length(self):
+ """
+ Make sure we don't allow overly long dates, causing a potential DoS.
+ """
+ user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd')
+ p0 = PasswordResetTokenGenerator()
+
+ # This will put a 14-digit base36 timestamp into the token, which is too large.
+ tk1 = p0._make_token_with_timestamp(user, 175455491841851871349)
+ self.assertFalse(p0.check_token(user, tk1))
diff --git a/django/contrib/auth/urls.py b/django/contrib/auth/urls.py
index 4f8a102e66..42b4e8f212 100644
--- a/django/contrib/auth/urls.py
+++ b/django/contrib/auth/urls.py
@@ -1,4 +1,4 @@
-# These URLs are normally mapped to /admin/urls.py. This URLs file is
+# These URLs are normally mapped to /admin/urls.py. This URLs file is
# provided as a convenience to those who want to deploy these URLs elsewhere.
# This file is also used to provide a reliable view deployment for test purposes.
@@ -11,7 +11,7 @@ urlpatterns = patterns('',
(r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
(r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
(r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
- (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
+ (r'^reset/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', 'django.contrib.auth.views.password_reset_confirm'),
(r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
)
diff --git a/django/utils/http.py b/django/utils/http.py
index f0b1af9c58..2fb60078e5 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -73,8 +73,13 @@ def http_date(epoch_seconds=None):
def base36_to_int(s):
"""
- Convertd a base 36 string to an integer
+ Converts a base 36 string to an ``int``. To prevent
+ overconsumption of server resources, raises ``ValueError` if the
+ input is longer than 13 base36 digits (13 digits is sufficient to
+ base36-encode any 64-bit integer).
"""
+ if len(s) > 13:
+ raise ValueError("Base36 input too large")
return int(s, 36)
def int_to_base36(i):