summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/contrib/auth/tests/test_views.py12
-rw-r--r--django/utils/http.py12
2 files changed, 20 insertions, 4 deletions
diff --git a/django/contrib/auth/tests/test_views.py b/django/contrib/auth/tests/test_views.py
index f8b035af8d..1a73af50c7 100644
--- a/django/contrib/auth/tests/test_views.py
+++ b/django/contrib/auth/tests/test_views.py
@@ -483,8 +483,10 @@ class LoginTest(AuthViewsTestCase):
# Those URLs should not pass the security check
for bad_url in ('http://example.com',
+ 'http:///example.com',
'https://example.com',
'ftp://exampel.com',
+ '///example.com',
'//example.com',
'javascript:alert("XSS")'):
@@ -506,8 +508,8 @@ class LoginTest(AuthViewsTestCase):
'/view/?param=https://example.com',
'/view?param=ftp://exampel.com',
'view/?param=//example.com',
- 'https:///',
- 'HTTPS:///',
+ 'https://testserver/',
+ 'HTTPS://testserver/',
'//testserver/',
'/url%20with%20spaces/'): # see ticket #12534
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
@@ -744,8 +746,10 @@ class LogoutTest(AuthViewsTestCase):
# Those URLs should not pass the security check
for bad_url in ('http://example.com',
+ 'http:///example.com',
'https://example.com',
'ftp://exampel.com',
+ '///example.com',
'//example.com',
'javascript:alert("XSS")'):
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
@@ -765,8 +769,8 @@ class LogoutTest(AuthViewsTestCase):
'/view/?param=https://example.com',
'/view?param=ftp://exampel.com',
'view/?param=//example.com',
- 'https:///',
- 'HTTPS:///',
+ 'https://testserver/',
+ 'HTTPS://testserver/',
'//testserver/',
'/url%20with%20spaces/'): # see ticket #12534
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
diff --git a/django/utils/http.py b/django/utils/http.py
index e3365776f3..28245d23f4 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -272,6 +272,18 @@ def is_safe_url(url, host=None):
"""
if not url:
return False
+ # Chrome treats \ completely as /
+ url = url.replace('\\', '/')
+ # Chrome considers any URL with more than two slashes to be absolute, but
+ # urlaprse is not so flexible. Treat any url with three slashes as unsafe.
+ if url.startswith('///'):
+ return False
url_info = urlparse(url)
+ # Forbid URLs like http:///example.com - with a scheme, but without a hostname.
+ # In that URL, example.com is not the hostname but, a path component. However,
+ # Chrome will still consider example.com to be the hostname, so we must not
+ # allow this syntax.
+ if not url_info.netloc and url_info.scheme:
+ return False
return ((not url_info.netloc or url_info.netloc == host) and
(not url_info.scheme or url_info.scheme in ['http', 'https']))