File 0006-1.5.x-Made-is_safe_url-reject-URLs-that-start-with-c.patch of Package python-django.openSUSE_13.1_Update

From b35f28462f7ae376714fad5187bae894aafb606a Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Mon, 9 Mar 2015 20:05:13 -0400
Subject: [PATCH 6/6] [1.5.x] Made is_safe_url() reject URLs that start with
 control characters. (bnc#923176)

https://bugzilla.suse.com/show_bug.cgi?id=923176 CVE-2015-2317
This is a security fix; disclosure to follow shortly.

Mitigated possible XSS attack via user-supplied redirect URLs

Django relies on user input in some cases (e.g. django.contrib.auth.views.login and i18n) to redirect the user to an "on success" URL. The security checks for these redirects (namely django.utils.http.is_safe_url()) accepted URLs with leading control characters and so considered URLs like \x08javascript:... safe. This issue doesn't affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn't a problem either.

However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href.

Thanks Daniel Chatfield for reporting the issue.

Conflicts:
	django/utils/http.py
	docs/releases/1.4.20.txt
	docs/releases/1.6.11.txt
---
 django/utils/http.py                | 14 ++++++++++----
 tests/regressiontests/utils/http.py |  4 +++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/django/utils/http.py b/django/utils/http.py
index f690a79..c0ce299 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -4,6 +4,7 @@ import calendar
 import datetime
 import re
 import sys
+import unicodedata
 try:
     from urllib import parse as urllib_parse
 except ImportError:     # Python 2
@@ -11,7 +12,6 @@ except ImportError:     # Python 2
     import urlparse
     urllib_parse.urlparse = urlparse.urlparse
 
-
 from email.utils import formatdate
 
 from django.utils.datastructures import MultiValueDict
@@ -235,9 +235,10 @@ def is_safe_url(url, host=None):
 
     Always returns ``False`` on an empty url.
     """
+    if url is not None:
+        url = url.strip()
     if not url:
         return False
-    url = url.strip()
     # Chrome treats \ completely as /
     url = url.replace('\\', '/')
     # Chrome considers any URL with more than two slashes to be absolute, but
@@ -251,5 +252,10 @@ def is_safe_url(url, host=None):
     # 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'])
+    # Forbid URLs that start with control characters. Some browsers (like
+    # Chrome) ignore quite a few control characters at the start of a
+    # URL and might consider the URL as scheme relative.
+    if unicodedata.category(url[0])[0] == 'C':
+        return False
+    return ((not url_info.netloc or url_info.netloc == host) and
+            (not url_info.scheme or url_info.scheme in ['http', 'https']))
diff --git a/tests/regressiontests/utils/http.py b/tests/regressiontests/utils/http.py
index 88bcfb8..4b62c6c 100644
--- a/tests/regressiontests/utils/http.py
+++ b/tests/regressiontests/utils/http.py
@@ -110,7 +110,9 @@ class TestUtilsHttp(unittest.TestCase):
                         'http:\/example.com',
                         'http:/\example.com',
                         'javascript:alert("XSS")',
-                        '\njavascript:alert(x)'):
+                        '\njavascript:alert(x)',
+                        '\x08//example.com',
+                        '\n'):
             self.assertFalse(http.is_safe_url(bad_url, host='testserver'), "%s should be blocked" % bad_url)
         for good_url in ('/view/?param=http://example.com',
                      '/view/?param=https://example.com',
-- 
2.1.4

openSUSE Build Service is sponsored by