components/python/django/patches/CVE-2016-2512.patch
branchs11u3-sru
changeset 6035 c9748fcc32de
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/django/patches/CVE-2016-2512.patch	Fri May 20 17:42:29 2016 -0400
@@ -0,0 +1,76 @@
+Patches taken from:
+https://github.com/django/django/commit/382ab137312961ad62feb8109d70a5a581fe8350
+https://github.com/django/django/commit/552f03869ea7f3072b3fa19ffb6cb2d957fd8447
+
+This is fixed in Django 1.8.11 and 1.9.4
+
+--- Django-1.4.22/django/utils/http.py.orig   2016-03-09 19:31:50.474600452 -0800
++++ Django-1.4.22/django/utils/http.py     2016-03-09 19:37:10.433043007 -0800
+@@ -7,8 +7,9 @@ import urlparse
+ import unicodedata
+ from email.utils import formatdate
+
++from django.utils import six
+ from django.utils.datastructures import MultiValueDict
+-from django.utils.encoding import smart_str, force_unicode
++from django.utils.encoding import smart_str, force_unicode, force_text
+ from django.utils.functional import allow_lazy
+
+ ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"')
+@@ -237,8 +238,16 @@ def is_safe_url(url, host=None):
+         url = url.strip()
+     if not url:
+         return False
+-    # Chrome treats \ completely as /
+-    url = url.replace('\\', '/')
++    if six.PY2:
++        try:
++            url = force_text(url)
++        except UnicodeDecodeError:
++            return False
++    # 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('///'):
+
+
+--- Django-1.4.22/tests/regressiontests/utils/http.py.orig   2016-03-09 19:40:41.664196629 -0800
++++ Django-1.4.22/tests/regressiontests/utils/http.py     2016-03-09 19:42:38.347335015 -0800
+@@ -1,3 +1,6 @@
++# -*- encoding: utf-8 -*-
++from __future__ import unicode_literals
++
+ import sys
+
+ from django.utils import http
+@@ -100,6 +103,11 @@ class TestUtilsHttp(unittest.TestCase):
+                         'javascript:alert("XSS")'
+                         '\njavascript:alert(x)',
+                         '\x08//example.com',
++                        r'http://otherserver\@example.com',
++                        r'http:\\testserver\@example.com',
++                        r'http://testserver\me:[email protected]',
++                        r'http://testserver\@example.com',
++                        r'http:\\testserver\confirm\[email protected]',
+                         '\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',
+@@ -109,5 +117,14 @@ class TestUtilsHttp(unittest.TestCase):
+                      'https://testserver/',
+                      'HTTPS://testserver/',
+                      '//testserver/',
++                     'http://testserver/[email protected]',
+                      '/url%20with%20spaces/'):
+             self.assertTrue(http.is_safe_url(good_url, host='testserver'), "%s should be allowed" % good_url)
++        self.assertFalse(http.is_safe_url('Ã view'.encode('latin-1'), host='testserver'))
++
++        # Valid basic auth credentials are allowed.
++        self.assertTrue(http.is_safe_url(r'http://user:pass@testserver/', host='user:pass@testserver'))
++        # A path without host is allowed.
++        self.assertTrue(http.is_safe_url('/confirm/[email protected]'))
++        # Basic auth without host is not allowed.
++        self.assertFalse(http.is_safe_url(r'http://testserver\@example.com'))