VYPR
Moderate severityNVD Advisory· Published Jan 10, 2011· Updated Apr 29, 2026

CVE-2010-4535

CVE-2010-4535

Description

The password reset functionality in django.contrib.auth in Django before 1.1.3, 1.2.x before 1.2.4, and 1.3.x before 1.3 beta 1 does not validate the length of a string representing a base36 timestamp, which allows remote attackers to cause a denial of service (resource consumption) via a URL that specifies a large base36 integer.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
< 1.1.31.1.3
DjangoPyPI
>= 1.2, < 1.2.41.2.4

Affected products

16
  • cpe:2.3:a:djangoproject:django:1.2.3:*:*:*:*:*:*:*+ 15 more
    • cpe:2.3:a:djangoproject:django:1.2.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.3:alpha1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.3:alpha2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:*:*:*:*:*:*:*:*range: <=1.1.2
    • cpe:2.3:a:djangoproject:django:0.91:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:0.95:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:0.95.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:0.96:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.2:*:*:*:*:*:*:*

Patches

2
7f8dd9cbac07

[1.1.X] Fix a security issue in the auth system. Disclosure and new release forthcoming.

https://github.com/django/djangoAlex GaynorDec 23, 2010via ghsa
3 files changed · +13 3
  • django/contrib/auth/tests/tokens.py+5 0 modified
    @@ -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
    +
     """
    
  • django/contrib/auth/urls.py+2 2 modified
    @@ -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 @@
         (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'),
     )
     
    
  • django/utils/http.py+6 1 modified
    @@ -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):
    
d5d8942a1606

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

https://github.com/django/djangoAlex GaynorDec 23, 2010via ghsa
3 files changed · +19 3
  • django/contrib/auth/tests/tokens.py+11 0 modified
    @@ -50,3 +50,14 @@ def _today(self):
     
             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))
    
  • django/contrib/auth/urls.py+2 2 modified
    @@ -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 @@
         (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'),
     )
     
    
  • django/utils/http.py+6 1 modified
    @@ -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):
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

21

News mentions

0

No linked articles in our index yet.