Apr 15, 2026·5 min read·2 visits
Jetty incorrectly terminates HTTP/1.1 chunk extension parsing when encountering a newline inside a quoted string, allowing attackers to desynchronize proxies and back-ends to smuggle malicious requests.
Eclipse Jetty's HTTP/1.1 parser contains a state-machine flaw when handling chunked transfer encoding extensions, leading to critical HTTP Request Smuggling via "Funky Chunks" techniques.
Eclipse Jetty is susceptible to HTTP Request Smuggling (CWE-444) within its HTTP/1.1 parser. The vulnerability targets the parsing logic for chunked transfer encoding, specifically how the parser handles chunk extensions containing quoted strings. This flaw permits an attacker to desynchronize the request stream between a front-end proxy and the Jetty back-end.
The vulnerability is classified as a variant of the "Funky Chunks" exploitation methodology. It exploits ambiguous handling of line terminators within HTTP message bodies. By manipulating the chunk size parameters, an attacker can manipulate how different servers in the request chain interpret the start and end of HTTP requests.
Successful desynchronization occurs because the front-end proxy and the Jetty back-end disagree on the boundaries of the HTTP message. This disagreement allows the injection of a smuggled, secondary request that bypasses edge security controls and is executed directly by the internal application logic.
According to RFC 9112 and RFC 9110, HTTP/1.1 chunk extensions can encapsulate values within quoted strings. These quoted strings are strictly prohibited from containing raw Carriage Return Line Feed (CRLF) sequences. The vulnerability exists within the state machine of Jetty's HttpParser.java during the CHUNK_PARAMS parsing phase.
When the parser encounters a double quote character, it fails to securely bound the quoted-string state. Instead of rejecting a CRLF sequence encountered within the quotes, or treating it as a literal malformed character, Jetty prioritizes the global search for \r\n. The parser incorrectly interprets the embedded CRLF as the termination of the chunk header.
This premature termination creates a fundamental synchronization discrepancy. An RFC-compliant front-end proxy parses the chunk extension correctly, treating the embedded CRLF as part of a malformed extension and forwarding the payload as a single continuous request. The Jetty back-end stops parsing the chunk header at the first CRLF, interpreting the subsequent bytes as the chunk body and eventually as an entirely new HTTP request.
The core vulnerability resides in the state-machine execution within HttpParser.java. During the processing of the CHUNK_PARAMS state, Jetty fails to suppress the detection of end-of-line markers when processing a quoted string.
The logic incorrectly prioritizes the structural markers of the HTTP protocol over the encapsulation rules of the quoted string parameter.
// Conceptual representation of the flawed parsing logic in Jetty
while (parsingChunkParams) {
byte ch = buffer.get();
if (ch == '"') {
inQuotedString = !inQuotedString;
}
// VULNERABILITY: CRLF check executes regardless of inQuotedString state
if (ch == '\n') {
transitionTo(State.CHUNK_BODY);
}
}The patched implementations (e.g., in commit 91435debf6bb5b2701e96f2202962ea262d38236) modify this logic to properly track quoted string boundaries. The parser now implements strict validation to reject control characters like CR or LF within a quoted string, aligning the parser with RFC compliance and preventing premature header termination.
The "Funky Chunks" exploitation technique requires sending a specifically crafted HTTP POST request using chunked transfer encoding. The attacker injects a chunk extension containing an unclosed double quote followed by a raw newline.
POST / HTTP/1.1
Host: vulnerable-app.com
Transfer-Encoding: chunked
1;ext="val
X
0
GET /smuggled-endpoint HTTP/1.1
Host: internal-serviceThe proxy forwards this payload as a single request because the chunk extension does not appear properly terminated according to its internal logic. Jetty parses 1;ext="val and terminates the header at the newline.
Jetty reads X as the 1-byte chunk body declared by the hexadecimal 1. The subsequent 0 terminates the chunked stream for the first request, causing Jetty to process the GET /smuggled-endpoint payload as a secondary, smuggled request.
The exploit relies entirely on the behavioral difference between the proxy and the back-end server. The following sequence illustrates the stream interpretation.
The front-end proxy perceives the entire payload as a single, in-flight POST request. The Jetty back-end splits the stream, effectively executing the GET /smuggled-endpoint request in the context of the back-end connection pool.
Successful exploitation grants the attacker the ability to bypass front-end security controls, such as Web Application Firewalls (WAF) or access control lists (ACL). The smuggled request is processed directly by the back-end application, evading all edge validation.
Depending on the application routing, this flaw facilitates cache poisoning, cross-user session hijacking, and unauthorized access to restricted endpoints. An attacker can manipulate backend routing to extract sensitive data belonging to other users sharing the same connection pool.
The CVSS 3.1 base score is 7.4 (High), reflecting the significant impact on confidentiality and integrity. The attack complexity is rated High because successful exploitation explicitly requires a specific behavioral differential between the upstream proxy and the Jetty server.
Administrators must upgrade Eclipse Jetty to versions 9.4.60, 10.0.28, 11.0.28, 12.0.33, or 12.1.7. These releases contain the corrected state machine logic for parsing HTTP/1.1 chunk extensions, neutralizing the vulnerability at the source.
If immediate patching is unfeasible, administrators can deploy interim mitigations at the proxy layer. Front-end load balancers or WAFs should be configured to strictly normalize HTTP/1.1 chunked requests. Stripping chunk extensions entirely before forwarding the request to the back-end neutralizes this specific exploitation vector.
As a defense-in-depth measure, disabling HTTP/1.1 keep-alive connections between the proxy and the back-end prevents request smuggling entirely. This approach ensures each request utilizes a distinct TCP connection, eliminating the shared stream required for desynchronization, though this incurs a notable performance penalty.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Eclipse Jetty Eclipse Foundation | 9.4.0 <= version <= 9.4.59 | 9.4.60 |
Eclipse Jetty Eclipse Foundation | 10.0.0 <= version <= 10.0.27 | 10.0.28 |
Eclipse Jetty Eclipse Foundation | 11.0.0 <= version <= 11.0.27 | 11.0.28 |
Eclipse Jetty Eclipse Foundation | 12.0.0 <= version <= 12.0.32 | 12.0.33 |
Eclipse Jetty Eclipse Foundation | 12.1.0 <= version <= 12.1.6 | 12.1.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-444 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.4 (High) |
| EPSS Score | 0.00031 |
| Impact | High Confidentiality, High Integrity |
| Exploit Status | Proof-of-Concept (PoC) |
| KEV Status | Not Listed |
Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')