summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTres Seaver <tseaver@palladion.com>2014-03-10 12:06:52 -0400
committerTres Seaver <tseaver@palladion.com>2014-03-10 12:06:52 -0400
commitab015fd0b9e28ecf1adada6e53e2f66c3925b301 (patch)
tree8b0361588e6eb6c2179823d085a0ddc12d410b1d
parent486315c33ecbbc19f29a8947615e8ecabfc6ad6c (diff)
downloadwaitress-ab015fd0b9e28ecf1adada6e53e2f66c3925b301.tar.gz
Only allow trustted proxies to overried request.urlscheme.
-rw-r--r--waitress/task.py8
-rw-r--r--waitress/tests/test_task.py24
2 files changed, 28 insertions, 4 deletions
diff --git a/waitress/task.py b/waitress/task.py
index 7dcd8a4..e28df4c 100644
--- a/waitress/task.py
+++ b/waitress/task.py
@@ -483,10 +483,14 @@ class WSGITask(Task):
environ['SCRIPT_NAME'] = url_prefix
environ['PATH_INFO'] = path
environ['QUERY_STRING'] = request.query
- environ['REMOTE_ADDR'] = channel.addr[0]
+ host = environ['REMOTE_ADDR'] = channel.addr[0]
headers = dict(request.headers)
- wsgi_url_scheme = headers.pop('X_FORWARDED_PROTO', request.url_scheme)
+ if host == server.adj.trusted_proxy:
+ wsgi_url_scheme = headers.pop('X_FORWARDED_PROTO',
+ request.url_scheme)
+ else:
+ wsgi_url_scheme = request.url_scheme
if wsgi_url_scheme not in ('http', 'https'):
raise ValueError('Invalid X_FORWARDED_PROTO value')
for key, value in headers.items():
diff --git a/waitress/tests/test_task.py b/waitress/tests/test_task.py
index 8abb1e5..14a84f3 100644
--- a/waitress/tests/test_task.py
+++ b/waitress/tests/test_task.py
@@ -650,9 +650,26 @@ class TestWSGITask(unittest.TestCase):
self.assertEqual(environ['wsgi.input'], 'stream')
self.assertEqual(inst.environ, environ)
- def test_get_environment_values_w_scheme_override(self):
+ def test_get_environment_values_w_scheme_override_untrusted(self):
+ inst = self._makeOne()
+ request = DummyParser()
+ request.headers = {
+ 'CONTENT_TYPE': 'abc',
+ 'CONTENT_LENGTH': '10',
+ 'X_FOO': 'BAR',
+ 'X_FORWARDED_PROTO': 'https',
+ 'CONNECTION': 'close',
+ }
+ request.query = 'abc'
+ inst.request = request
+ environ = inst.get_environment()
+ self.assertEqual(environ['wsgi.url_scheme'], 'http')
+
+ def test_get_environment_values_w_scheme_override_trusted(self):
import sys
inst = self._makeOne()
+ inst.channel.addr = ['192.168.1.1']
+ inst.channel.server.adj.trusted_proxy = '192.168.1.1'
request = DummyParser()
request.headers = {
'CONTENT_TYPE': 'abc',
@@ -683,7 +700,7 @@ class TestWSGITask(unittest.TestCase):
self.assertEqual(environ['HTTP_CONNECTION'], 'close')
self.assertEqual(environ['PATH_INFO'], '/')
self.assertEqual(environ['QUERY_STRING'], 'abc')
- self.assertEqual(environ['REMOTE_ADDR'], '127.0.0.1')
+ self.assertEqual(environ['REMOTE_ADDR'], '192.168.1.1')
self.assertEqual(environ['CONTENT_TYPE'], 'abc')
self.assertEqual(environ['CONTENT_LENGTH'], '10')
self.assertEqual(environ['HTTP_X_FOO'], 'BAR')
@@ -698,6 +715,8 @@ class TestWSGITask(unittest.TestCase):
def test_get_environment_values_w_bogus_scheme_override(self):
inst = self._makeOne()
+ inst.channel.addr = ['192.168.1.1']
+ inst.channel.server.adj.trusted_proxy = '192.168.1.1'
request = DummyParser()
request.headers = {
'CONTENT_TYPE': 'abc',
@@ -817,6 +836,7 @@ class DummyAdj(object):
host = '127.0.0.1'
port = 80
url_prefix = ''
+ trusted_proxy = None
class DummyServer(object):
server_name = 'localhost'