notes
Last updated
Last updated
technique for interfering with the way a web stie processes sequences of HTTP requests that are received from one or more users
Request smuggling vulnerabilities are often critical in nature, allowing an attacker to
bypass security controls
gain unauthorized access to sensitive data, and
directly compromise other application users
For most of today's web application, users send requests to a front-end server (load balancer or reverse proxy) and this server forwards requests to one or more back-end servers
it typically sends several requests over the same back-end network connection
HTTP requests are sent on after another, and the receiving server parses the HTTP request headers to determine where one request ends and the next one begins
In this situation, it is crucial that the front-end and back-end systems agree about the boundaries between requests
an attacker might be able to send an ambiguous request that gets interpreted differently by the front-end and back-end systems
the HTTP specification provides two different ways to specify where a request ends: the Content-Length
header and the Transfer-Encoding
header
Content-Length
- specifies the length of the message body in bytes
Transfer-Encoding
- specifies that the message body uses chunked encoding; message body contains one or more chunks of data; each chunk consists of the chunk size in bytes (in hexadecimal) followed by a newline, followed by the chunk contents
since the HTTP specification provides two different methods for specifying the length of HTTP messages, it is possible for a single message to use both methods at once, such that they conflict with each other
if both headers are present, Content-Length
should be ignored (only a single server is in play and not for two or more servers are chained together)
if the front-end and back-end servers behave differently for the Transfer-Encoding
, then they might disagree about the boundaries between successive requests, leading to request smuggling vulnerabilities
placing both the Content-Length
and Transfer-Encoding
headers into a single HTTP request and manipulating these so that the front-end and back-end servers process the request differently
it depends on the behavior of the two servers:
CL.TE - front-end server uses the Content-Length
header and the back-end server uses the Transfer-Encoding
header
TE.CL - front-end uses Transfer-Encoding
and back-end uses Content-Length
TE.TE - both front and back-end support Transfer-Encoding
but one of the servers can be induced not to process it by obfuscating the header in some way
Front-end server processes the Content-Length
header and request body has 13 bytes long, up to the end of SMUGGLED
Back-end server processes the Transfer-Encoding
which is chunked and processes the first chunk which is stated to be zero length, and treated as terminating the request
So, the following bytes, SMUGGLED are left unprocessed and the back-end server will treat these as being the start of next request in the sequence
front-end - Transfer-Encoding
back-end - Content-Length
front-end server processes the Transfer-Encoding
header, and treat the message body as using chunked encoding. It processes the first chunk which is stated as 8 bytes long, up to the end of SMUGGLED and it processes the second chunk, which is stated to be zero length and treated as terminating the request. Then forwarded to the back-end server
back-end server processes the Content-Length
header and determines that the request body as 3 bytes long, up to the end of 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.
both front and back-end support Transfer-Encoding
but one of the servers can be induced not to process it by obfuscating the header
many ways to obfuscate the Transfer-Encoding
header
eg
Finding CL.TE vulnerabilities
if the application is vulnerable to the CL.TE variant of request smuggling, sending a request like the following will often cause a time delay:
front-end uses Content-Length
, it will forward only part of this request, omitting X
back-end uses Transfer-Encoding
, processes the first chunk, and waits for the next chunk to arrive and will cause an observable time delay
Findng TE.CL vulnerabilities
front-end uses Transfer-Encoding
, it will forward only part of this request, omitting the X
back-end uses Content-Length
, expect more content in the message body and will cause time delay
sending two requests to the application in quick succession:
attack request that is designed to interfere with the processing of the next request
normal request
if the response to the normal request contains the expected interference, the vulnerability is confirmed.
eg - normal request looks like:
This request normally receives an HTTP response with status code 200, containing some search results
attack request depends on variant of whether CL.TE vs TE.CL
Confirming CL.TE
if the attack is successful, the last two lines of the request are treated by the back-end server as belonging to the next request that is received and cause the subsequent normal request to look like this
the request contains an invalid URL, the server will response with status code 404
Confirming TE.CL
attack request like this:
if the attack is successful, everything from GET /404
onwards is treated by the back-end server as belonging to the next request that is received.
attack request and normal request should be sent to the server using different network connection. Sending both from the same connection won't prove that the vulnerability exists attack request and normal request should use the same URL and parameter names should send the normal request immediately after the attack request
suppose an application uses the front-end server to implement access control restrictions, only forwarding requests if the user is authorized to access the requested URL
back-end server honors every request without further checking
suppose current user is permitted to access /home
but not /admin
this can bypass by using the following smuggling attack
before sending to backend server, front-end server adds some additional request headers. eg.
terminate the TLS connection and add some headers describing the protocol and ciphers that were used
add an X-Forwarded-For
header containing the user's IP address
determine the user's ID based on their session token and add a header identifying the user
add some sensitive information that is of interest for other attacks
so, in some situations, if your smuggled requests are missing some headers that are normally added by the front-end server, the back-end server might not process the requests in normal way and result in smuggled requests failing to have the intended effects
to reveal how the front-end server is rewriting requests
Find a POST request that reflects the value of a request parameter into the application's response
shuffle the parameters so that the reflected parameter appears last in the message body
smuggle this request to the back-end server, followed directly by a normal request whose rewritten from you want to reveal
eg - an application that reflects the value of the email parameter
that results in
for this application, the following request smuggling attack can be used to reveal the rewriting that is performed by the front-end server
this requests will be written by the front-end server to include the additional headers, and then the back-end server will process the smuggled request and reflect this value back in the response to the second request
for Content-Length header in smuggled request, it should be set a bit bigger than the submitted request and gradually increase the value to retrieve more information
if it is known how the front-end server is rewriting requests, it can be applied the necessary rewrites to the smuggled requests, to ensure they are processed in the intended way by the back-end server
as part of TLS handshake, servers authenticate themselves with the client (browser) by providing a certificate that contains common name (CN) which should match their registered hostname
client can use this to verify that they're talking to a legitimate server belonging to the expected domain
CN is often a username which can be used in the back-end application logic as part of an access control mechanism
eg -
they are completely hidden from users
you're able to send the right combination of headers and values and can bypass access controls
if the application contains any kind of functionality that allows textual data to be stored and retrieved, HTTP request smuggling can be used to capture the contents of other users' requests which include session tokens, enabling session hijacking attacks, or other sensitive data submitted by the user
an application uses the following request to submit a blog post comment which will be stored and displayed on the blog:
to perform HTTP request smuggling to the data storage request to the back-end server
when another user's request is processed by the back-end server, it will be appended to the smuggled request, with the result that the user's request gets stored including victim user's session cookie and any other sensitive data
default behavior of Apache and IIS web servers, where a request for a folder without a trailing slash receives a redirect to the same folder including the trailing slash
with request smuggling attack to redirect other users to an external domain
eg
the smuggled request will trigger a redirect to the attacker's website, which will affect the next user's request that is processed by the back-end server
Turning root-relative redirects into open directs
some servers redirect that use the path to construct a root-relative URL for the Location header
to exploit
Leave for later
Request smuggling is fundamentally about exploiting discrepancies between how different servers interpret the length of a request
HTTP/2 messages are sent over the wire as a series of separate "frames"
each frame is preceded by an explicit length field which tells the server exactly how many bytes to read in and the length of the request is the sum of its frame lengths
vulnerabilities occur due to HTTP/2 downgrading
front-end servers rewrite each incoming HTTP/2 request using HTTP/1 syntax and downgraded request is forwarded to the back-end server and vice versa
front-end use HTTP/2 length to determine where the request ends but the HTTP/1 back-end has to refer to the Content-Length header derived from the injected one, resulting in a desync
HTTP/2 requests don't have to specify their length explicitly in a header
during downgrading, front-end servers often add an HTTP/1 Content-Length
header, deriving its value using HTTP/2 build-in length mechanism and some front-end servers will reuse this value in the resulting HTTP/1 request
any Content-Length
header in a HTTP/2 request must match the length calculated using the built-in mechanism but this isn't always validated properly before downgrading; it may be possible to smuggle requests by injecting a misleading Content-Length header
eg
Front-end (HTTP/2)
Back-end(HTTP/1)