Skip to content

Support custom Forwarded header parameters #2170

Closed
@vfaronov

Description

Long story short

aiohttp.web.BaseRequest.forwarded does not parse the Forwarded header in accordance with RFC 7239. In particular, it does not support custom parameters.

The whole point of deploying Forwarded instead of the legacy X-Forwarded-* zoo is extensibility. For example, custom parameters could be very useful for identifying proxies reliably (as opposed to the current practice of “take the nth proxy from the end”).

Expected behaviour

Given a request with headers:

Forwarded: for=203.40.91.97;by=10.1.2.3;secret=JxED1spY6t;
Forwarded: for=10.1.2.3;by=10.4.5.6;;some="other, stuff"

the forwarded attribute should have the value:

(
    mappingproxy({
        'for': '203.40.91.97',
        'by': '10.1.2.3',
        'secret': 'JxED1spY6t',
    }),
    mappingproxy({
        'for': '10.1.2.3',
        'by': '10.4.5.6',
        'some': 'other, stuff',
    }),
)

Actual behaviour

The forwarded attribute has the value ({}, {}, {}).

Note how a comma inside a quoted-string confuses aiohttp, which could even lead to security problems if the application is programmed to look at the nth value from the end or the beginning.

Steps to reproduce

Run this server program:

from aiohttp import web
async def handle(request):
    return web.Response(text=repr(request.forwarded))
app = web.Application()
app.router.add_get('/', handle)
web.run_app(app)

and send requests to it with curl:

$ curl -v localhost:8080/ \
>   -H 'Forwarded: for=203.40.91.97;by=10.1.2.3;secret=JxED1spY6t;' \
>   -H 'Forwarded: for=10.1.2.3;by=10.4.5.6;;some="other, stuff"'

Your environment

aiohttp Git master, Python 3.5, Linux

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions