--- /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'))