-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request Smuggling in WEBrick Due to Incorrect Parsing of Empty Content-Length
Values
#119
Comments
Note: this was originally submitted to Ruby's HackerOne program, but I was told to report this publicly here. |
Based on the suggested fix: diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb
index 680ac65..7937eb9 100644
--- a/lib/webrick/httprequest.rb
+++ b/lib/webrick/httprequest.rb
@@ -479,6 +479,14 @@ module WEBrick
end
end
@header = HTTPUtils::parse_header(@raw_header.join)
+
+ if (content_length = @header['content-length']) && content_length.length != 0
+ if content_length.length > 1
+ raise HTTPStatus::BadRequest, "multiple content-length request headers"
+ elsif !/\A\d+\z/.match?(content_length[0])
+ raise HTTPStatus::BadRequest, "invalid content-length request header"
+ end
+ end
end
def parse_uri(str, scheme="http") Haven't had time to come up with tests for this yet, but it does pass existing tests. |
jeremyevans
added a commit
to jeremyevans/webrick
that referenced
this issue
Aug 15, 2023
…ent-length headers Addresses CVE-2023-40225. Fixes ruby#119
jeremyevans
added a commit
to jeremyevans/webrick
that referenced
this issue
Aug 15, 2023
…ent-length headers Addresses CVE-2023-40225. Fixes ruby#119
jeremyevans
added a commit
that referenced
this issue
Aug 16, 2023
…ent-length headers Addresses CVE-2023-40225. Fixes #119
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Abstract
WEBrick is vulnerable to request smuggling when it is deployed behind a reverse proxy with the following two properties:
Content-Length
headers, of which the first is empty.Content-Length
header over the first.HAProxy exhibited both of these behaviors until a few days ago. See CVE-2023-40225 for details.
WEBrick is vulnerable for two reasons:
Content-Length
headers to have a value of0
, andContent-Length
header over the rest if a request contains multipleContent-Length
headers.I suggest that WEBrick start rejecting messages with empty or multiple different
Content-Length
values. This is what most other web servers do, including Nginx, Apache, Lighttpd, H2O, IIS, Node.js, and LiteSpeed.PoC Description
Suppose that we have WEBrick deployed behind a reverse proxy with the aforementioned properties (e.g. HAProxy 2.8.0) that has an ACL rule blocking access to the
/evil
directory on the WEBrick host.The following payload will bypass the ACL rule:
This works because HAProxy sees the payload as two
GET
requests for/
, but WEBrick sees the payload as aGET
request for/
and aPOST
request for/evil
.PoC Reproduction Steps
docker run --workdir /repro -it alpine:3.18.0
)ruby /repro/server.rb &
/evil
:haproxy -f /repro/haproxy.conf &
/evil
, indicating that the ACL has been bypassed:Files
/repro/server.rb
/repro/haproxy.conf
Suggested Fix
WEBrick should reject any message that contains an empty
Content-Length
header. WEBrick should also reject any message containing multipleContent-Length
headers, especially if those headers do not all have the same value. See here for the relevant portion of the standard.The text was updated successfully, but these errors were encountered: