postrank-labs / goliath

Goliath is a non-blocking Ruby web server framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HTTP Request Smuggling Hardening

snoopysecurity opened this issue · comments

Posting it here for community patches after talking with the maintainers privately.

Issue: Goliath doesn't prevent Request Smuggling attacks

  1. Goliath allows requests with multiple content-lengths.

When sent a request such as the below, the first content-length header is ignored and the second content-length header is prioritized. Since the second content-length was set to zero, the backend will expect no request body and the /smuggledreq request is treated as another pipelined request.

GET / HTTP/1.1
Content-Length: 46
Content-Length: 0
Host: 127.0.0.1

GET /smuggledreq HTTP/1.1
Host: 127.0.0.1


HTTP/1.1 200 OK
Content-Length: 11
Server: Goliath
Date: Tue, 02 Jun 2020 19:45:59 GMT

hello worldHTTP/1.1 200 OK
Content-Length: 11
Server: Goliath
Date: Tue, 02 Jun 2020 19:45:59 GMT

hello world
  1. Goliath allows multiple malformed variations of the Transfer Encoding header. Depending on how Goliath will be used as part of a chain of servers, this could result in a successful request smuggling attack.
POST / HTTP/1.1
Host: 127.0.0.1:9000
Content-Type: application/x-www-form-urlencoded
Content-Length: 8
tRANSFER-ENCODING: chunked

0

X

Other examples:

Transfer-Encoding:  chunked
Transfer-Encoding:chunked
Transfer-Encoding: ch–nked
tRANSFER-ENCODING: chunked

How to fix:

Prioritize Transfer-Encoding over Content-Length
Remediation: This remediation will prevent CL:TE and TE:CL attacks
Details: When a request with both a Transfer-Encoding: chunked header and Content-length is received, the transfer-encoding header should be prioritized over Content-Length. This is referenced in RFC 7230 Section 3.3.3#3.

Disallow requests with Double Content-Length
Remediation: This remediation will prevent CL:CL attacks
Details: As mentioned in RFC 7230 Section 3.3.3#4, if a HTTP request is received with multiple content-length headers with different length values, this should be responded with a HTTP 400 response.

Disallow malformed Transfer encoding headers
Remediation: This remediation will prevent TE:TE attacks.
Details: If both a frontend and backend prioritizes the Transfer-Encoding header, it could allow smuggling attacks where an attacker inserts two Transfer-Encoding headers, one which would be ignored by the frontend and is processed by the backend and vice versa. As such, the following type of header variations should be rejected. More examples of header variations can be seen here:https://portswigger.net/web-security/request-smuggling

Disallow requests with both Content-length and Transfer encoding
Remediation: This remediation will prevent CL:TE and TE:CL attacks
Details: This can be seen as a better alternative to “Prioritize Transfer-Encoding over Content-Length” solution. Runtime platforms such as Node.js have used this solution to remediate against request smuggling where any requests with both headers are returned with a HTTP 400 response.