12345G
on to the back-end, which only reads 12345
before issuing a response. This leaves the back-end socket poisoned with G
. When the legitimate request arrives, it ends up appended onto the G
, causing an unexpected response.G
will corrupt the user's request and they will probably get a response along the lines of "Unknown method GPOST".Content-Length
headers. Double Content-Length header support is strictly forbidden by the RFC 7230 3.3.3:If a message is received without Transfer-Encoding and with either multiple Content-Length header fields having differing field-values or a single Content-Length header field having an invalid value, then the message framing is invalid and the recipient MUST treat it as an unrecoverable error. If this is a request message, the server MUST respond with a 400 (Bad Request) status code and then close the connection. If this is a response message received by a proxy, the proxy MUST close the connection to the server, discard the received response, and send a 502 (Bad Gateway) response to the client. If this is a response message received by a user agent, the user agent MUST close the connection to the server and discard the received response.
400 Bad Request
, because the second query is starting with X-Foo: Bar
and that is an invalid first query line.\r
between the 2 queries):400 Bad Request
and one 200 OK
response. Second query is taken as a valid.GET /index.html?bar=1 HTTP/1.1
is a bad header and most agent will reject early the fake pipeline as a bad query, becauseLOCATION
may be used to inject the special [:]
that is required in an header line, especially on the query string part, but this would inject a lot of bad characters in the HEADER-NAME-NO-SPACE
part, like '/' or '?'.[:]
comes with the line, and the bad character for an HEADER-NAME-NO-SPACE
will only be a space. This will also fix the potential presence of the double Host
header (absolute uri does replace the Host
header).GET http://vulnerable-website.com/index.html?bar=1 HTTP/1.1
will be parse like header with name is GET http
and value is //vulnerable-website.com/index.html?bar=1 HTTP/1.1
. This is still an invalid header (the header name contains a space), but some HTTP agents pass such a header. And after the error 400 Bad Request
we have a 200 OK
response.400 Bad Request
and a 200 OK
response.Transfer-Encoding: chunked
and Content-Length
, few servers reject such requests:If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
Transfer-Encoding
header from one server in a chain it will fall back to using the Content-Length
and we can desynchronize the whole system. The exact way in which this is done depends on the behavior of the two servers:Content-Length
header and the back-end server uses the Transfer-Encoding
header,Transfer-Encoding
header and the back-end server uses the Content-Length
header,Transfer-Encoding
header, but one of the servers can be induced not to process it by obfuscating the header in some way.\r
, followed by the chunk contents. The message is terminated with a chunk of size 0, followed by a newline \r
. Example:Each header field consists of a case-insensitive field name followed by a colon (":"), optional leading whitespace, the field value, and optional trailing whitespace.
No whitespace is allowed between the header field-name and colon. In the past, differences in the handling of such whitespace have led to security vulnerabilities in request routing and response handling. A server MUST reject any received request message that contains whitespace between a header field-name and colon with a response code of 400 (Bad Request). A proxy MUST remove any such whitespace from a response message before forwarding the message downstream.
Content-Length
header and the back-end server uses the Transfer-Encoding
header. We can perform a simple HTTP request smuggling attack as follows:Content-Length
header and determines that the request body is 13 bytes long, up to the end of SMUGGLED. This request is forwarded on to the back-end server.Transfer-Encoding
header, and so treats the message body as using chunked encoding. It processes the first chunk, which is stated to be zero length, and so is treated as terminating the request. The following bytes, SMUGGLED, are left unprocessed, and the back-end server will treat these as being the start of the next request in the sequence.Transfer-Encoding
header and the back-end server uses the Content-Length
header. We can perform a simple HTTP request smuggling attack as follows:Transfer-Encoding
header, and so treats the message body as using chunked encoding. It processes the first chunk, which is stated to be 8 bytes long, up to the start of the line following SMUGGLED. It processes the second chunk, which is stated to be zero length, and so is treated as terminating the request. This request is forwarded on to the back-end server.Content-Length
header and determines that the request body is 3 bytes long, up to the start of the line following 8. The following bytes, starting with SMUGGLED, are left unprocessed, and the back-end server will treat these as being the start of the next request in the sequence.Transfer-Encoding
header, but one of the servers can be induced not to process it by obfuscating the header in some way.Transfer-Encoding
header, for example:Transfer-Encoding
header such that only one of the front-end or back-end servers processes it, while the other server ignores it.Transfer-Encoding
header, the remainder of the attack will take the same form as for the CL.TE or TE.CL vulnerabilities.