Skip to content

deny injection of custom http headers #4818

Closed
@xppt

Description

Hello!

I've noticed, that aiohttp is simply concatenating server-response (or client-request) header like this, w/o any validation:

    line = status_line + '\r\n' + ''.join(
        [k + ': ' + v + '\r\n' for k, v in headers.items()])

Which may be not okay, if some of the header values were based on user input.

Consider this example:

import aiohttp.web
async def handler(req: aiohttp.web.Request):
    return aiohttp.web.Response(headers={
        'X-Debug-Param': req.query.get('param', ''),
    })
app = aiohttp.web.Application()
app.add_get('/', handler)

This code seems to be fine. Unfortunately it is not, since an attacker can craft urls that will force this handler to return any custom http-headers, or skip some of the existing ones, or broke http payload:

/?param=%0d%0aLocation:%20https://malware.host/  # open redirect
/?param=%0d%0aSet-Cookie:%20...                  # set some cookie
/?param=%0d%0aContent-Length:%2040%0d%0a         # skip next headers

and so on.

I think that aiohttp should raise an exception for any http-reason, header-name or header-value that contains \r or \n characters, instead of breaking http payload silently.

Actually this is what flask/werkzeug do for header-value:

	if u"\n" in value or u"\r" in value:
		raise ValueError(
			"Detected newline in header value.  This is "
			"a potential security problem"
		)

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions