Fuzzing HTTP Proxies: Squid, Part 2
Security is important to us, here at Opera. That’s why, apart from making our browsers safer, we also want to make the Web a bit safer. One of those ways is helping other developers find and fix vulnerabilities in their products.
Note: the vulnerabilities described below aren’t connected to any of the Opera products, but they’re quite the read for security buffs.
In my last blog post, Fuzzing HTTP Proxies: Privoxy, Part 1, I outlined how we’re working to secure open-source HTTP proxies. By auditing the security of open-source proxies used for privacy and security, we want to create a safer world-wide-web.
While that blog post focused on how we found six previously undiscovered vulnerabilities in Privoxy, this post is going to be mostly concerned about what we found, in The Squid Caching Proxy. We’re saving the technical blog of how we found these bugs, for the very end!
We’re disclosing 5 of the vulnerabilities we found during our audit of The Squid Caching Proxy. As of writing this, these bugs have been fixed already for four months.
|CVE-2021-28662||Vary: Other Response Header Assertion|
|CVE-2021-31806||Range Request Header Assertion|
|CVE-2021-31807||Range Request Header Use-After-Free|
|CVE-2021-31808||Range Request Header Int Overflow|
|CVE-2021-33620||Content-Range Response Header Crash|
If you’re hunting for bugs during a bug bounty for example, and come across a Squid server, these vulnerabilities should be tested for, as they can be used to crash Squid with a single request and/or response, and are incredibly simple to perform.
Three of the vulnerabilities are related to incorrect handling of the “Range” request header. One is related to the “Content-Range” response header, and one is related to the “Vary” response header.
In all five cases, the outcome is the same: Squid will completely crash (we do not believe CVE-2021-31807 can be used to achieve code execution).
If Squid receives an HTTP response with the following header, it will crash:
The “Vary” header is used to determine which headers should be matched against future requests, for purposes of caching. “Vary: Other:”, means to check the “Other” header, when caching (or not). The “Other” header has a special meaning in Squid, and when it is parsed as a header normally, it is rejected. However, by including it in the “Vary” header, this rejection is skipped, and Squid will assert when it is processed. Note: the trailing colon in the header is required.
If Squid receives the following HTTP request, it will crash with an assertion:
The middle value of the Range header (-0) is unsatisfiable: there is no way to satisfy a range from between zero (0-0) and negative one (-1). Squid does not handle this case effectively, and crashes.
If Squid receives the following HTTP request, it will cause a use-after-free, then a crash. It is not believed the use-after-free can be used for remote code execution (happy to be wrong!):
For similar reasons in CVE-2021-31806, the unsatisfiable negative bytes request between bytes zero and zero, makes Squid crash.
When Squid receives the following request and response combination, Squid will crash:
An integer overflow in the handling of the Range request header, and then the response Content-Length header, causes an assertion.
When squid receives the following HTTP response, it will crash:
* character has a special meaning within the context of the “Content-Range” header. When a response is a 206 Partial Content response, and contains the Content-Range
*, Squid mishandles a variable, causing the crash.