Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-1.9.git;a=commitdiff;h=9cc78009b3904f4f1648ad8b6b995091b1ed606e
commit 9cc78009b3904f4f1648ad8b6b995091b1ed606e Author: kikadf <[email protected]> Date: Thu May 15 08:10:06 2014 +0200 django-1.5.2-2arcturus2-x86_64 * Fix CVE-2014-1418 * Fix the "malformed URLs from user input incorrectly validated" issue diff --git a/source/devel-extra/django/CVE-2014-1418.patch b/source/devel-extra/django/CVE-2014-1418.patch new file mode 100644 index 0000000..a27bd2c --- /dev/null +++ b/source/devel-extra/django/CVE-2014-1418.patch @@ -0,0 +1,147 @@ +Description: Drop IE6/IE7 compatability functions that introduced cache + coherency errors. Fixes CVE-2014-1418. + +Origin: Original patch from upstream + +diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py +index 7fff71a..4819ad3 100644 +--- a/django/core/handlers/base.py ++++ b/django/core/handlers/base.py +@@ -22,8 +22,6 @@ class BaseHandler(object): + response_fixes = [ + http.fix_location_header, + http.conditional_content_removal, +- http.fix_IE_for_attach, +- http.fix_IE_for_vary, + ] + + def __init__(self): +diff --git a/django/http/__init__.py b/django/http/__init__.py +index 46afa34..08d9d23 100644 +--- a/django/http/__init__.py ++++ b/django/http/__init__.py +@@ -6,5 +6,4 @@ from django.http.response import (HttpResponse, StreamingHttpResponse, + HttpResponseRedirect, HttpResponseNotModified, HttpResponseBadRequest, + HttpResponseForbidden, HttpResponseNotFound, HttpResponseNotAllowed, + HttpResponseGone, HttpResponseServerError, Http404, BadHeaderError) +-from django.http.utils import (fix_location_header, conditional_content_removal, +- fix_IE_for_attach, fix_IE_for_vary) ++from django.http.utils import fix_location_header, conditional_content_removal +diff --git a/django/http/utils.py b/django/http/utils.py +index fcb3fec..ace35eb 100644 +--- a/django/http/utils.py ++++ b/django/http/utils.py +@@ -39,58 +39,3 @@ def conditional_content_removal(request, response): + else: + response.content = '' + return response +- +- +-def fix_IE_for_attach(request, response): +- """ +- This function will prevent Django from serving a Content-Disposition header +- while expecting the browser to cache it (only when the browser is IE). This +- leads to IE not allowing the client to download. +- """ +- useragent = request.META.get('HTTP_USER_AGENT', '').upper() +- if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent: +- return response +- +- offending_headers = ('no-cache', 'no-store') +- if response.has_header('Content-Disposition'): +- try: +- del response['Pragma'] +- except KeyError: +- pass +- if response.has_header('Cache-Control'): +- cache_control_values = [value.strip() for value in +- response['Cache-Control'].split(',') +- if value.strip().lower() not in offending_headers] +- +- if not len(cache_control_values): +- del response['Cache-Control'] +- else: +- response['Cache-Control'] = ', '.join(cache_control_values) +- +- return response +- +- +-def fix_IE_for_vary(request, response): +- """ +- This function will fix the bug reported at +- http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global +- by clearing the Vary header whenever the mime-type is not safe +- enough for Internet Explorer to handle. Poor thing. +- """ +- useragent = request.META.get('HTTP_USER_AGENT', '').upper() +- if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent: +- return response +- +- # These mime-types that are decreed "Vary-safe" for IE: +- safe_mime_types = ('text/html', 'text/plain', 'text/sgml') +- +- # The first part of the Content-Type field will be the MIME type, +- # everything after ';', such as character-set, can be ignored. +- mime_type = response.get('Content-Type', '').partition(';')[0] +- if mime_type not in safe_mime_types: +- try: +- del response['Vary'] +- except KeyError: +- pass +- +- return response +diff --git a/tests/regressiontests/utils/http.py b/tests/regressiontests/utils/http.py +index 6d3bc02..03706ca 100644 +--- a/tests/regressiontests/utils/http.py ++++ b/tests/regressiontests/utils/http.py +@@ -67,50 +67,6 @@ class TestUtilsHttp(unittest.TestCase): + ] + self.assertTrue(result in acceptable_results) + +- def test_fix_IE_for_vary(self): +- """ +- Regression for #16632. +- +- `fix_IE_for_vary` shouldn't crash when there's no Content-Type header. +- """ +- +- # functions to generate responses +- def response_with_unsafe_content_type(): +- r = HttpResponse(content_type="text/unsafe") +- r['Vary'] = 'Cookie' +- return r +- +- def no_content_response_with_unsafe_content_type(): +- # 'Content-Type' always defaulted, so delete it +- r = response_with_unsafe_content_type() +- del r['Content-Type'] +- return r +- +- # request with & without IE user agent +- rf = RequestFactory() +- request = rf.get('/') +- ie_request = rf.get('/', HTTP_USER_AGENT='MSIE') +- +- # not IE, unsafe_content_type +- response = response_with_unsafe_content_type() +- utils.fix_IE_for_vary(request, response) +- self.assertTrue('Vary' in response) +- +- # IE, unsafe_content_type +- response = response_with_unsafe_content_type() +- utils.fix_IE_for_vary(ie_request, response) +- self.assertFalse('Vary' in response) +- +- # not IE, no_content +- response = no_content_response_with_unsafe_content_type() +- utils.fix_IE_for_vary(request, response) +- self.assertTrue('Vary' in response) +- +- # IE, no_content +- response = no_content_response_with_unsafe_content_type() +- utils.fix_IE_for_vary(ie_request, response) +- self.assertFalse('Vary' in response) +- + def test_base36(self): + # reciprocity works + for n in [0, 1, 1000, 1000000]: diff --git a/source/devel-extra/django/FrugalBuild b/source/devel-extra/django/FrugalBuild index 05e60d1..5ccf433 100644 --- a/source/devel-extra/django/FrugalBuild +++ b/source/devel-extra/django/FrugalBuild @@ -7,7 +7,7 @@ pkgname=django _F_archive_name=Django pkgver=1.5.2 _branch=1.5 -pkgrel=2arcturus1 +pkgrel=2arcturus2 pkgdesc="Django is a Python web framework" url="https://www.djangoproject.com" depends=('python') @@ -20,10 +20,13 @@ sha1sums=('7137d32505727b057c77b025c3a0355c131de1af') # FSA fix *** -source=(${source[@]} CVE-2014-0472.patch CVE-2014-0473.patch CVE-2014-0474.patch) +source=(${source[@]} CVE-2014-0472.patch CVE-2014-0473.patch CVE-2014-0474.patch + is_safe_url_1_5.diff CVE-2014-1418.patch) sha1sums=(${sha1sums[@]} '5ef94b51e0d3bf4ed93411266a738ea99fca7eb8' \ '47d506fa7cddd4994ea47652e9fda7d35de882d4' \ - '1a5b72cb58fdae94132403f53c7a15e210826c59') + '1a5b72cb58fdae94132403f53c7a15e210826c59' \ + '0097ec2fd08eb0c7ee93b638da6d7a2c47067f17' \ + '6173fe9fdc3099aaf5e6afe184bb88434576cb41') # *********** diff --git a/source/devel-extra/django/is_safe_url_1_5.diff b/source/devel-extra/django/is_safe_url_1_5.diff new file mode 100644 index 0000000..199569f --- /dev/null +++ b/source/devel-extra/django/is_safe_url_1_5.diff @@ -0,0 +1,122 @@ +Description: Blacklist several more URL patterns that can cause Chrome to + access unexpected resources. + +Origin: Original patch from upstream + +--- + django/contrib/auth/tests/views.py | 12 ++++++++---- + django/utils/http.py | 12 ++++++++++++ + tests/regressiontests/utils/http.py | 29 +++++++++++++++++++++++++++++ + 3 files changed, 49 insertions(+), 4 deletions(-) + +Index: b/django/contrib/auth/tests/views.py +=================================================================== +--- a/django/contrib/auth/tests/views.py ++++ b/django/contrib/auth/tests/views.py +@@ -326,8 +326,10 @@ + + # 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")'): + +@@ -349,8 +351,8 @@ + '/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' % { +@@ -522,8 +524,10 @@ + + # 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' % { +@@ -543,8 +547,8 @@ + '/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' % { +Index: b/django/utils/http.py +=================================================================== +--- a/django/utils/http.py ++++ b/django/utils/http.py +@@ -237,6 +237,18 @@ + """ + 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 = urllib_parse.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']) +Index: b/tests/regressiontests/utils/http.py +=================================================================== +--- a/tests/regressiontests/utils/http.py ++++ b/tests/regressiontests/utils/http.py +@@ -91,6 +91,35 @@ + self.assertEqual(http.int_to_base36(n), b36) + self.assertEqual(http.base36_to_int(b36), n) + ++ def test_is_safe_url(self): ++ for bad_url in ('http://example.com', ++ 'http:///example.com', ++ 'https://example.com', ++ 'ftp://exampel.com', ++ r'\\example.com', ++ r'\\\example.com', ++ r'/\\/example.com', ++ r'\\\example.com', ++ r'\\example.com', ++ r'\\//example.com', ++ r'/\/example.com', ++ r'\/example.com', ++ r'/\example.com', ++ 'http:///example.com', ++ 'http:/\//example.com', ++ 'http:\/example.com', ++ 'http:/\example.com', ++ 'javascript:alert("XSS")'): ++ 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', ++ '/view?param=ftp://exampel.com', ++ 'view/?param=//example.com', ++ 'https://testserver/', ++ 'HTTPS://testserver/', ++ '//testserver/', ++ '/url%20with%20spaces/'): ++ self.assertTrue(http.is_safe_url(good_url, host='testserver'), "%s should be allowed" % good_url) + + class ETagProcessingTests(unittest.TestCase): + def testParsing(self): _______________________________________________ Frugalware-git mailing list [email protected] http://frugalware.org/mailman/listinfo/frugalware-git
