VYPR
High severityNVD Advisory· Published Aug 26, 2014· Updated May 6, 2026

CVE-2014-0480

CVE-2014-0480

Description

The core.urlresolvers.reverse function in Django before 1.4.14, 1.5.x before 1.5.9, 1.6.x before 1.6.6, and 1.7 before release candidate 3 does not properly validate URLs, which allows remote attackers to conduct phishing attacks via a // (slash slash) in a URL, which triggers a scheme-relative URL to be generated.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
< 1.4.141.4.14
DjangoPyPI
>= 1.5, < 1.5.91.5.9
DjangoPyPI
>= 1.6, < 1.6.61.6.6

Affected products

42
  • cpe:2.3:a:djangoproject:django:*:*:*:*:*:*:*:*+ 39 more
    • cpe:2.3:a:djangoproject:django:*:*:*:*:*:*:*:*range: <=1.4.13
    • cpe:2.3:a:djangoproject:django:1.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.10:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.11:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.12:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.4.9:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.7:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5.8:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:alpha:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.5:beta:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:-:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.4:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6.5:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.6:beta4:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta2:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta3:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:beta4:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:rc1:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.7:rc2:*:*:*:*:*:*
  • OpenSUSE/openSUSE2 versions
    cpe:2.3:o:opensuse:opensuse:12.3:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:o:opensuse:opensuse:12.3:*:*:*:*:*:*:*
    • cpe:2.3:o:opensuse:opensuse:13.1:*:*:*:*:*:*:*

Patches

3
da051da8df5e

[1.6.x] Prevented reverse() from generating URLs pointing to other hosts.

https://github.com/django/djangoFlorian ApollonerJul 17, 2014via ghsa
6 files changed · +50 1
  • django/core/urlresolvers.py+5 1 modified
    @@ -435,7 +435,11 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
                     candidate_pat = prefix_norm.replace('%', '%%') + result
                     if re.search('^%s%s' % (prefix_norm, pattern), candidate_pat % candidate_subs, re.UNICODE):
                         candidate_subs = dict((k, urlquote(v)) for (k, v) in candidate_subs.items())
    -                    return candidate_pat % candidate_subs
    +                    url = candidate_pat % candidate_subs
    +                    # Don't allow construction of scheme relative urls.
    +                    if url.startswith('//'):
    +                        url = '/%%2F%s' % url[2:]
    +                    return url
             # lookup_view can be URL label, or dotted path, or callable, Any of
             # these can be passed in at the top, but callables are not friendly in
             # error messages.
    
  • docs/releases/1.4.14.txt+13 0 modified
    @@ -5,3 +5,16 @@ Django 1.4.14 release notes
     *Under development*
     
     Django 1.4.14 fixes several security issues in 1.4.13.
    +
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    
  • docs/releases/1.5.9.txt+13 0 modified
    @@ -5,3 +5,16 @@ Django 1.5.9 release notes
     *Under development*
     
     Django 1.5.9 fixes several security issues in 1.5.8.
    +
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    
  • docs/releases/1.6.6.txt+13 0 modified
    @@ -6,6 +6,19 @@ Django 1.6.6 release notes
     
     Django 1.6.6 fixes several security issues and bugs in 1.6.5.
     
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    +
     Bugfixes
     ========
     
    
  • tests/urlpatterns_reverse/tests.py+3 0 modified
    @@ -147,6 +147,9 @@
         ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
         ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
         ('defaults', NoReverseMatch, [], {'arg2': 1}),
    +
    +    # Security tests
    +    ('security', '/%2Fexample.com/security/', ['/example.com'], {}),
     )
     
     class NoURLPatternsTests(TestCase):
    
  • tests/urlpatterns_reverse/urls.py+3 0 modified
    @@ -71,4 +71,7 @@
         (r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
     
         url('^includes/', include(other_patterns)),
    +
    +    # Security tests
    +    url('(.+)/security/$', empty_view, name='security'),
     )
    
c2fe73133b62

[1.4.x] Prevented reverse() from generating URLs pointing to other hosts.

https://github.com/django/djangoFlorian ApollonerJul 17, 2014via ghsa
4 files changed · +21 0
  • django/core/urlresolvers.py+2 0 modified
    @@ -406,6 +406,8 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
                         unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
                         candidate = (prefix_norm + result) % unicode_kwargs
                     if re.search(u'^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
    +                    if candidate.startswith('//'):
    +                        candidate = '/%%2F%s' % candidate[2:]
                         return candidate
             # lookup_view can be URL label, or dotted path, or callable, Any of
             # these can be passed in at the top, but callables are not friendly in
    
  • docs/releases/1.4.14.txt+13 0 modified
    @@ -5,3 +5,16 @@ Django 1.4.14 release notes
     *Under development*
     
     Django 1.4.14 fixes several security issues in 1.4.13.
    +
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    
  • tests/regressiontests/urlpatterns_reverse/tests.py+3 0 modified
    @@ -142,6 +142,9 @@
         ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
         ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
         ('defaults', NoReverseMatch, [], {'arg2': 1}),
    +
    +    # Security tests
    +    ('security', '/%2Fexample.com/security/', ['/example.com'], {}),
     )
     
     class NoURLPatternsTests(TestCase):
    
  • tests/regressiontests/urlpatterns_reverse/urls.py+3 0 modified
    @@ -71,4 +71,7 @@
         (r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
     
         url('^includes/', include(other_patterns)),
    +
    +    # Security tests
    +    url('(.+)/security/$', empty_view, name='security'),
     )
    
45ac9d4fb087

[1.5.x] Prevented reverse() from generating URLs pointing to other hosts.

https://github.com/django/djangoFlorian ApollonerJul 17, 2014via ghsa
5 files changed · +34 0
  • django/core/urlresolvers.py+2 0 modified
    @@ -426,6 +426,8 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
                         unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()])
                         candidate = (prefix_norm.replace('%', '%%') + result) % unicode_kwargs
                     if re.search('^%s%s' % (prefix_norm, pattern), candidate, re.UNICODE):
    +                    if candidate.startswith('//'):
    +                        candidate = '/%%2F%s' % candidate[2:]
                         return candidate
             # lookup_view can be URL label, or dotted path, or callable, Any of
             # these can be passed in at the top, but callables are not friendly in
    
  • docs/releases/1.4.14.txt+13 0 modified
    @@ -5,3 +5,16 @@ Django 1.4.14 release notes
     *Under development*
     
     Django 1.4.14 fixes several security issues in 1.4.13.
    +
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    
  • docs/releases/1.5.9.txt+13 0 modified
    @@ -5,3 +5,16 @@ Django 1.5.9 release notes
     *Under development*
     
     Django 1.5.9 fixes several security issues in 1.5.8.
    +
    +:func:`~django.core.urlresolvers.reverse()` could generate URLs pointing to other hosts
    +=======================================================================================
    +
    +In certain situations, URL reversing could generate scheme-relative URLs  (URLs
    +starting with two slashes), which could unexpectedly redirect a user  to a
    +different host. An attacker could exploit this, for example, by redirecting
    +users to a phishing site designed to ask for user's passwords.
    +
    +To remedy this, URL reversing now ensures that no URL starts with two slashes
    +(//), replacing the second slash with its URL encoded counterpart (%2F). This
    +approach ensures that semantics stay the same, while making the URL relative to
    +the domain and not to the scheme.
    
  • tests/regressiontests/urlpatterns_reverse/tests.py+3 0 modified
    @@ -143,6 +143,9 @@
         ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
         ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
         ('defaults', NoReverseMatch, [], {'arg2': 1}),
    +
    +    # Security tests
    +    ('security', '/%2Fexample.com/security/', ['/example.com'], {}),
     )
     
     class NoURLPatternsTests(TestCase):
    
  • tests/regressiontests/urlpatterns_reverse/urls.py+3 0 modified
    @@ -71,4 +71,7 @@
         (r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
     
         url('^includes/', include(other_patterns)),
    +
    +    # Security tests
    +    url('(.+)/security/$', empty_view, name='security'),
     )
    

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

15

News mentions

0

No linked articles in our index yet.