puma 5.6.6 → 5.6.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +10 -0
- data/lib/puma/client.rb +42 -8
- data/lib/puma/const.rb +1 -1
- data/lib/puma/null_io.rb +0 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc34dc2b7094b86d3eec5100455de02cdcfb14a2e382059565e06e512d5c40ac
|
4
|
+
data.tar.gz: 10080424606d3a4613f1b27b33199a048711da57e4b45a55f7e997346c64c419
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18da16eff3311151ff29f868f07762d509541b1302dd6ff80bf323bb6fdd73da9d8bc32983a37b71e439faf4753e8110bdafb8f444df205b62f742376c980147
|
7
|
+
data.tar.gz: 89968813be0e066fc4de68dc439827d621d2d1803c58c64ee2df78f4d9baa4785fc7865d655990564ff52d9cd64ebc8d9dbc4be048334e0f8db954d83efaeef1
|
data/History.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 5.6.8 / 2023-01-08
|
2
|
+
|
3
|
+
* Security
|
4
|
+
* Limit the size of chunk extensions. Without this limit, an attacker could cause unbounded resource (CPU, network bandwidth) consumption. ([GHSA-c2f4-cvqm-65w2](https://github.com/puma/puma/security/advisories/GHSA-c2f4-cvqm-65w2))
|
5
|
+
|
6
|
+
## 5.6.7 / 2023-08-18
|
7
|
+
|
8
|
+
* Security
|
9
|
+
* Address HTTP request smuggling vulnerabilities with zero-length Content Length header and trailer fields ([GHSA-68xg-gqqm-vgj8](https://github.com/puma/puma/security/advisories/GHSA-68xg-gqqm-vgj8))
|
10
|
+
|
1
11
|
## 5.6.6 / 2023-06-21
|
2
12
|
|
3
13
|
* Bugfix
|
data/lib/puma/client.rb
CHANGED
@@ -45,7 +45,16 @@ module Puma
|
|
45
45
|
|
46
46
|
# chunked body validation
|
47
47
|
CHUNK_SIZE_INVALID = /[^\h]/.freeze
|
48
|
-
CHUNK_VALID_ENDING =
|
48
|
+
CHUNK_VALID_ENDING = Const::LINE_END
|
49
|
+
CHUNK_VALID_ENDING_SIZE = CHUNK_VALID_ENDING.bytesize
|
50
|
+
|
51
|
+
# The maximum number of bytes we'll buffer looking for a valid
|
52
|
+
# chunk header.
|
53
|
+
MAX_CHUNK_HEADER_SIZE = 4096
|
54
|
+
|
55
|
+
# The maximum amount of excess data the client sends
|
56
|
+
# using chunk size extensions before we abort the connection.
|
57
|
+
MAX_CHUNK_EXCESS = 16 * 1024
|
49
58
|
|
50
59
|
# Content-Length header value validation
|
51
60
|
CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze
|
@@ -347,8 +356,8 @@ module Puma
|
|
347
356
|
cl = @env[CONTENT_LENGTH]
|
348
357
|
|
349
358
|
if cl
|
350
|
-
# cannot contain characters that are not \d
|
351
|
-
if cl =~ CONTENT_LENGTH_VALUE_INVALID
|
359
|
+
# cannot contain characters that are not \d, or be empty
|
360
|
+
if cl =~ CONTENT_LENGTH_VALUE_INVALID || cl.empty?
|
352
361
|
raise HttpParserError, "Invalid Content-Length: #{cl.inspect}"
|
353
362
|
end
|
354
363
|
else
|
@@ -459,6 +468,7 @@ module Puma
|
|
459
468
|
@chunked_body = true
|
460
469
|
@partial_part_left = 0
|
461
470
|
@prev_chunk = ""
|
471
|
+
@excess_cr = 0
|
462
472
|
|
463
473
|
@body = Tempfile.new(Const::PUMA_TMP_BASE)
|
464
474
|
@body.unlink
|
@@ -509,7 +519,7 @@ module Puma
|
|
509
519
|
|
510
520
|
while !io.eof?
|
511
521
|
line = io.gets
|
512
|
-
if line.end_with?(
|
522
|
+
if line.end_with?(CHUNK_VALID_ENDING)
|
513
523
|
# Puma doesn't process chunk extensions, but should parse if they're
|
514
524
|
# present, which is the reason for the semicolon regex
|
515
525
|
chunk_hex = line.strip[/\A[^;]+/]
|
@@ -521,19 +531,39 @@ module Puma
|
|
521
531
|
@in_last_chunk = true
|
522
532
|
@body.rewind
|
523
533
|
rest = io.read
|
524
|
-
|
525
|
-
if rest.bytesize < last_crlf_size
|
534
|
+
if rest.bytesize < CHUNK_VALID_ENDING_SIZE
|
526
535
|
@buffer = nil
|
527
|
-
@partial_part_left =
|
536
|
+
@partial_part_left = CHUNK_VALID_ENDING_SIZE - rest.bytesize
|
528
537
|
return false
|
529
538
|
else
|
530
|
-
|
539
|
+
# if the next character is a CRLF, set buffer to everything after that CRLF
|
540
|
+
start_of_rest = if rest.start_with?(CHUNK_VALID_ENDING)
|
541
|
+
CHUNK_VALID_ENDING_SIZE
|
542
|
+
else # we have started a trailer section, which we do not support. skip it!
|
543
|
+
rest.index(CHUNK_VALID_ENDING*2) + CHUNK_VALID_ENDING_SIZE*2
|
544
|
+
end
|
545
|
+
|
546
|
+
@buffer = rest[start_of_rest..-1]
|
531
547
|
@buffer = nil if @buffer.empty?
|
532
548
|
set_ready
|
533
549
|
return true
|
534
550
|
end
|
535
551
|
end
|
536
552
|
|
553
|
+
# Track the excess as a function of the size of the
|
554
|
+
# header vs the size of the actual data. Excess can
|
555
|
+
# go negative (and is expected to) when the body is
|
556
|
+
# significant.
|
557
|
+
# The additional of chunk_hex.size and 2 compensates
|
558
|
+
# for a client sending 1 byte in a chunked body over
|
559
|
+
# a long period of time, making sure that that client
|
560
|
+
# isn't accidentally eventually punished.
|
561
|
+
@excess_cr += (line.size - len - chunk_hex.size - 2)
|
562
|
+
|
563
|
+
if @excess_cr >= MAX_CHUNK_EXCESS
|
564
|
+
raise HttpParserError, "Maximum chunk excess detected"
|
565
|
+
end
|
566
|
+
|
537
567
|
len += 2
|
538
568
|
|
539
569
|
part = io.read(len)
|
@@ -561,6 +591,10 @@ module Puma
|
|
561
591
|
@partial_part_left = len - part.size
|
562
592
|
end
|
563
593
|
else
|
594
|
+
if @prev_chunk.size + chunk.size >= MAX_CHUNK_HEADER_SIZE
|
595
|
+
raise HttpParserError, "maximum size of chunk header exceeded"
|
596
|
+
end
|
597
|
+
|
564
598
|
@prev_chunk = line
|
565
599
|
return false
|
566
600
|
end
|
data/lib/puma/const.rb
CHANGED
@@ -100,7 +100,7 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "5.6.
|
103
|
+
PUMA_VERSION = VERSION = "5.6.8".freeze
|
104
104
|
CODE_NAME = "Birdie's Version".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
data/lib/puma/null_io.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.6.
|
4
|
+
version: 5.6.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
144
|
+
rubygems_version: 3.5.3
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|