Twisted: HTTP Request Smuggling in twisted.web via a Bare CR or LF in a Header Value
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 直った版 |
|---|---|---|---|
| twisted | twisted | — | — |
| pip | Twisted |
26.10.0rc1 未満 |
26.10.0rc1 |
| PyPI | twisted |
26.10.0rc1 未満 |
26.10.0rc1 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Summary
An incomplete header-value validation (CWE-444) in the Twisted HTTP server lets a bare carriage return or line feed in a header value hide a following header from the parser. twisted.web.http.HTTPChannel.headerReceived rejects a NUL byte in a header value but not a bare CR or LF, even though RFC 9110 section 5.5 requires a recipient to reject all three. Because the channel splits requests only on CRLF, a value carrying a bare LF and a second header arrives as one line, so the second header is folded into the value and the request is framed with no body. A front-end that treats the bare LF as a line terminator frames the request differently, and the disagreement lets an attacker smuggle a request past it. This is an incomplete fix of the earlier Twisted request-smuggling advisories, which guarded the NUL sibling of this exact check.
Details
headerReceived splits a header line on the first colon, strips space and tab from the value, and validates it with a single test that rejects only NUL:
# twisted/web/http.py HTTPChannel.headerReceived
data = data.strip(b" \t")
if b"\x00" in data: # NUL rejected; a bare CR or LF is not
self._respondToBadRequestAndDisconnect()
return False
The channel delimiter is CRLF, so Foo: x\nContent-Length: 39 is one line: the split yields name Foo and value x\nContent-Length: 39, strip leaves the LF, and the NUL check passes. _maybeChooseTransferDecoder is then called with Foo, never se…
出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory