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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.rdoc +27 -0
- data/lib/rack/query_parser.rb +53 -10
- data/lib/rack/session/pool.rb +6 -1
- data/lib/rack/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfe795272720eaaf8af60d73a6f48b8f67363e5fc302f55e58db739c3c934b1a
|
4
|
+
data.tar.gz: 6bb1f296c683cb5fb4628aed7cca3b34613d3a72f86cf2821e0d5ef358def5d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/rack/query_parser.rb
CHANGED
@@ -16,20 +16,47 @@ module Rack
|
|
16
16
|
# sequence.
|
17
17
|
class InvalidParameterError < ArgumentError; end
|
18
18
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
class
|
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
|
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
|
-
|
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
|
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
|
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
|
159
|
-
|
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
|
data/lib/rack/session/pool.rb
CHANGED
@@ -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
|
-
|
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
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.
|
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-
|
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.
|
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: []
|