Application Security

Application Penetration Testing

Browser-Powered Request Smuggling: What is a Client-Side Desync Attack?

This article is designed to help you understand Client-Side Desync from an attacker’s perspective.

Attacker Perspective: Client-Side Desync

Client-side desyncs are a class of browser-powered HTTP smuggling attacks. HTTP smuggling can be succinctly described as a technique that enables a malicious actor to sneak an HTTP request into the body of another request. The act of sneaking a second request in the body of a primary request is the most significant similarity between Client-Side Desync and classic HTTP smuggling attacks. One of the primary differences between the two is that client-side desyncs are browser-powered. Security features in modern browsers restrict malicious actors from manipulating data belonging to the Content-Length and Transfer-Encoding headers. Traditional smuggling attacks require modification of these headers to be performed and, therefore, cannot be conducted by a victim’s browser. Both client-side and server-side Desyncs do not rely on the same mechanism and can execute in the browser. The browser-powered desync attack class was first discovered by the Portswigger Director of Research, James Kettel.

The attack class was popularized after his presentation at Defcon 30 titled “Browser-Powered Desync Attacks: A New Frontier in HTTP Request Smuggling.” An incredible article by the same title can be found on the Portswigger website. Client-side desync refers to a browser-powered desync where desynchronization occurs between the client and the front-end server. This differs from Server-side desyncs where the confusion occurs between the front and back-end servers.

Web Server Configuration

Client-side desyncs occur when web servers are configured (or misconfigured) to issue an immediate response to a POST or PUT request without first checking the content of the body. The server answers the first request immediately but prepares an additional response for the secondary, smuggled request that was hidden in the body of the original. An easy way to picture this is the classic two kids in a trench coat cliché. An unsuspecting bouncer looks at the height of the apparent “individual.” He assumes all is well and lets the “man” inside. What he doesn’t see is that there is a second person hidden beneath the coat. Once they are inside, they can approach the bar, and each can make an order and receive a drink. Similarly, client-side desync attacks work with the victim’s browser being the bouncer and the vulnerable server being an apparently apathetic bartender. An example desync would look something like this:

Application Security
Figure 1: Basic Client-Side Desync Example

Attack Path

Let’s break down the above image. In green, we see the primary request being sent. In red, we see the smuggled request, which is technically in the content body of the primary request. Lastly, in purple, is the next request. The browser would send this as an entirely separate request, while the server would interpret it exactly as shown above. With the lack of a carriage return(\r\n) at the end of the smuggled request, the server would simply append the next request to the end of the smuggled request. By placing an arbitrary header in the smuggled request, we can cause the server to ignore the first line of the next request. We can even use this technique to make use of cookies that would normally be inaccessible to us as attackers.

Tricking the Browser

So, what are we really doing here? We are tricking the victim’s browser into sending what it perceives as a single request but is read by the server as two requests. Why is this a security issue and not just a bug? What can be impacted? The answer to the first question is straightforward. Imagine a situation where a victim visits an attacker-controlled website. Normally the malicious actor can cause the victim’s browser to issue HTTP requests but is limited in the scope of what can be modified. The client-side desync allows the attacker to control certain content that is typically off-limits due to browser security. We can modify fields that were previously untouchable, such as the host header, origin, cookies, and other fields. Many potential security findings that are typically considered “unexploitable” suddenly become feasible. Host header redirects and XSS via cookies become very real and dangerous vulnerabilities when delivered via a desync. Several client-side desync CVEs utilize an attack chain that uses a host header or other open redirect vulnerabilities to perform web cache poisoning. 

Examples of this form of web cache poisoning via redirects include 

  • CVE-2022-20713 
  • CVE-2022-29361

which exploit Cisco ASA Web VPNs and Werkzeug v2.1.0, respectively.

How to identify client-side desync vulnerabilities

The methodology used to identify Client-side desync vulnerabilities is simple. Identify endpoints on the target web server that issue responses without considering the content length. This is most often static files or redirects. Common static files include robots.txt, JavaScript files, and CSS files. Redirects can often be found by removing the ending / from known endpoints. For example, if a site has the endpoint “target-site.com/login/,” try sending a request to “target-site.com/login.” There is a good chance you may receive a 301 redirect message. 

Using a web application proxy tool like Burp Suite, try sending an overlong content length to the target endpoint. If the response is immediate, the likelihood of CLIENT-SIDE DESYNC is high.

If the response hangs, never comes, or returns 400 bad request, then this file/redirect is not a viable target, as shown in Figure 2 below.

Penetration Testing for Applications
Figure 2: Overlong Content-length

In the event the target server issues an immediate response to your overlong content-length, the next step is to send a request with a smuggled request in the body, followed by another request on the same connection. A few steps are necessary to perform this test. First, alter the primary request by changing the connection header to keep-alive as seen in Figure 3 below.

Web Application Vulnerability
Figure 3: Modify the Connection Header to ‘keep-alive’

This will instruct the server to continue listening for additional requests on the same connection. Next, you must write a smuggled request into the body of the first. This can be a barebones request with only the method, path, HTTP version (ensure the version is not HTTP2), and an arbitrary header. Ensure you choose a path that you would recognize the response of. After writing the smuggled request, create a new request to another path you are familiar with. Add the two separate requests to a group and select “Send Sequence over Single Connection.”

Offensive Security
Figure 4: Send Group Over Single Connection

Click send and observe the responses. You should see the response to the primary request, then after clicking on the second request, you should see it received the response you would expect for the smuggled request.

Is your site vulnerable
Figure 5: Responses

Confirm the Vulnerability

The last step to confirm vulnerability to client-side desync is to validate that the request can be sent by a browser. This can be performed using the fetch() method. Open a browser and navigate to a site on another domain than the target server. Open the developer tools and paste the following JavaScript inspired by James Kettil’s Browser Powered Desync Attacks:

  • This will send a POST request to the target site with the GET request in the body followed by a redirect to the site. Check the network tab and you will see two responses sharing the same connection ID. These will be responses to the primary and smuggled requests. If the CLIENT-SIDE DESYNC works in the browser, then it is undeniably a client-side desync vulnerability.

Demonstrating Impact

At this point you would have a client-side desync finding, but no penetration tester would feel accomplished without demonstrating impact. A client-side desync, while still warranting remediation, is not much of a finding without a way to weaponize it. If you have already discovered a typically difficult-to-exploit vulnerability, such as host header redirect or XSS via cookies, then this would be a prime opportunity to link them with the client-side desync. Furthermore, client-side desync essentially completes these types of attacks thereby raising their exploitability from nearly zero to very likely. Web cache poisoning is one of the best attacks to chain with client-side desync, though it requires some form of open redirect vulnerability. Another article demonstrating attacks using client-side desync as a sled will be uploaded to the Redbot Security feed at a future date.

Conclusion

After all this talk about finding and exploiting client-side desync vulnerabilities, it is only fair to provide basic remediation advice. Most known client-side desync vulnerabilities have been resolved by product creators. Simply patching web servers will resolve most cases of client-side desync. If a patch is unavailable due to using an end-of-life server or the patch simply hasn’t been released yet, an easy solution may still be available. Client-side desync attacks do not work against the HTTP2 protocol. HTTP2 does not use content length and is therefore immune to this attack. Configuring servers to use HTTP2 will prevent client-side desync attacks entirely. This is a quick and effective method to remove the possibility of being attacked via client-side desync.

Client-side desync is part of the new browser-powered desync attack class. This vulnerability is an excellent way to elevate the severity of previously “unexploitable” vulnerabilities. This attack technique desynchronizes the communication between a victim’s browser and a target server allowing circumvention of many modern browser security features. Becoming familiar with identifying client-side desync attack vectors will expand a penetration tester’s skillset and allow them to provide a more complete security assessment for their clients. Consider adding the client-side desync attack to your personal penetration testing toolkit. 

Citations

  • Kettle, James. “Browser-Powered Desync Attacks: A New Frontier in HTTP Request Smuggling.” PortSwigger Research, 10 Aug. 2022, portswigger.net/research/browser-powered-desync-attacks.
  • Mizu.re. “Abusing Client-Side Desync on Werkzeug. Tags:Article – Article – Web – XSS.” Mizu.re, 7 June 2023, mizu.re/post/abusing-client-side-desync-on-werkzeug#construct-the-exploit-chain. Accessed 29 Sept. 2023.

 

Contact Redbot Security

Related Articles