1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
Description: Fix denial-of-service attack in password-reset mechanism
Origin: upstream, http://code.djangoproject.com/changeset/15034
Bug: http://www.djangoproject.com/weblog/2010/dec/22/security/
--- 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'),
)
--- 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):
--- a/django/contrib/auth/tests/tokens.py 2011-01-18 08:57:34.000000000 -0600
+++ b/django/contrib/auth/tests/tokens.py 2011-01-18 08:57:40.000000000 -0600
@@ -34,4 +34,9 @@
>>> p2.check_token(u, tk1)
False
+This will put a 14-digit base36 timestamp into the token, which is too large.
+>>> tk1 = p0._make_token_with_timestamp(u, 175455491841851871349)
+>>> p0.check_token(u, tk1)
+False
+
"""
|