VYPR
Low severityNVD Advisory· Published Nov 14, 2023· Updated Nov 3, 2025

Inconsistent interpretation of `Content-Length` vs. `Transfer-Encoding` in aiohttp

CVE-2023-47641

Description

aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. Affected versions of aiohttp have a security vulnerability regarding the inconsistent interpretation of the http protocol. HTTP/1.1 is a persistent protocol, if both Content-Length(CL) and Transfer-Encoding(TE) header values are present it can lead to incorrect interpretation of two entities that parse the HTTP and we can poison other sockets with this incorrect interpretation. A possible Proof-of-Concept (POC) would be a configuration with a reverse proxy(frontend) that accepts both CL and TE headers and aiohttp as backend. As aiohttp parses anything with chunked, we can pass a chunked123 as TE, the frontend entity will ignore this header and will parse Content-Length. The impact of this vulnerability is that it is possible to bypass any proxy rule, poisoning sockets to other users like passing Authentication Headers, also if it is present an Open Redirect an attacker could combine it to redirect random users to another website and log the request. This vulnerability has been addressed in release 3.8.0 of aiohttp. Users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
aiohttpPyPI
< 3.8.03.8.0

Affected products

1

Patches

1
f016f0680e4a

Raise '400: Content-Length can't be present with Transfer-Encoding' if both Content-Length and Transfer-Encoding are sent by peer (#6182)

https://github.com/aio-libs/aiohttpAndrew SvetlovOct 31, 2021via ghsa
3 files changed · +25 3
  • aiohttp/http_parser.py+10 2 modified
    @@ -28,6 +28,7 @@
     from .base_protocol import BaseProtocol
     from .helpers import NO_EXTENSIONS, BaseTimerContext
     from .http_exceptions import (
    +    BadHttpMessage,
         BadStatusLine,
         ContentEncodingError,
         ContentLengthError,
    @@ -489,8 +490,15 @@ def parse_headers(
     
             # chunking
             te = headers.get(hdrs.TRANSFER_ENCODING)
    -        if te and "chunked" in te.lower():
    -            chunked = True
    +        if te is not None:
    +            te_lower = te.lower()
    +            if "chunked" in te_lower:
    +                chunked = True
    +
    +            if hdrs.CONTENT_LENGTH in headers:
    +                raise BadHttpMessage(
    +                    "Content-Length can't be present with Transfer-Encoding",
    +                )
     
             return (headers, raw_headers, close_conn, encoding, upgrade, chunked)
     
    
  • CHANGES/6182.bugfix+1 0 added
    @@ -0,0 +1 @@
    +Raise ``400: Content-Length can't be present with Transfer-Encoding`` if both ``Content-Length`` and ``Transfer-Encoding`` are sent by peer by both C and Python implementations
    
  • tests/test_http_parser.py+14 1 modified
    @@ -291,7 +291,20 @@ def test_request_chunked(parser) -> None:
         assert isinstance(payload, streams.StreamReader)
     
     
    -def test_conn_upgrade(parser) -> None:
    +def test_request_te_chunked_with_content_length(parser: Any) -> None:
    +    text = (
    +        b"GET /test HTTP/1.1\r\n"
    +        b"content-length: 1234\r\n"
    +        b"transfer-encoding: chunked\r\n\r\n"
    +    )
    +    with pytest.raises(
    +        http_exceptions.BadHttpMessage,
    +        match="Content-Length can't be present with Transfer-Encoding",
    +    ):
    +        parser.feed_data(text)
    +
    +
    +def test_conn_upgrade(parser: Any) -> None:
         text = (
             b"GET /test HTTP/1.1\r\n"
             b"connection: upgrade\r\n"
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.