[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