Description: CVE-2016-2512: Prevented spoofing is_safe_url() with basic auth
Origin: backport, https://github.com/django/django/commit/382ab137312961ad62feb8109d70a5a581fe8350
Bug-Debian: https://bugs.debian.org/816434
Forwarded: not-needed
Author: Mark Striemer <mstriemer@mozilla.com>
Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
Last-Update: 2016-03-12
Applied-Upstream: 1.8.10

---
 django/utils/http.py           |  8 ++++++--
 tests/utils_tests/test_http.py | 12 ++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -237,8 +237,12 @@ def is_safe_url(url, host=None):
         url = url.strip()
     if not url:
         return False
-    # Chrome treats \ completely as /
-    url = url.replace('\\', '/')
+    # Chrome treats \ completely as / in paths but it could be part of some
+    # basic auth credentials so we need to check both URLs.
+    return _is_safe_url(url, host) and _is_safe_url(url.replace('\\', '/'), host)
+
+
+def _is_safe_url(url, host):
     # 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('///'):
--- a/django/contrib/auth/tests/views.py
+++ b/django/contrib/auth/tests/views.py
@@ -312,7 +312,12 @@ class LoginTest(AuthViewsTestCase):
                         'ftp://exampel.com',
                         '///example.com',
                         '//example.com',
-                        'javascript:alert("XSS")'):
+                        'javascript:alert("XSS")',
+                        r'http://otherserver\@example.com',
+                        r'http:\\testserver\@example.com',
+                        r'http://testserver\me:pass@example.com',
+                        r'http://testserver\@example.com',
+                        r'http:\\testserver\confirm\me@example.com'):
 
             nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
                 'url': login_url,
@@ -335,6 +340,7 @@ class LoginTest(AuthViewsTestCase):
                          'https://testserver/',
                          'HTTPS://testserver/',
                          '//testserver/',
+                         'http://testserver/confirm?email=me@example.com',
                          '/url%20with%20spaces/'):  # see ticket #12534
             safe_url = '%(url)s?%(next)s=%(good_url)s' % {
                 'url': login_url,
