VYPR
Low severity2.7GHSA Advisory· Published Jun 15, 2026· Updated Jun 15, 2026

aiohttp: CRLF injection in multipart headers

CVE-2026-50269

Description

CRLF injection in aiohttp's multipart header handling allows header injection when user input is passed to MultipartWriter.append or Payload.headers.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CRLF injection in aiohttp's multipart header handling allows header injection when user input is passed to MultipartWriter.append or Payload.headers.

Vulnerability

A CRLF injection vulnerability exists in the aiohttp library (versions <= 3.13.5) within the MultipartWriter.append() method and the Payload.headers property. When an application passes attacker-controlled strings as header values or names, the library does not sanitize the input for \r, \n, or null bytes before constructing multipart boundaries, allowing an attacker to inject arbitrary headers into the HTTP request. The vulnerable code path is reachable only if the application actively passes unsanitized user input to these specific API calls [1][2].

Exploitation

An attacker must find an application that uses aiohttp and passes unvalidated user input into either MultipartWriter.append(headers=...) or directly into Payload.headers dict. The attacker can then include CR (\r), LF (\n), or null bytes in the input, which when processed by _binary_headers will result in injected header lines. No authentication or special network position is required beyond normal access to the application's user-controllable input fields that feed into these functions. The fix includes parameterized tests that demonstrate injection attempts with \r, \n, and \x00 in both header names and values [3].

Impact

Successful exploitation allows an attacker to modify the request by injecting additional HTTP headers or altering the content structure. This could lead to request smuggling, cache poisoning, or bypassing security controls depending on the downstream handling. The impact is limited to header injection in multipart requests; it is not a direct remote code execution or data disclosure vulnerability. The severity is rated low by the maintainers due to the prerequisite condition of the application passing unsanitized user input into specific aiohttp APIs [1][2].

Mitigation

The vulnerability is fixed in commit bf88077, which adds validation in _binary_headers to reject any header value or name containing \r, \n, or \x00 characters with a ValueError matching "header injection" [3]. Users should upgrade to aiohttp version > 3.13.5. As a workaround, applications should sanitize all user input before passing it to MultipartWriter.append(), Payload.headers, or any header-related parameters, ensuring that no CR, LF, or null bytes are present [1][2].

AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

1
bf88077ebb14

[PR #12719/879d48d1 backport][3.14] Reject invalid bytes in multipart/payload headers (#12720)

https://github.com/aio-libs/aiohttppatchback[bot]May 28, 2026via ghsa
3 files changed · +21 3
  • aiohttp/payload.py+5 3 modified
    @@ -23,6 +23,7 @@
         parse_mimetype,
         sentinel,
     )
    +from .http_writer import _safe_header
     from .streams import StreamReader
     from .typedefs import JSONBytesEncoder, JSONEncoder, _CIMultiDict
     
    @@ -197,9 +198,10 @@ def headers(self) -> _CIMultiDict:
         @property
         def _binary_headers(self) -> bytes:
             return (
    -            "".join([k + ": " + v + "\r\n" for k, v in self.headers.items()]).encode(
    -                "utf-8"
    -            )
    +            "".join(
    +                _safe_header(k) + ": " + _safe_header(v) + "\r\n"
    +                for k, v in self.headers.items()
    +            ).encode("utf-8")
                 + b"\r\n"
             )
     
    
  • CHANGES/12706.bugfix.rst+1 0 added
    @@ -0,0 +1 @@
    +Fixed invalid bytes being allowed in multipart/payload headers -- by :user:`Dreamsorcerer`.
    
  • tests/test_payload.py+15 0 modified
    @@ -101,6 +101,21 @@ def test_payload_content_type() -> None:
         assert p.content_type == "application/json"
     
     
    +@pytest.mark.parametrize("bad_byte", ("\r", "\n", "\x00"))
    +def test_binary_headers_reject_injection_in_value(bad_byte: str) -> None:
    +    p = Payload("test", headers={"X-Custom": f"value{bad_byte}Injected: bad"})
    +    with pytest.raises(ValueError, match="header injection"):
    +        p._binary_headers
    +
    +
    +@pytest.mark.parametrize("bad_byte", ("\r", "\n", "\x00"))
    +def test_binary_headers_reject_injection_in_name(bad_byte: str) -> None:
    +    p = Payload("test")
    +    p.headers[f"X-Custom{bad_byte}Injected"] = "value"
    +    with pytest.raises(ValueError, match="header injection"):
    +        p._binary_headers
    +
    +
     def test_bytes_payload_default_content_type() -> None:
         p = payload.BytesPayload(b"data")
         assert p.content_type == "application/octet-stream"
    

Vulnerability mechanics

Root cause

"Missing validation of header name and value bytes allows injection of CR/LF characters, enabling HTTP header injection."

Attack vector

An attacker who can control strings passed into `MultipartWriter.append(headers=...)` or `Payload.headers` can inject carriage return (`\r`) or newline (`\n`) characters to break out of the intended header line and inject arbitrary additional HTTP headers or alter the request body. This is a classic HTTP header injection attack [CWE-113]. The attacker must have the ability to supply unsanitized input to these header parameters, which is described as an 'unlikely situation' in the advisory.

Affected code

The vulnerability resides in `aiohttp/payload.py` in the `_binary_headers` property, which concatenates header names and values directly without sanitization. The patch introduces a call to `_safe_header()` from `http_writer` to reject bytes `\r`, `\n`, and `\x00` in both header names and values.

What the fix does

The patch modifies `_binary_headers` in `payload.py` to pass each header name and value through `_safe_header()` before concatenation. `_safe_header()` raises a `ValueError` if the input contains `\r`, `\n`, or `\x00` bytes, preventing an attacker from injecting line breaks into the serialized header block. The corresponding tests verify that both header names and values containing these bad bytes are rejected with a 'header injection' error.

Preconditions

  • inputThe application must pass user-controlled strings into `MultipartWriter.append(headers=...)` or `Payload.headers`.
  • inputThe attacker-supplied string must contain `\r`, `\n`, or `\x00` bytes to break out of the header line.

Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.