console1984 0.1.15 → 0.1.19
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/README.md +5 -2
- data/app/models/console1984/session/incineratable.rb +1 -1
- data/lib/console1984/command_executor.rb +10 -12
- data/lib/console1984/ext/active_record/protected_auditable_tables.rb +1 -1
- data/lib/console1984/ext/core/object.rb +1 -1
- data/lib/console1984/ext/core/string.rb +24 -0
- data/lib/console1984/ext/irb/commands.rb +9 -0
- data/lib/console1984/ext/socket/tcp_socket.rb +2 -2
- data/lib/console1984/shield.rb +1 -1
- data/lib/console1984/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4341afd03a8560ccada70b03687e27a3e7b36aad9ee0e2ec914861df4c9457c8
|
4
|
+
data.tar.gz: 9f304ed8cc187d1ab43eb393b6c7ddba38855de5dea6793f4abb3ba6a1394dad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdb5812e2a23ff74037eb7290ec5960ba593b8cd999031275a4fdfbe26ec3186d195744190e575c31768b8307058bce13110980ba46083d3889f2d76af59de38
|
7
|
+
data.tar.gz: c738ea7bf36946273ab054aa2cf4cd33d0186fc8251b9ec6303bdd156d9851ac2203a62c213f97f081a200e63511844e6cb2d72fbae192f07b16227d60c03c00
|
data/README.md
CHANGED
@@ -35,6 +35,9 @@ By default, console1984 is only enabled in `production`. You can configure the t
|
|
35
35
|
config.console1984.protected_environments = %i[ production staging ]
|
36
36
|
```
|
37
37
|
|
38
|
+
Finally, you need to [configure Active Record Encryption](https://edgeguides.rubyonrails.org/active_record_encryption.html#setup) in your
|
39
|
+
project. This is because the library stores the tracked console commands encrypted.
|
40
|
+
|
38
41
|
## How it works
|
39
42
|
|
40
43
|
### Session activity logging
|
@@ -155,9 +158,9 @@ These config options are namespaced in `config.console1984`:
|
|
155
158
|
|
156
159
|
## About built-in protection mechanisms
|
157
160
|
|
158
|
-
`console1984`
|
161
|
+
`console1984` adds many protection mechanisms to prevent tampering. This includes attempts to alter data in auditing tables or monkey patching certain classes to change how the system works. If you find a way to circumvent these tampering controls, please [report an issue](https://github.com/basecamp/console1984/issues).
|
159
162
|
|
160
|
-
|
163
|
+
We aim to make these defense mechanisms as robust as possible, but there might always be open doors because Ruby is highly dynamic. If your organization needs bullet-proof protection against malicious actors using the console, you should consider additional security measures. An example would be using a read-only database user for auditing data while in a console. The gem doesn't offer direct support for doing this, but it's on our radar for future improvement.
|
161
164
|
|
162
165
|
## Running the test suite
|
163
166
|
|
@@ -10,6 +10,7 @@ class Console1984::CommandExecutor
|
|
10
10
|
include Console1984::Freezeable
|
11
11
|
|
12
12
|
delegate :username_resolver, :session_logger, :shield, to: Console1984
|
13
|
+
attr_reader :last_suspicious_command_error
|
13
14
|
|
14
15
|
# Logs and validates +commands+, and executes the passed block in a protected environment.
|
15
16
|
#
|
@@ -19,14 +20,14 @@ class Console1984::CommandExecutor
|
|
19
20
|
run_as_system { session_logger.before_executing commands }
|
20
21
|
validate_command commands
|
21
22
|
execute_in_protected_mode(&block)
|
22
|
-
rescue Console1984::Errors::ForbiddenCommandAttempted, FrozenError
|
23
|
-
flag_suspicious(commands)
|
24
|
-
rescue Console1984::Errors::SuspiciousCommandAttempted
|
25
|
-
flag_suspicious(commands)
|
23
|
+
rescue Console1984::Errors::ForbiddenCommandAttempted, FrozenError => error
|
24
|
+
flag_suspicious(commands, error: error)
|
25
|
+
rescue Console1984::Errors::SuspiciousCommandAttempted => error
|
26
|
+
flag_suspicious(commands, error: error)
|
26
27
|
execute_in_protected_mode(&block)
|
27
|
-
rescue Console1984::Errors::ForbiddenCommandExecuted
|
28
|
+
rescue Console1984::Errors::ForbiddenCommandExecuted => error
|
28
29
|
# We detected that a forbidden command was executed. We exit IRB right away.
|
29
|
-
flag_suspicious(commands)
|
30
|
+
flag_suspicious(commands, error: error)
|
30
31
|
Console1984.supervisor.exit_irb
|
31
32
|
ensure
|
32
33
|
run_as_system { session_logger.after_executing commands }
|
@@ -70,11 +71,7 @@ class Console1984::CommandExecutor
|
|
70
71
|
end
|
71
72
|
|
72
73
|
def from_irb?(backtrace)
|
73
|
-
executing_user_command? && backtrace.
|
74
|
-
line_from_irb = line =~ /^[^\/]/
|
75
|
-
break if !(line =~ /console1984\/lib/ || line_from_irb)
|
76
|
-
line_from_irb
|
77
|
-
end
|
74
|
+
executing_user_command? && backtrace.first.to_s =~ /^[^\/]/
|
78
75
|
end
|
79
76
|
|
80
77
|
private
|
@@ -86,9 +83,10 @@ class Console1984::CommandExecutor
|
|
86
83
|
Console1984::CommandValidator.from_config(Console1984.protections_config.validations)
|
87
84
|
end
|
88
85
|
|
89
|
-
def flag_suspicious(commands)
|
86
|
+
def flag_suspicious(commands, error: nil)
|
90
87
|
puts "Forbidden command attempted: #{commands.join("\n")}"
|
91
88
|
run_as_system { session_logger.suspicious_commands_attempted commands }
|
89
|
+
@last_suspicious_command_error = error
|
92
90
|
nil
|
93
91
|
end
|
94
92
|
|
@@ -5,7 +5,7 @@ module Console1984::Ext::ActiveRecord::ProtectedAuditableTables
|
|
5
5
|
%i[ execute exec_query exec_insert exec_delete exec_update exec_insert_all ].each do |method|
|
6
6
|
define_method method do |*args, **kwargs|
|
7
7
|
sql = args.first
|
8
|
-
if Console1984.command_executor.executing_user_command? && sql =~ auditable_tables_regexp
|
8
|
+
if Console1984.command_executor.executing_user_command? && sql.b =~ auditable_tables_regexp
|
9
9
|
raise Console1984::Errors::ForbiddenCommandAttempted, "#{sql}"
|
10
10
|
else
|
11
11
|
super(*args, **kwargs)
|
@@ -16,7 +16,7 @@ module Console1984::Ext::Core::Object
|
|
16
16
|
|
17
17
|
class_methods do
|
18
18
|
def const_get(*arguments)
|
19
|
-
if Console1984.command_executor.
|
19
|
+
if Console1984.command_executor.from_irb?(caller)
|
20
20
|
begin
|
21
21
|
# To validate if it's an invalid constant, we try to declare a class with it.
|
22
22
|
# We essentially leverage Console1984::CommandValidator::ForbiddenReopeningValidation here:
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Prevents loading forbidden classes dynamically.
|
2
|
+
#
|
3
|
+
# See extension to +Console1984::Ext::Core::Object#const_get+.
|
4
|
+
module Console1984::Ext::Core::String
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include Console1984::Freezeable
|
8
|
+
self.prevent_instance_data_manipulation_after_freezing = false
|
9
|
+
|
10
|
+
def constantize
|
11
|
+
if Console1984.command_executor.from_irb?(caller)
|
12
|
+
begin
|
13
|
+
Console1984.command_executor.validate_command("class #{self}; end")
|
14
|
+
super
|
15
|
+
rescue Console1984::Errors::ForbiddenCommandAttempted
|
16
|
+
raise
|
17
|
+
rescue StandardError
|
18
|
+
super
|
19
|
+
end
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -13,4 +13,13 @@ module Console1984::Ext::Irb::Commands
|
|
13
13
|
def encrypt!
|
14
14
|
shield.enable_protected_mode
|
15
15
|
end
|
16
|
+
|
17
|
+
# This returns the last error that prevented a command execution in the console
|
18
|
+
# or nil if there isn't any.
|
19
|
+
#
|
20
|
+
# This is meant for internal usage when debugging legit commands that are wrongly
|
21
|
+
# prevented.
|
22
|
+
def _console_last_suspicious_command_error
|
23
|
+
Console1984.command_executor.last_suspicious_command_error
|
24
|
+
end
|
16
25
|
end
|
data/lib/console1984/shield.rb
CHANGED
@@ -40,6 +40,7 @@ class Console1984::Shield
|
|
40
40
|
def extend_core_ruby
|
41
41
|
Object.prepend Console1984::Ext::Core::Object
|
42
42
|
Module.prepend Console1984::Ext::Core::Module
|
43
|
+
String.prepend Console1984::Ext::Core::String
|
43
44
|
end
|
44
45
|
|
45
46
|
def extend_sockets
|
@@ -63,7 +64,6 @@ class Console1984::Shield
|
|
63
64
|
if Object.const_defined?(class_string)
|
64
65
|
klass = class_string.constantize
|
65
66
|
klass.prepend(Console1984::Ext::ActiveRecord::ProtectedAuditableTables)
|
66
|
-
klass.include(Console1984::Freezeable)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
data/lib/console1984/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: console1984
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jorge Manrubia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -225,6 +225,7 @@ files:
|
|
225
225
|
- lib/console1984/ext/active_record/protected_auditable_tables.rb
|
226
226
|
- lib/console1984/ext/core/module.rb
|
227
227
|
- lib/console1984/ext/core/object.rb
|
228
|
+
- lib/console1984/ext/core/string.rb
|
228
229
|
- lib/console1984/ext/irb/commands.rb
|
229
230
|
- lib/console1984/ext/irb/context.rb
|
230
231
|
- lib/console1984/ext/socket/tcp_socket.rb
|
@@ -260,7 +261,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
260
261
|
requirements:
|
261
262
|
- - ">="
|
262
263
|
- !ruby/object:Gem::Version
|
263
|
-
version:
|
264
|
+
version: 2.7.0
|
264
265
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
265
266
|
requirements:
|
266
267
|
- - ">="
|