rack 2.2.13 → 2.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09a6d038df42d0af44940110fca3a8f9eb37a56a2acea9f1ad02f6fc39c685a9'
4
- data.tar.gz: d4a25103cf82081f357f621ee9a44027a799cda9c566f1ad4ffff3ec9d45a603
3
+ metadata.gz: cfe795272720eaaf8af60d73a6f48b8f67363e5fc302f55e58db739c3c934b1a
4
+ data.tar.gz: 6bb1f296c683cb5fb4628aed7cca3b34613d3a72f86cf2821e0d5ef358def5d9
5
5
  SHA512:
6
- metadata.gz: 6324e627506aa9605cab9ad4778303ccb24dffa41d2877e5a9008813556f84cc4660f2638fa00431b36a23cac528c81fa23884d21e907f56370634a67f94070c
7
- data.tar.gz: bc7cabae2f718457165de32fa8905028d0cbb85bcfe150ac2a7871e78ad57b3651d1881aedfc9a366fb9aa11ca009a1344e180ad2c470f1792b4e2befb629034
6
+ metadata.gz: 40d36f5e876e382aaf49daa1f56506577a4e24a3227be7a3645c599850b7de06e4a4292fafcdc9cd4cb3da207e7fb635f0382cad5ae4d0a25a7a4fc5aaa7551f
7
+ data.tar.gz: 6a348030a182d2d380ba66bdb99d0f9738b6bd25388ca206b4bec1c50fcd195a1d425388c75509628d8fa345a6ccd509741141841bf66722337504685f4c4c7b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
+ ## [2.2.14] - 2025-05-06
6
+
7
+ ### Security
8
+
9
+ - [CVE-2025-32441](https://github.com/rack/rack/security/advisories/GHSA-vpfw-47h7-xj4g) Rack session can be restored after deletion.
10
+ - [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion.
11
+
5
12
  ## [2.2.13] - 2025-03-11
6
13
 
7
14
  ### Security
data/README.rdoc CHANGED
@@ -179,6 +179,33 @@ e.g:
179
179
 
180
180
  Rack::Utils.key_space_limit = 128
181
181
 
182
+ === `RACK_QUERY_PARSER_BYTESIZE_LIMIT`
183
+
184
+ This environment variable sets the default for the maximum query string bytesize
185
+ that `Rack::QueryParser` will attempt to parse. Attempts to use a query string
186
+ that exceeds this number of bytes will result in a
187
+ `Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is
188
+ provided, it must be an integer, or `Rack::QueryParser` will raise an exception.
189
+
190
+ The default limit can be overridden on a per-`Rack::QueryParser` basis using
191
+ the `bytesize_limit` keyword argument when creating the `Rack::QueryParser`.
192
+
193
+ === `RACK_QUERY_PARSER_PARAMS_LIMIT`
194
+
195
+ This environment variable sets the default for the maximum number of query
196
+ parameters that `Rack::QueryParser` will attempt to parse. Attempts to use a
197
+ query string with more than this many query parameters will result in a
198
+ `Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is
199
+ provided, it must be an integer, or `Rack::QueryParser` will raise an exception.
200
+
201
+ The default limit can be overridden on a per-`Rack::QueryParser` basis using
202
+ the `params_limit` keyword argument when creating the `Rack::QueryParser`.
203
+
204
+ This is implemented by counting the number of parameter separators in the
205
+ query string, before attempting parsing, so if the same parameter key is
206
+ used multiple times in the query, each counts as a separate parameter for
207
+ this check.
208
+
182
209
  === key_space_limit
183
210
 
184
211
  The default number of bytes to allow all parameters keys in a given parameter hash to take up.
@@ -16,20 +16,47 @@ module Rack
16
16
  # sequence.
17
17
  class InvalidParameterError < ArgumentError; end
18
18
 
19
- # ParamsTooDeepError is the error that is raised when params are recursively
20
- # nested over the specified limit.
21
- class ParamsTooDeepError < RangeError; end
19
+ # QueryLimitError is for errors raised when the query provided exceeds one
20
+ # of the query parser limits.
21
+ class QueryLimitError < RangeError
22
+ end
23
+
24
+ # ParamsTooDeepError is the old name for the error that is raised when params
25
+ # are recursively nested over the specified limit. Make it the same as
26
+ # as QueryLimitError, so that code that rescues ParamsTooDeepError error
27
+ # to handle bad query strings also now handles other limits.
28
+ ParamsTooDeepError = QueryLimitError
22
29
 
23
- def self.make_default(key_space_limit, param_depth_limit)
24
- new Params, key_space_limit, param_depth_limit
30
+ def self.make_default(key_space_limit, param_depth_limit, **options)
31
+ new(Params, key_space_limit, param_depth_limit, **options)
25
32
  end
26
33
 
27
34
  attr_reader :key_space_limit, :param_depth_limit
28
35
 
29
- def initialize(params_class, key_space_limit, param_depth_limit)
36
+ env_int = lambda do |key, val|
37
+ if str_val = ENV[key]
38
+ begin
39
+ val = Integer(str_val, 10)
40
+ rescue ArgumentError
41
+ raise ArgumentError, "non-integer value provided for environment variable #{key}"
42
+ end
43
+ end
44
+
45
+ val
46
+ end
47
+
48
+ BYTESIZE_LIMIT = env_int.call("RACK_QUERY_PARSER_BYTESIZE_LIMIT", 4194304)
49
+ private_constant :BYTESIZE_LIMIT
50
+
51
+ PARAMS_LIMIT = env_int.call("RACK_QUERY_PARSER_PARAMS_LIMIT", 4096)
52
+ private_constant :PARAMS_LIMIT
53
+
54
+ def initialize(params_class, key_space_limit, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT)
30
55
  @params_class = params_class
31
56
  @key_space_limit = key_space_limit
32
57
  @param_depth_limit = param_depth_limit
58
+ @bytesize_limit = bytesize_limit
59
+ @params_limit = params_limit
33
60
  end
34
61
 
35
62
  # Stolen from Mongrel, with some small modifications:
@@ -42,7 +69,7 @@ module Rack
42
69
 
43
70
  params = make_params
44
71
 
45
- (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
72
+ check_query_string(qs, d).split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
46
73
  next if p.empty?
47
74
  k, v = p.split('=', 2).map!(&unescaper)
48
75
 
@@ -69,7 +96,7 @@ module Rack
69
96
  params = make_params
70
97
 
71
98
  unless qs.nil? || qs.empty?
72
- (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
99
+ check_query_string(qs, d).split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
73
100
  k, v = p.split('=', 2).map! { |s| unescape(s) }
74
101
 
75
102
  normalize_params(params, k, v, param_depth_limit)
@@ -155,8 +182,24 @@ module Rack
155
182
  true
156
183
  end
157
184
 
158
- def unescape(s)
159
- Utils.unescape(s)
185
+ def check_query_string(qs, sep)
186
+ if qs
187
+ if qs.bytesize > @bytesize_limit
188
+ raise QueryLimitError, "total query size (#{qs.bytesize}) exceeds limit (#{@bytesize_limit})"
189
+ end
190
+
191
+ if (param_count = qs.count(sep.is_a?(String) ? sep : '&')) >= @params_limit
192
+ raise QueryLimitError, "total number of query parameters (#{param_count+1}) exceeds limit (#{@params_limit})"
193
+ end
194
+
195
+ qs
196
+ else
197
+ ''
198
+ end
199
+ end
200
+
201
+ def unescape(string)
202
+ Utils.unescape(string)
160
203
  end
161
204
 
162
205
  class Params
@@ -55,6 +55,7 @@ module Rack
55
55
 
56
56
  def write_session(req, session_id, new_session, options)
57
57
  with_lock(req) do
58
+ return false unless get_session_with_fallback(session_id)
58
59
  @pool.store session_id.private_id, new_session
59
60
  session_id
60
61
  end
@@ -64,7 +65,11 @@ module Rack
64
65
  with_lock(req) do
65
66
  @pool.delete(session_id.public_id)
66
67
  @pool.delete(session_id.private_id)
67
- generate_sid unless options[:drop]
68
+ unless options[:drop]
69
+ sid = generate_sid
70
+ @pool.store(sid.private_id, {})
71
+ sid
72
+ end
68
73
  end
69
74
  end
70
75
 
data/lib/rack/version.rb CHANGED
@@ -20,7 +20,7 @@ module Rack
20
20
  VERSION.join(".")
21
21
  end
22
22
 
23
- RELEASE = "2.2.13"
23
+ RELEASE = "2.2.14"
24
24
 
25
25
  # Return the Rack release as a dotted string.
26
26
  def self.release
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.13
4
+ version: 2.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leah Neukirchen
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 2025-03-10 00:00:00.000000000 Z
11
+ date: 2025-05-06 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: minitest
@@ -168,6 +169,7 @@ metadata:
168
169
  changelog_uri: https://github.com/rack/rack/blob/master/CHANGELOG.md
169
170
  documentation_uri: https://rubydoc.info/github/rack/rack
170
171
  source_code_uri: https://github.com/rack/rack
172
+ post_install_message:
171
173
  rdoc_options: []
172
174
  require_paths:
173
175
  - lib
@@ -182,7 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
184
  - !ruby/object:Gem::Version
183
185
  version: '0'
184
186
  requirements: []
185
- rubygems_version: 3.6.2
187
+ rubygems_version: 3.5.22
188
+ signing_key:
186
189
  specification_version: 4
187
190
  summary: A modular Ruby webserver interface.
188
191
  test_files: []