Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix a security issue in the auth system. Disclosure and new release f…

…orthcoming.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15032 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6819be1ea17ace34ae3a5c31ab0be960e99fcb85 1 parent 732198e
Alex Gaynor authored December 23, 2010
11  django/contrib/auth/tests/tokens.py
@@ -72,3 +72,14 @@ def _make_token(user):
72 72
         p0 = PasswordResetTokenGenerator()
73 73
         tk1 = _make_token(user)
74 74
         self.assertTrue(p0.check_token(user, tk1))
  75
+
  76
+    def test_date_length(self):
  77
+        """
  78
+        Make sure we don't allow overly long dates, causing a potential DoS.
  79
+        """
  80
+        user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd')
  81
+        p0 = PasswordResetTokenGenerator()
  82
+
  83
+        # This will put a 14-digit base36 timestamp into the token, which is too large.
  84
+        tk1 = p0._make_token_with_timestamp(user, 175455491841851871349)
  85
+        self.assertFalse(p0.check_token(user, tk1))
4  django/contrib/auth/urls.py
... ...
@@ -1,4 +1,4 @@
1  
-# These URLs are normally mapped to /admin/urls.py. This URLs file is 
  1
+# These URLs are normally mapped to /admin/urls.py. This URLs file is
2 2
 # provided as a convenience to those who want to deploy these URLs elsewhere.
3 3
 # This file is also used to provide a reliable view deployment for test purposes.
4 4
 
@@ -11,7 +11,7 @@
11 11
     (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
12 12
     (r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
13 13
     (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
14  
-    (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
  14
+    (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'),
15 15
     (r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
16 16
 )
17 17
 
7  django/utils/http.py
@@ -73,8 +73,13 @@ def http_date(epoch_seconds=None):
73 73
 
74 74
 def base36_to_int(s):
75 75
     """
76  
-    Convertd a base 36 string to an integer
  76
+    Converts a base 36 string to an ``int``. To prevent
  77
+    overconsumption of server resources, raises ``ValueError` if the
  78
+    input is longer than 13 base36 digits (13 digits is sufficient to
  79
+    base36-encode any 64-bit integer).
77 80
     """
  81
+    if len(s) > 13:
  82
+        raise ValueError("Base36 input too large")
78 83
     return int(s, 36)
79 84
 
80 85
 def int_to_base36(i):

0 notes on commit 6819be1

Please sign in to comment.
Something went wrong with that request. Please try again.