Projects
Eulaceura:Mainline
rubygem-puma
_service:obs_scm:CVE-2024-21647.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2024-21647.patch of Package rubygem-puma
Ubuntu note: simplified test case as to not hit this upstream bug: https://github.com/puma/puma/issues/3307 From bbb880ffb6debbfdea535b4b3eb2204d49ae151d Mon Sep 17 00:00:00 2001 From: Nate Berkopec <nate.berkopec@gmail.com> Date: Mon, 8 Jan 2024 14:48:43 +0900 Subject: [PATCH] Merge pull request from GHSA-c2f4-cvqm-65w2 Origin: https://github.com/puma/puma/commit/bbb880ffb6debbfdea535b4b3eb2204d49ae151d Co-authored-by: MSP-Greg <MSP-Greg@users.noreply.github.com> Co-authored-by: Patrik Ragnarsson <patrik@starkast.net> Co-authored-by: Evan Phoenix <evan@phx.io> --- lib/puma/client.rb | 27 +++++++++++++++++++++++++++ test/test_puma_server.rb | 14 ++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/puma/client.rb b/lib/puma/client.rb index 9c11912caa..b5a1569c68 100644 --- a/lib/puma/client.rb +++ b/lib/puma/client.rb @@ -48,6 +48,14 @@ class Client CHUNK_VALID_ENDING = Const::LINE_END CHUNK_VALID_ENDING_SIZE = CHUNK_VALID_ENDING.bytesize + # The maximum number of bytes we'll buffer looking for a valid + # chunk header. + MAX_CHUNK_HEADER_SIZE = 4096 + + # The maximum amount of excess data the client sends + # using chunk size extensions before we abort the connection. + MAX_CHUNK_EXCESS = 16 * 1024 + # Content-Length header value validation CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze @@ -460,6 +468,7 @@ def setup_chunked_body(body) @chunked_body = true @partial_part_left = 0 @prev_chunk = "" + @excess_cr = 0 @body = Tempfile.new(Const::PUMA_TMP_BASE) @body.unlink @@ -541,6 +550,20 @@ def decode_chunk(chunk) end end + # Track the excess as a function of the size of the + # header vs the size of the actual data. Excess can + # go negative (and is expected to) when the body is + # significant. + # The additional of chunk_hex.size and 2 compensates + # for a client sending 1 byte in a chunked body over + # a long period of time, making sure that that client + # isn't accidentally eventually punished. + @excess_cr += (line.size - len - chunk_hex.size - 2) + + if @excess_cr >= MAX_CHUNK_EXCESS + raise HttpParserError, "Maximum chunk excess detected" + end + len += 2 part = io.read(len) @@ -568,6 +591,10 @@ def decode_chunk(chunk) @partial_part_left = len - part.size end else + if @prev_chunk.size + chunk.size >= MAX_CHUNK_HEADER_SIZE + raise HttpParserError, "maximum size of chunk header exceeded" + end + @prev_chunk = line return false end diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb index 2bfaf98848..05bf83e20d 100644 --- a/test/test_puma_server.rb +++ b/test/test_puma_server.rb @@ -648,6 +648,20 @@ def test_large_chunked_request end end + def test_large_chunked_request_header + server_run(environment: :production) { |env| + [200, {}, [""]] + } + + max_chunk_header_size = Puma::Client::MAX_CHUNK_HEADER_SIZE + header = "GET / HTTP/1.1\r\nConnection: close\r\nContent-Length: 200\r\nTransfer-Encoding: chunked\r\n\r\n" + socket = send_http "#{header}1;t#{'x' * (max_chunk_header_size + 2)}" + + data = socket.read + + assert_match "HTTP/1.1 400 Bad Request\r\n\r\n", data + end + def test_chunked_request_pause_before_value body = nil content_length = nil -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2