safer_redis 1.1.0 → 1.2.0
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 +4 -0
- data/Gemfile.lock +12 -11
- data/README.md +8 -1
- data/lib/safer_redis/assessor.rb +30 -0
- data/lib/safer_redis/interceptor.rb +4 -1
- data/lib/safer_redis/suggestion.rb +4 -1
- data/lib/safer_redis/version.rb +1 -1
- data/lib/safer_redis.rb +0 -12
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 790845a432c5b85fa5261a8cbca3170058adcc00352f79ae3a1d211e5027b7dc
|
4
|
+
data.tar.gz: 9bacdc397e449211800e19ccd0fb6e99089215db5fbd52593d452ec8b73f44d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0fa1a49e44253388abaa4483ad9ceeae25b65386c1ed5ecff2820075905245d45684aabd0dfb475041739ec1b938ddcf125e3546d52b22d1380e30793b823f6
|
7
|
+
data.tar.gz: ee4c6847111eb19a6e2d836e557826a3cf9a4a14219dfcb9734e26b9728d9f8649960aa0071c2a2de68f83b421c339713e92291d52b796f8926e3e15cc118b54
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,38 +1,39 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
safer_redis (1.
|
4
|
+
safer_redis (1.1.0)
|
5
5
|
redis (>= 4.6.0)
|
6
6
|
zeitwerk
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
connection_pool (2.
|
11
|
+
connection_pool (2.4.1)
|
12
12
|
diff-lcs (1.5.0)
|
13
|
-
rake (13.0
|
14
|
-
redis (5.0.
|
15
|
-
redis-client (>= 0.
|
16
|
-
redis-client (0.
|
13
|
+
rake (13.1.0)
|
14
|
+
redis (5.0.8)
|
15
|
+
redis-client (>= 0.17.0)
|
16
|
+
redis-client (0.18.0)
|
17
17
|
connection_pool
|
18
18
|
rspec (3.12.0)
|
19
19
|
rspec-core (~> 3.12.0)
|
20
20
|
rspec-expectations (~> 3.12.0)
|
21
21
|
rspec-mocks (~> 3.12.0)
|
22
|
-
rspec-core (3.12.
|
22
|
+
rspec-core (3.12.2)
|
23
23
|
rspec-support (~> 3.12.0)
|
24
|
-
rspec-expectations (3.12.
|
24
|
+
rspec-expectations (3.12.3)
|
25
25
|
diff-lcs (>= 1.2.0, < 2.0)
|
26
26
|
rspec-support (~> 3.12.0)
|
27
|
-
rspec-mocks (3.12.
|
27
|
+
rspec-mocks (3.12.6)
|
28
28
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
29
|
rspec-support (~> 3.12.0)
|
30
|
-
rspec-support (3.12.
|
31
|
-
zeitwerk (2.6.
|
30
|
+
rspec-support (3.12.1)
|
31
|
+
zeitwerk (2.6.12)
|
32
32
|
|
33
33
|
PLATFORMS
|
34
34
|
x86_64-darwin-21
|
35
35
|
x86_64-darwin-22
|
36
|
+
x86_64-darwin-23
|
36
37
|
|
37
38
|
DEPENDENCIES
|
38
39
|
rake (~> 13.0)
|
data/README.md
CHANGED
@@ -4,9 +4,16 @@ SaferRedis wraps a Redis connection, and warns you before letting through comman
|
|
4
4
|
|
5
5
|
Inspiration is taken from https://github.com/ankane/strong_migrations which provides similar guard-rails for potentially dangerous database migrations.
|
6
6
|
|
7
|
+
## Special cases
|
8
|
+
|
9
|
+
Commands tagged as `@slow` but with only O(1) complexity are not considered dangerous. This includes
|
10
|
+
e.g. the extremely commonly used `SET` command.
|
11
|
+
|
12
|
+
The [`DEL`](https://redis.io/commands/del/) command (`@slow`) is treated as [`UNLINK`](https://redis.io/commands/unlink/) (`@fast`) when the `lazyfree-lazy-user-del` server option is set.
|
13
|
+
|
7
14
|
## Limitations
|
8
15
|
|
9
|
-
Currently SaferRedis works with the [`redis` gem](https://rubygems.org/gems/redis) from https://github.com/redis/redis-rb (regardless of which connection adapter is being used, e.g. [`hiredis`](https://rubygems.org/gems/hiredis)) by hooking into the private `#send_command` method which was introduced in v4.6.0. This isn't a stable API, so other interception strategies will be considered and may be added in future. Some Redis connectors/drivers
|
16
|
+
Currently SaferRedis works with the [`redis` gem](https://rubygems.org/gems/redis) from https://github.com/redis/redis-rb (regardless of which connection adapter is being used, e.g. [`hiredis`](https://rubygems.org/gems/hiredis)) by hooking into the private `#send_command` method which was introduced in v4.6.0. This isn't a stable API, so other interception strategies will be considered and may be added in future. Some Redis connectors/drivers support middleware, but others don't.
|
10
17
|
|
11
18
|
Some commands are documented at the subcommand level as multiple words (e.g. `CLIENT LIST`). SaferRedis currently only recognises commands documented at their top-level single word (e.g. `DEL`). Support for multi-word commands will be considered and may be added in future.
|
12
19
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module SaferRedis
|
6
|
+
class Assessor
|
7
|
+
def self.assess!(doc, redis:)
|
8
|
+
# DEL becomes UNLINK if lazyfree-lazy-user-del is set
|
9
|
+
# https://github.com/redis/redis/pull/6243
|
10
|
+
# https://redis.io/docs/management/config-file/
|
11
|
+
if doc.name == "DEL" && config_get("lazyfree-lazy-user-del", redis:) == "yes"
|
12
|
+
doc = SaferRedis::CommandDoc.new("UNLINK")
|
13
|
+
end
|
14
|
+
|
15
|
+
if doc.dangerous?
|
16
|
+
# Anything tagged @dangerous is… dangerous
|
17
|
+
raise SaferRedis::Danger.new(doc)
|
18
|
+
|
19
|
+
elsif doc.slow? && doc.complexity != "O(1)"
|
20
|
+
# Anything tagged @slow might be dangerous, but we'll let through O(1)
|
21
|
+
# complexity commands e.g. SET
|
22
|
+
raise SaferRedis::Danger.new(doc)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.config_get(option, redis:)
|
27
|
+
SaferRedis.really { redis.config(:get, option)[option] }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -4,7 +4,10 @@ module SaferRedis
|
|
4
4
|
module Interceptor
|
5
5
|
def send_command(command, &block)
|
6
6
|
if SaferRedis.active?
|
7
|
-
SaferRedis.assess!(
|
7
|
+
SaferRedis::Assessor.assess!(
|
8
|
+
SaferRedis::CommandDoc.from_command_array(command),
|
9
|
+
redis: self,
|
10
|
+
)
|
8
11
|
end
|
9
12
|
|
10
13
|
super
|
@@ -12,7 +12,10 @@ module SaferRedis
|
|
12
12
|
def self.for_command(command)
|
13
13
|
case command
|
14
14
|
when "DEL"
|
15
|
-
new(command,
|
15
|
+
new(command, <<~END)
|
16
|
+
Consider using the non-blocking UNLINK command instead to delete the key on a \
|
17
|
+
background thread, or set the lazyfree-lazy-user-del server option
|
18
|
+
END
|
16
19
|
else
|
17
20
|
nil
|
18
21
|
end
|
data/lib/safer_redis/version.rb
CHANGED
data/lib/safer_redis.rb
CHANGED
@@ -26,16 +26,4 @@ module SaferRedis
|
|
26
26
|
ensure
|
27
27
|
@active = was
|
28
28
|
end
|
29
|
-
|
30
|
-
def self.assess!(doc)
|
31
|
-
if doc.dangerous?
|
32
|
-
# Anything tagged @dangerous is… dangerous
|
33
|
-
raise SaferRedis::Danger.new(doc)
|
34
|
-
|
35
|
-
elsif doc.slow? && doc.complexity != "O(1)"
|
36
|
-
# Anything tagged @slow might be dangerous, but we'll let through O(1)
|
37
|
-
# complexity commands e.g. SET
|
38
|
-
raise SaferRedis::Danger.new(doc)
|
39
|
-
end
|
40
|
-
end
|
41
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safer_redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Annesley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- Rakefile
|
57
57
|
- data/redis-doc/commands.json
|
58
58
|
- lib/safer_redis.rb
|
59
|
+
- lib/safer_redis/assessor.rb
|
59
60
|
- lib/safer_redis/command_doc.rb
|
60
61
|
- lib/safer_redis/danger.rb
|
61
62
|
- lib/safer_redis/interceptor.rb
|
@@ -77,14 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
78
|
requirements:
|
78
79
|
- - ">="
|
79
80
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.
|
81
|
+
version: 3.2.0
|
81
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
83
|
requirements:
|
83
84
|
- - ">="
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: '0'
|
86
87
|
requirements: []
|
87
|
-
rubygems_version: 3.4.
|
88
|
+
rubygems_version: 3.4.22
|
88
89
|
signing_key:
|
89
90
|
specification_version: 4
|
90
91
|
summary: Catch unsafe Redis commands in production
|