[Python-modules-commits] [python-django] 01/01: Replace CVE-2015-0219-fix.diff with the upstream patch
Raphaël Hertzog
hertzog at moszumanska.debian.org
Wed Jan 28 21:21:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
hertzog pushed a commit to branch debian/wheezy
in repository python-django.
commit 148e72f6f0d4efac93256006b0afe618b4db1ab7
Author: Raphaël Hertzog <hertzog at debian.org>
Date: Wed Jan 28 22:19:07 2015 +0100
Replace CVE-2015-0219-fix.diff with the upstream patch
Use the patch committed upstream instead of the patch that I submitted
them.
---
debian/patches/CVE-2015-0219-fix.diff | 255 ++++++++++++++++++++++++++++------
1 file changed, 210 insertions(+), 45 deletions(-)
diff --git a/debian/patches/CVE-2015-0219-fix.diff b/debian/patches/CVE-2015-0219-fix.diff
index 6f9eb85..c5b479a 100644
--- a/debian/patches/CVE-2015-0219-fix.diff
+++ b/debian/patches/CVE-2015-0219-fix.diff
@@ -1,59 +1,224 @@
-From b5cfe770f4ed31ded4bcd477f8a3e5060bd52f84 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= <hertzog at debian.org>
-Date: Wed, 28 Jan 2015 17:56:04 +0100
-Subject: [PATCH] [1.4.x] Fixed #24239 -- merge both WSGIRequestHandler.get_environ() methods
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
+From e60557c249d33e100008cc30890cde2daeb677bb Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Wed, 28 Jan 2015 12:03:05 -0500
+Subject: [PATCH] [1.4.x] Fixed #24238 -- Removed unused
+ WSGIRequestHandler.get_environ()
-Commit 4f6fffc1dc429f1ad428ecf8e6620739e8837450 incorrectly added a
-get_environ() method that replaced the original implementation. Instead
-the filtering logic should have been merged into the pre-existing
-get_environ().
-
-Signed-off-by: Raphaël Hertzog <hertzog at debian.org>
-Bug: https://code.djangoproject.com/ticket/24239
+Also moved the test as it wasn't running.
---
- django/core/servers/basehttp.py | 19 ++++++++-----------
- 1 file changed, 8 insertions(+), 11 deletions(-)
+ django/core/servers/basehttp.py | 33 -----------
+ .../servers/servers/test_basehttp.py | 67 ----------------------
+ tests/regressiontests/servers/tests.py | 67 +++++++++++++++++++++-
+ 3 files changed, 66 insertions(+), 101 deletions(-)
+ delete mode 100644 tests/regressiontests/servers/servers/test_basehttp.py
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
-index 0ec5f98..ef18687 100644
+index 0ec5f98..d570657 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
-@@ -160,6 +160,14 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
- if length:
- env['CONTENT_LENGTH'] = length
-
-+ # Strip all headers with underscores in the name before constructing
-+ # the WSGI environ. This prevents header-spoofing based on ambiguity
-+ # between underscores and dashes both normalized to underscores in WSGI
-+ # env vars. Nginx and Apache 2.4+ both do this as well.
-+ for k, v in self.headers.items():
-+ if '_' in k:
-+ del self.headers[k]
-+
- for h in self.headers.headers:
- k,v = h.split(':',1)
- k=k.replace('-','_').upper(); v=v.strip()
-@@ -199,17 +207,6 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
-
- sys.stderr.write(msg)
+@@ -138,39 +138,6 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
+ self.style = color_style()
+ super(WSGIRequestHandler, self).__init__(*args, **kwargs)
- def get_environ(self):
-- # Strip all headers with underscores in the name before constructing
-- # the WSGI environ. This prevents header-spoofing based on ambiguity
-- # between underscores and dashes both normalized to underscores in WSGI
-- # env vars. Nginx and Apache 2.4+ both do this as well.
-- for k, v in self.headers.items():
-- if '_' in k:
-- del self.headers[k]
+- env = self.server.base_environ.copy()
+- env['SERVER_PROTOCOL'] = self.request_version
+- env['REQUEST_METHOD'] = self.command
+- if '?' in self.path:
+- path,query = self.path.split('?',1)
+- else:
+- path,query = self.path,''
+-
+- env['PATH_INFO'] = urllib.unquote(path)
+- env['QUERY_STRING'] = query
+- env['REMOTE_ADDR'] = self.client_address[0]
+-
+- if self.headers.typeheader is None:
+- env['CONTENT_TYPE'] = self.headers.type
+- else:
+- env['CONTENT_TYPE'] = self.headers.typeheader
+-
+- length = self.headers.getheader('content-length')
+- if length:
+- env['CONTENT_LENGTH'] = length
+-
+- for h in self.headers.headers:
+- k,v = h.split(':',1)
+- k=k.replace('-','_').upper(); v=v.strip()
+- if k in env:
+- continue # skip content length, type,etc.
+- if 'HTTP_'+k in env:
+- env['HTTP_'+k] += ','+v # comma-separate multiple headers
+- else:
+- env['HTTP_'+k] = v
+- return env
+-
+ def log_message(self, format, *args):
+ # Don't bother logging requests for admin images or the favicon.
+ if (self.path.startswith(self.admin_media_prefix)
+diff --git a/tests/regressiontests/servers/servers/test_basehttp.py b/tests/regressiontests/servers/servers/test_basehttp.py
+deleted file mode 100644
+index 6bca608..0000000
+--- a/tests/regressiontests/servers/servers/test_basehttp.py
++++ /dev/null
+@@ -1,67 +0,0 @@
+-import sys
+-
+-from django.core.servers.basehttp import WSGIRequestHandler
+-from django.test import TestCase
+-from django.utils.six import BytesIO, StringIO
+-
+-
+-class Stub(object):
+- def __init__(self, **kwargs):
+- self.__dict__.update(kwargs)
+-
+-
+-class WSGIRequestHandlerTestCase(TestCase):
+-
+- def test_strips_underscore_headers(self):
+- """WSGIRequestHandler ignores headers containing underscores.
+-
+- This follows the lead of nginx and Apache 2.4, and is to avoid
+- ambiguity between dashes and underscores in mapping to WSGI environ,
+- which can have security implications.
+- """
+- def test_app(environ, start_response):
+- """A WSGI app that just reflects its HTTP environ."""
+- start_response('200 OK', [])
+- http_environ_items = sorted(
+- '%s:%s' % (k, v) for k, v in environ.items()
+- if k.startswith('HTTP_')
+- )
+- yield (','.join(http_environ_items)).encode('utf-8')
+-
+- rfile = BytesIO()
+- rfile.write(b"GET / HTTP/1.0\r\n")
+- rfile.write(b"Some-Header: good\r\n")
+- rfile.write(b"Some_Header: bad\r\n")
+- rfile.write(b"Other_Header: bad\r\n")
+- rfile.seek(0)
+-
+- # WSGIRequestHandler closes the output file; we need to make this a
+- # no-op so we can still read its contents.
+- class UnclosableBytesIO(BytesIO):
+- def close(self):
+- pass
+-
+- wfile = UnclosableBytesIO()
+-
+- def makefile(mode, *a, **kw):
+- if mode == 'rb':
+- return rfile
+- elif mode == 'wb':
+- return wfile
-
-- return super(WSGIRequestHandler, self).get_environ()
+- request = Stub(makefile=makefile)
+- server = Stub(base_environ={}, get_app=lambda: test_app)
-
+- # We don't need to check stderr, but we don't want it in test output
+- old_stderr = sys.stderr
+- sys.stderr = StringIO()
+- try:
+- # instantiating a handler runs the request as side effect
+- WSGIRequestHandler(request, '192.168.0.2', server)
+- finally:
+- sys.stderr = old_stderr
+-
+- wfile.seek(0)
+- body = list(wfile.readlines())[-1]
+-
+- self.assertEqual(body, b'HTTP_SOME_HEADER:good')
+diff --git a/tests/regressiontests/servers/tests.py b/tests/regressiontests/servers/tests.py
+index d237c83..e0a66f6 100644
+--- a/tests/regressiontests/servers/tests.py
++++ b/tests/regressiontests/servers/tests.py
+@@ -2,6 +2,7 @@
+ Tests for django.core.servers.
+ """
+ import os
++import sys
+ from urlparse import urljoin
+ import urllib2
+
+@@ -10,8 +11,10 @@ from django.conf import settings
+ from django.core.exceptions import ImproperlyConfigured
+ from django.test import TestCase, LiveServerTestCase
+ from django.core.handlers.wsgi import WSGIHandler
+-from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException
++from django.core.servers.basehttp import (
++ AdminMediaHandler, WSGIRequestHandler, WSGIServerException)
+ from django.test.utils import override_settings
++from django.utils.six import BytesIO, StringIO
- class AdminMediaHandler(handlers.StaticFilesHandler):
- """
+ from .models import Person
+
+@@ -213,3 +216,65 @@ class LiveServerDatabase(LiveServerBase):
+ self.urlopen('/create_model_instance/')
+ names = [person.name for person in Person.objects.all()]
+ self.assertEquals(names, ['jane', 'robert', 'emily'])
++
++
++class Stub(object):
++ def __init__(self, **kwargs):
++ self.__dict__.update(kwargs)
++
++
++class WSGIRequestHandlerTestCase(TestCase):
++
++ def test_strips_underscore_headers(self):
++ """WSGIRequestHandler ignores headers containing underscores.
++
++ This follows the lead of nginx and Apache 2.4, and is to avoid
++ ambiguity between dashes and underscores in mapping to WSGI environ,
++ which can have security implications.
++ """
++ def test_app(environ, start_response):
++ """A WSGI app that just reflects its HTTP environ."""
++ start_response('200 OK', [])
++ http_environ_items = sorted(
++ '%s:%s' % (k, v) for k, v in environ.items()
++ if k.startswith('HTTP_')
++ )
++ yield (','.join(http_environ_items)).encode('utf-8')
++
++ rfile = BytesIO()
++ rfile.write("GET / HTTP/1.0\r\n")
++ rfile.write("Some-Header: good\r\n")
++ rfile.write("Some_Header: bad\r\n")
++ rfile.write("Other_Header: bad\r\n")
++ rfile.seek(0)
++
++ # WSGIRequestHandler closes the output file; we need to make this a
++ # no-op so we can still read its contents.
++ class UnclosableBytesIO(BytesIO):
++ def close(self):
++ pass
++
++ wfile = UnclosableBytesIO()
++
++ def makefile(mode, *a, **kw):
++ if mode == 'rb':
++ return rfile
++ elif mode == 'wb':
++ return wfile
++
++ request = Stub(makefile=makefile)
++ server = Stub(base_environ={}, get_app=lambda: test_app)
++
++ # We don't need to check stderr, but we don't want it in test output
++ old_stderr = sys.stderr
++ sys.stderr = StringIO()
++ try:
++ # instantiating a handler runs the request as side effect
++ WSGIRequestHandler(request, '192.168.0.2', server)
++ finally:
++ sys.stderr = old_stderr
++
++ wfile.seek(0)
++ body = list(wfile.readlines())[-1]
++
++ self.assertEqual(body, 'HTTP_SOME_HEADER:good')
--
2.1.4
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django.git
More information about the Python-modules-commits
mailing list