X-Forwarded-For improvements and bug fixes (#15204)

* Use new trusted_proxies setting for X-Forwarded-For whitelist

* Only use the last IP in the header

Per Wikipedia (https://en.wikipedia.org/wiki/X-Forwarded-For#Format):

 > The last IP address is always the IP address that connects to the last proxy,
 > which means it is the most reliable source of information.

* Add two additional tests

* Ignore nonsense header values instead of failing
This commit is contained in:
Colin O'Dell
2018-06-29 16:27:06 -04:00
committed by Paulus Schoutsen
parent c61a652c90
commit fd38caa287
5 changed files with 67 additions and 9 deletions
+48
View File
@@ -58,3 +58,51 @@ async def test_use_x_forwarded_for_with_trusted_proxy(aiohttp_client):
assert resp.status == 200
text = await resp.text()
assert text == '255.255.255.255'
async def test_use_x_forwarded_for_with_untrusted_proxy(aiohttp_client):
"""Test that we get the IP from the transport."""
app = web.Application()
app.router.add_get('/', mock_handler)
setup_real_ip(app, True, [ip_network('1.1.1.1')])
mock_api_client = await aiohttp_client(app)
resp = await mock_api_client.get('/', headers={
X_FORWARDED_FOR: '255.255.255.255'
})
assert resp.status == 200
text = await resp.text()
assert text != '255.255.255.255'
async def test_use_x_forwarded_for_with_spoofed_header(aiohttp_client):
"""Test that we get the IP from the transport."""
app = web.Application()
app.router.add_get('/', mock_handler)
setup_real_ip(app, True, [ip_network('127.0.0.1')])
mock_api_client = await aiohttp_client(app)
resp = await mock_api_client.get('/', headers={
X_FORWARDED_FOR: '222.222.222.222, 255.255.255.255'
})
assert resp.status == 200
text = await resp.text()
assert text == '255.255.255.255'
async def test_use_x_forwarded_for_with_nonsense_header(aiohttp_client):
"""Test that we get the IP from the transport."""
app = web.Application()
app.router.add_get('/', mock_handler)
setup_real_ip(app, True, [ip_network('127.0.0.1')])
mock_api_client = await aiohttp_client(app)
resp = await mock_api_client.get('/', headers={
X_FORWARDED_FOR: 'This value is invalid'
})
assert resp.status == 200
text = await resp.text()
assert text == '127.0.0.1'
+1
View File
@@ -160,6 +160,7 @@ class TestCheckConfig(unittest.TestCase):
'server_host': '0.0.0.0',
'server_port': 8123,
'trusted_networks': [],
'trusted_proxies': [],
'use_x_forwarded_for': False}
assert res['secret_cache'] == {secrets_path: {'http_pw': 'abc123'}}
assert res['secrets'] == {'http_pw': 'abc123'}