VYPR
Critical severity9.1NVD Advisory· Published Apr 1, 2026· Updated Apr 16, 2026

CVE-2026-34520

CVE-2026-34520

Description

AIOHTTP is an asynchronous HTTP client/server framework for asyncio and Python. Prior to version 3.13.4, the C parser (the default for most installs) accepted null bytes and control characters in response headers. This issue has been patched in version 3.13.4.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
aiohttpPyPI
< 3.13.43.13.4

Affected products

1
  • cpe:2.3:a:aiohttp:aiohttp:*:*:*:*:*:*:*:*
    Range: <3.13.4

Patches

1
9370b9714a7a

[PR #12231/7043bc56 backport][3.13] Adjust header value character checks to RFC 9110 (#12235)

https://github.com/aio-libs/aiohttpRodrigo NogueiraMar 11, 2026via ghsa
3 files changed · +20 1
  • aiohttp/http_parser.py+8 1 modified
    @@ -81,6 +81,10 @@
     #     token = 1*tchar
     _TCHAR_SPECIALS: Final[str] = re.escape("!#$%&'*+-.^_`|~")
     TOKENRE: Final[Pattern[str]] = re.compile(f"[0-9A-Za-z{_TCHAR_SPECIALS}]+")
    +# https://www.rfc-editor.org/rfc/rfc9110#section-5.5-5
    +_FIELD_VALUE_FORBIDDEN_CTL_RE: Final[Pattern[str]] = re.compile(
    +    r"[\x00-\x08\x0a-\x1f\x7f]"
    +)
     VERSRE: Final[Pattern[str]] = re.compile(r"HTTP/(\d)\.(\d)", re.ASCII)
     DIGITS: Final[Pattern[str]] = re.compile(r"\d+", re.ASCII)
     HEXDIGITS: Final[Pattern[bytes]] = re.compile(rb"[0-9a-fA-F]+")
    @@ -208,7 +212,10 @@ def parse_headers(
                 value = bvalue.decode("utf-8", "surrogateescape")
     
                 # https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-5
    -            if "\n" in value or "\r" in value or "\x00" in value:
    +            if self._lax:
    +                if "\n" in value or "\r" in value or "\x00" in value:
    +                    raise InvalidHeader(bvalue)
    +            elif _FIELD_VALUE_FORBIDDEN_CTL_RE.search(value):
                     raise InvalidHeader(bvalue)
     
                 headers.add(name, value)
    
  • CHANGES/12231.bugfix.rst+2 0 added
    @@ -0,0 +1,2 @@
    +Adjusted pure-Python request header value validation to align with RFC 9110 control-character handling, while preserving lax response parser behavior, and added regression tests for Host/header control-character cases.
    +-- by :user:`rodrigobnogueira`.
    
  • tests/test_http_parser.py+10 0 modified
    @@ -221,6 +221,9 @@ def test_bad_header_name(parser: Any, rfc9110_5_6_2_token_delim: str) -> None:
             "Foo : bar",  # https://www.rfc-editor.org/rfc/rfc9112.html#section-5.1-2
             "Foo\t: bar",
             "\xffoo: bar",
    +        "Foo: abc\x01def",  # CTL bytes forbidden per RFC 9110 §5.5
    +        "Foo: abc\x7fdef",  # DEL is also a CTL byte
    +        "Foo: abc\x1fdef",
         ),
     )
     def test_bad_headers(parser: Any, hdr: str) -> None:
    @@ -229,6 +232,13 @@ def test_bad_headers(parser: Any, hdr: str) -> None:
             parser.feed_data(text)
     
     
    +def test_ctl_host_header_bad_characters(parser: HttpRequestParser) -> None:
    +    """CTL byte in Host header must be rejected."""
    +    text = b"GET /test HTTP/1.1\r\nHost: trusted.example\x01@bad.test\r\n\r\n"
    +    with pytest.raises(http_exceptions.BadHttpMessage):
    +        parser.feed_data(text)
    +
    +
     def test_unpaired_surrogate_in_header_py(loop: Any, protocol: Any) -> None:
         parser = HttpRequestParserPy(
             protocol,
    

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

5

News mentions

0

No linked articles in our index yet.