Am I affected?
Description
Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling') vulnerability in the HTTP/1.1 chunked body reader of mtrudel bandit allows an unauthenticated remote attacker to smuggle a second request past a front-end proxy via a chunk extension that contains a bare LF.
The chunked reader in lib/bandit/http1/socket.ex takes the chunk-size line to be everything up to the first CRLF and discards everything after ; without checking it against the RFC 9112 chunk-ext grammar, so bare LF, bare CR and other control bytes pass. A proxy that ends the size line at a bare LF reads 2;\nxx\r\n40\r\n... as one request whose second chunk holds a GET /admin, while Bandit ends the body early and dispatches GET /admin as a separate pipelined request. Deployments without such a proxy in front of Bandit are not affected.
This issue affects bandit: from 1.12.4 before 1.14.0.
Technical analysis
1. Unchecked extension. In lib/bandit/http1/socket.ex, the chunked body reader takes the chunk-size line to be everything up to the first CRLF. Anything after ; is thrown away without being checked against the RFC 9112 §7.1.1 chunk-ext grammar, so bare LF, bare CR and other control bytes are accepted. The 16-byte size-line cap does not help, because the payload needs only 5 bytes.
2. Bandit's reading. For the body 2;\nxx\r\n40\r\n0\r\n\r\nGET /admin ..., Bandit takes 2;\nxx as the size line and 40 as the 2-byte chunk, and the embedded 0\r\n\r\n ends the body. Bandit then runs GET /admin as a second pipelined request.
3. The proxy's reading. A proxy that ends the size line at the bare LF sees only one POST, with the chunk xx and a 0x40-byte chunk that holds the GET /admin bytes.
Proof of concept
- Run Bandit with a Plug that reads the body and records each request's method and path.
- On one connection, send
POST /publicwithTransfer-Encoding: chunkedand the body2;\nxx\r\n40\r\n0\r\n\r\n, followed directly byGET /admin HTTP/1.1withContent-Length: 7and the body\r\n0\r\n\r\n. - Bandit dispatches both
POST /publicwith the body40andGET /admin. A proxy that ends lines at a bare LF would have forwarded the same bytes as the singlePOST /public.
Weaknesses & attack patterns
Weakness
CWE-444
·
Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
in catalog →
MITRE ↗
Attack patterns
CAPEC-33
·
HTTP Request Smuggling
MITRE ↗
Behind a front-end proxy that treats a bare LF as a line ending and forwards chunked bodies unchanged, an unauthenticated attacker can have Bandit run requests the proxy never saw, getting past the proxy's access controls.
Affected — Hex / bandit Hex.pm ↗ Repository ↗
Affected — GitHub / mtrudel/bandit Repository ↗
Workarounds
Where the front-end proxy can reach Bandit over HTTP/2, disable HTTP/1 with http_1_options: [enabled: false], so that the chunked body reader never runs.
References
Credits
CVSS breakdown
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N