dalli 3.2.8 → 3.2.9
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 +11 -0
- data/lib/dalli/client.rb +14 -0
- data/lib/dalli/protocol/meta/request_formatter.rb +18 -6
- data/lib/dalli/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2fe56d2ea432b05cde81f7b4c5e3017fc8e11788526cd3dbecbaede2e11c1659
|
|
4
|
+
data.tar.gz: 450380fe328c475a93b32d4b1cca10fef1d33065d13bed32e1126276621c2e54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ccdbfa346efdf6a09ab53fbd4e44179b298028e348716780b5356d909270fce2fa5fdf66f00579703ab9e0a15dde4b699faf483b5fadb016cff434b85b99011a
|
|
7
|
+
data.tar.gz: 3c312e4303bf6b076b20fa28a73277b3975396af12cbee42e3c1cceaab9fde3cb679422f3301a0c3c06a784f3706c704d1e181207bb107b245db2683d7f0c690
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ Dalli Changelog
|
|
|
4
4
|
Unreleased
|
|
5
5
|
==========
|
|
6
6
|
|
|
7
|
+
3.2.9
|
|
8
|
+
==========
|
|
9
|
+
|
|
10
|
+
Security:
|
|
11
|
+
|
|
12
|
+
- Fix memcached command injection through the `incr`/`decr` default with the meta protocol (GHSA-6wmv-xq9m-fmp7)
|
|
13
|
+
- With `protocol: :meta`, the `default` argument of `incr`/`decr` was written into the command without conversion, so a String containing CRLF injected additional memcached commands (e.g. `set`, `flush_all`) on the connection. The default binary protocol is not affected
|
|
14
|
+
- `default` must now be an Integer, or a String of decimal digits; anything else raises `ArgumentError` before a request is sent
|
|
15
|
+
- As defense in depth, the meta `RequestFormatter` now converts every numeric flag it writes (`D`, `J`, `N`, `T`) to an Integer
|
|
16
|
+
- Thanks to oss-security-shop for the report
|
|
17
|
+
|
|
7
18
|
3.2.8
|
|
8
19
|
==========
|
|
9
20
|
|
data/lib/dalli/client.rb
CHANGED
|
@@ -257,6 +257,8 @@ module Dalli
|
|
|
257
257
|
##
|
|
258
258
|
# Incr adds the given amount to the counter on the memcached server.
|
|
259
259
|
# Amt must be a positive integer value.
|
|
260
|
+
# Default, if given, must be an Integer (or a String of decimal digits);
|
|
261
|
+
# anything else raises ArgumentError.
|
|
260
262
|
#
|
|
261
263
|
# If default is nil, the counter must already exist or the operation
|
|
262
264
|
# will fail and will return nil. Otherwise this method will return
|
|
@@ -269,6 +271,7 @@ module Dalli
|
|
|
269
271
|
# If the value already exists, it must have been set with raw: true
|
|
270
272
|
def incr(key, amt = 1, ttl = nil, default = nil)
|
|
271
273
|
check_positive!(amt)
|
|
274
|
+
validate_integer!(:default, default)
|
|
272
275
|
|
|
273
276
|
perform(:incr, key, amt.to_i, ttl_or_default(ttl), default)
|
|
274
277
|
end
|
|
@@ -276,6 +279,8 @@ module Dalli
|
|
|
276
279
|
##
|
|
277
280
|
# Decr subtracts the given amount from the counter on the memcached server.
|
|
278
281
|
# Amt must be a positive integer value.
|
|
282
|
+
# Default, if given, must be an Integer (or a String of decimal digits);
|
|
283
|
+
# anything else raises ArgumentError.
|
|
279
284
|
#
|
|
280
285
|
# memcached counters are unsigned and cannot hold negative values. Calling
|
|
281
286
|
# decr on a counter which is 0 will just return 0.
|
|
@@ -291,6 +296,7 @@ module Dalli
|
|
|
291
296
|
# If the value already exists, it must have been set with raw: true
|
|
292
297
|
def decr(key, amt = 1, ttl = nil, default = nil)
|
|
293
298
|
check_positive!(amt)
|
|
299
|
+
validate_integer!(:default, default)
|
|
294
300
|
|
|
295
301
|
perform(:decr, key, amt.to_i, ttl_or_default(ttl), default)
|
|
296
302
|
end
|
|
@@ -373,6 +379,14 @@ module Dalli
|
|
|
373
379
|
raise ArgumentError, "Positive values only: #{amt}" if amt.negative?
|
|
374
380
|
end
|
|
375
381
|
|
|
382
|
+
# Numeric arguments that become meta protocol flags (GHSA-6wmv-xq9m-fmp7).
|
|
383
|
+
# Checked before the request starts so a bad value raises a clean
|
|
384
|
+
# ArgumentError, instead of Protocol::Base#request logging it as
|
|
385
|
+
# unexpected and closing the connection.
|
|
386
|
+
def validate_integer!(name, value)
|
|
387
|
+
Dalli::Protocol::Meta::RequestFormatter.integer_flag(name, value) unless value.nil?
|
|
388
|
+
end
|
|
389
|
+
|
|
376
390
|
def cas_core(key, always_set, ttl = nil, req_options = nil)
|
|
377
391
|
(value, cas) = perform(:cas, key)
|
|
378
392
|
return if value.nil? && !always_set
|
|
@@ -21,7 +21,7 @@ module Dalli
|
|
|
21
21
|
cmd << ' v f' if value
|
|
22
22
|
cmd << ' c' if return_cas
|
|
23
23
|
cmd << ' b' if base64
|
|
24
|
-
cmd << " T#{ttl}" if ttl
|
|
24
|
+
cmd << " T#{integer_flag(:ttl, ttl)}" if ttl
|
|
25
25
|
cmd << ' k q s' if quiet # Return the key in the response if quiet
|
|
26
26
|
cmd + TERMINATOR
|
|
27
27
|
end
|
|
@@ -32,7 +32,7 @@ module Dalli
|
|
|
32
32
|
cmd << ' b' if base64
|
|
33
33
|
cmd << " F#{bitflags}" if bitflags
|
|
34
34
|
cmd << cas_string(cas)
|
|
35
|
-
cmd << " T#{ttl}" if ttl
|
|
35
|
+
cmd << " T#{integer_flag(:ttl, ttl)}" if ttl
|
|
36
36
|
cmd << " M#{mode_to_token(mode)}"
|
|
37
37
|
cmd << ' q' if quiet
|
|
38
38
|
cmd << TERMINATOR
|
|
@@ -44,7 +44,7 @@ module Dalli
|
|
|
44
44
|
cmd = "md #{key}"
|
|
45
45
|
cmd << ' b' if base64
|
|
46
46
|
cmd << cas_string(cas)
|
|
47
|
-
cmd << " T#{ttl}" if ttl
|
|
47
|
+
cmd << " T#{integer_flag(:ttl, ttl)}" if ttl
|
|
48
48
|
cmd << ' q' if quiet
|
|
49
49
|
cmd + TERMINATOR
|
|
50
50
|
end
|
|
@@ -52,10 +52,10 @@ module Dalli
|
|
|
52
52
|
def self.meta_arithmetic(key:, delta:, initial:, incr: true, cas: nil, ttl: nil, base64: false, quiet: false)
|
|
53
53
|
cmd = "ma #{key} v"
|
|
54
54
|
cmd << ' b' if base64
|
|
55
|
-
cmd << " D#{delta}" if delta
|
|
56
|
-
cmd << " J#{initial}" if initial
|
|
55
|
+
cmd << " D#{integer_flag(:delta, delta)}" if delta
|
|
56
|
+
cmd << " J#{integer_flag(:initial, initial)}" if initial
|
|
57
57
|
# Always set a TTL if an initial value is specified
|
|
58
|
-
cmd << " N#{ttl
|
|
58
|
+
cmd << " N#{ttl ? integer_flag(:ttl, ttl) : 0}" if ttl || initial
|
|
59
59
|
cmd << cas_string(cas)
|
|
60
60
|
cmd << ' q' if quiet
|
|
61
61
|
cmd << " M#{incr ? 'I' : 'D'}"
|
|
@@ -104,6 +104,18 @@ module Dalli
|
|
|
104
104
|
end
|
|
105
105
|
# rubocop:enable Metrics/MethodLength
|
|
106
106
|
|
|
107
|
+
# Numeric flag values are written straight into the command line, so a
|
|
108
|
+
# value that isn't an integer -- e.g. a String carrying CRLF -- would let
|
|
109
|
+
# the caller inject further memcached commands (GHSA-6wmv-xq9m-fmp7).
|
|
110
|
+
# Converting to Integer means only digits ever reach the wire. Strings
|
|
111
|
+
# are parsed as base 10 so "010" means 10, as memcached would read it,
|
|
112
|
+
# rather than octal 8.
|
|
113
|
+
def self.integer_flag(name, value)
|
|
114
|
+
value.is_a?(String) ? Integer(value, 10) : Integer(value)
|
|
115
|
+
rescue ArgumentError, TypeError, FloatDomainError
|
|
116
|
+
raise ArgumentError, "#{name} must be an Integer, got #{value.inspect}"
|
|
117
|
+
end
|
|
118
|
+
|
|
107
119
|
def self.cas_string(cas)
|
|
108
120
|
cas = parse_to_64_bit_int(cas, nil)
|
|
109
121
|
cas.nil? || cas.zero? ? '' : " C#{cas}"
|
data/lib/dalli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dalli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.2.
|
|
4
|
+
version: 3.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter M. Goldstein
|
|
8
8
|
- Mike Perham
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies: []
|
|
14
13
|
description: High performance memcached client for Ruby
|
|
15
14
|
email:
|
|
@@ -62,7 +61,6 @@ metadata:
|
|
|
62
61
|
bug_tracker_uri: https://github.com/petergoldstein/dalli/issues
|
|
63
62
|
changelog_uri: https://github.com/petergoldstein/dalli/blob/main/CHANGELOG.md
|
|
64
63
|
rubygems_mfa_required: 'true'
|
|
65
|
-
post_install_message:
|
|
66
64
|
rdoc_options: []
|
|
67
65
|
require_paths:
|
|
68
66
|
- lib
|
|
@@ -77,8 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
75
|
- !ruby/object:Gem::Version
|
|
78
76
|
version: '0'
|
|
79
77
|
requirements: []
|
|
80
|
-
rubygems_version:
|
|
81
|
-
signing_key:
|
|
78
|
+
rubygems_version: 4.0.21
|
|
82
79
|
specification_version: 4
|
|
83
80
|
summary: High performance memcached client for Ruby
|
|
84
81
|
test_files: []
|