Commit 8ed2f2b6 authored by Jason Madden's avatar Jason Madden

Strip incoming headers that contain an underscore. Fixes #819.

parent ff5ca13b
......@@ -46,6 +46,8 @@ Security
``start_response`` do not contain a carriage return or newline in
order to prevent HTTP response splitting (header injection), raising
a :exc:`ValueError` if they do. See :issue:`775`.
- Incoming headers containing an underscore are no longer placed in
the WSGI environ. See :issue:`819`.
- Errors logged by :class:`~gevent.pywsgi.WSGIHandler` no
longer print the entire WSGI environment by default. This avoids
possible information disclosure vulnerabilities. Applications can
......
......@@ -1010,18 +1010,23 @@ class WSGIHandler(object):
def _headers(self):
key = None
value = None
IGNORED_KEYS = (None, 'CONTENT_TYPE', 'CONTENT_LENGTH')
for header in self.headers.headers:
if key is not None and header[:1] in " \t":
value += header
continue
if key not in (None, 'CONTENT_TYPE', 'CONTENT_LENGTH'):
if key not in IGNORED_KEYS:
yield 'HTTP_' + key, value.strip()
key, value = header.split(':', 1)
if '_' in key:
# strip incoming bad veaders
key = None
else:
key = key.replace('-', '_').upper()
if key not in (None, 'CONTENT_TYPE', 'CONTENT_LENGTH'):
if key not in IGNORED_KEYS:
yield 'HTTP_' + key, value.strip()
def get_environ(self):
......
......@@ -36,7 +36,7 @@ from gevent.hub import _get_hub
from functools import wraps
import contextlib
import gc
import six
import _six as six
PYPY = hasattr(sys, 'pypy_version_info')
......
"""Check __all__, __implements__, __extensions__, __imports__ of the modules"""
from __future__ import print_function
import six
import _six as six
import sys
import unittest
import types
......
......@@ -2,7 +2,7 @@ import greentest
import gevent
from gevent import socket
from gevent import backdoor
from six import xrange
from _six import xrange
def read_until(conn, postfix):
......
import greentest
import gevent
from gevent.event import Event, AsyncResult
from six import xrange
from _six import xrange
DELAY = 0.01
......
import gevent
import sys
import greentest
import six
import _six as six
if not six.PY3:
sys.exc_clear()
......
from greentest import walk_modules, BaseTestCase, main, NON_APPLICABLE_SUFFIXES
import six
import _six as six
class TestExec(BaseTestCase):
......
import gevent
import greentest
from six import xrange
from _six import xrange
class appender(object):
......
import sys
import six
import _six as six
from os import pipe
from gevent import os
from greentest import TestCase, main
......
......@@ -6,7 +6,7 @@ from gevent.queue import Queue
import greentest
import random
from greentest import ExpectedException
import six
import _six as six
import unittest
......
......@@ -1363,6 +1363,21 @@ class TestInvalidEnviron(TestCase):
read_http(fd)
class TestInvalidHeadersDropped(TestCase):
validator = None
# check that invalid headers with a _ are dropped
def application(self, environ, start_response):
self.assertNotIn('HTTP_X_AUTH_USER', environ)
start_response('200 OK', [])
return []
def test(self):
fd = self.makefile()
fd.write('GET / HTTP/1.0\r\nx-auth_user: bob\r\n\r\n')
read_http(fd)
class Handler(pywsgi.WSGIHandler):
def read_requestline(self):
......
import six
import _six as six
import sys
import os
import errno
......
......@@ -7,7 +7,7 @@ import traceback
import time
import greentest
from functools import wraps
import six
import _six as six
# we use threading on purpose so that we can test both regular and gevent sockets with the same code
from threading import Thread as _Thread
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
import six
import _six as six
import re
import greentest
import socket
......@@ -8,7 +8,7 @@ from time import time
import gevent
import gevent.socket as gevent_socket
from util import log
from six import xrange
from _six import xrange
resolver = gevent.get_hub().resolver
......
import sys
from six import xrange
from _six import xrange
if 'runtestcase' in sys.argv[1:]:
......
......@@ -7,7 +7,7 @@ import gevent.threadpool
from gevent.threadpool import ThreadPool
import gevent
from greentest import ExpectedException
import six
import _six as six
import gc
......
......@@ -2,7 +2,7 @@ from contextlib import contextmanager
import gevent
from gevent.event import Event
from time import time
from six import xrange
from _six import xrange
SMALL = 0.1
......
......@@ -9,7 +9,7 @@ try:
from test import support as test_support
except ImportError:
from test import test_support
from six import xrange
from _six import xrange
QUEUE_SIZE = 5
......
# testing gevent's Event, Lock, RLock, Semaphore, BoundedSemaphore with standard test_threading
from __future__ import print_function
from six import xrange
from _six import xrange
setup_ = '''from gevent import monkey; monkey.patch_all()
from gevent.event import Event
......
#!/usr/bin/env python
from __future__ import print_function
import six
import _six as six
import sys
import os
import glob
......
import sys
import os
import six
import _six as six
import traceback
import unittest
import threading
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment