diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/auth/tests/test_views.py | 12 | ||||
| -rw-r--r-- | django/utils/http.py | 12 |
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'])) |
