[1.4.x] Prevented reverse() from generating URLs pointing to other hosts.
This is a security fix. Disclosure following shortly.
This commit is contained in:
parent
4d5e972a2c
commit
c2fe73133b
|
@ -406,6 +406,8 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
|
unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
|
||||||
candidate = (prefix_norm + result) % unicode_kwargs
|
candidate = (prefix_norm + result) % unicode_kwargs
|
||||||
if re.search(u'^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
|
if re.search(u'^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
|
||||||
|
if candidate.startswith('//'):
|
||||||
|
candidate = '/%%2F%s' % candidate[2:]
|
||||||
return candidate
|
return candidate
|
||||||
# lookup_view can be URL label, or dotted path, or callable, Any of
|
# 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
|
# these can be passed in at the top, but callables are not friendly in
|
||||||
|
|
|
@ -5,3 +5,16 @@ Django 1.4.14 release notes
|
||||||
*Under development*
|
*Under development*
|
||||||
|
|
||||||
Django 1.4.14 fixes several security issues in 1.4.13.
|
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.
|
||||||
|
|
|
@ -142,6 +142,9 @@ test_data = (
|
||||||
('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
|
('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
|
||||||
('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
|
('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
|
||||||
('defaults', NoReverseMatch, [], {'arg2': 1}),
|
('defaults', NoReverseMatch, [], {'arg2': 1}),
|
||||||
|
|
||||||
|
# Security tests
|
||||||
|
('security', '/%2Fexample.com/security/', ['/example.com'], {}),
|
||||||
)
|
)
|
||||||
|
|
||||||
class NoURLPatternsTests(TestCase):
|
class NoURLPatternsTests(TestCase):
|
||||||
|
|
|
@ -71,4 +71,7 @@ urlpatterns = patterns('',
|
||||||
(r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
|
(r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
|
||||||
|
|
||||||
url('^includes/', include(other_patterns)),
|
url('^includes/', include(other_patterns)),
|
||||||
|
|
||||||
|
# Security tests
|
||||||
|
url('(.+)/security/$', empty_view, name='security'),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue