tcell_agent 2.1.0 → 2.3.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/bin/tcell_agent +42 -146
- data/lib/tcell_agent.rb +8 -16
- data/lib/tcell_agent/agent.rb +76 -46
- data/lib/tcell_agent/config_initializer.rb +66 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- data/lib/tcell_agent/instrumentation/cmdi.rb +15 -15
- data/lib/tcell_agent/instrumentation/lfi.rb +16 -5
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +39 -100
- data/lib/tcell_agent/logger.rb +1 -2
- data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +103 -102
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -58
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp.rb +0 -4
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +4 -1
- data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes.rb +3 -6
- data/lib/tcell_agent/rails/routes/grape.rb +4 -12
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +0 -1
- data/lib/tcell_agent/rust/agent_config.rb +43 -32
- data/lib/tcell_agent/rust/{libtcellagent-4.17.1.dylib → libtcellagent-6.2.1.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.17.1.so → libtcellagent-6.2.1.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.17.1.so → libtcellagent-alpine-6.2.1.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +18 -0
- data/lib/tcell_agent/rust/native_library.rb +2 -1
- data/lib/tcell_agent/rust/{tcellagent-4.17.1.dll → tcellagent-6.2.1.dll} +0 -0
- data/lib/tcell_agent/servers/puma.rb +7 -7
- data/lib/tcell_agent/servers/rack_puma_handler.rb +23 -0
- data/lib/tcell_agent/servers/rails_server.rb +4 -4
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/servers/webrick.rb +0 -1
- data/lib/tcell_agent/settings_reporter.rb +0 -79
- data/lib/tcell_agent/tcell_context.rb +1 -1
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +46 -4
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +47 -2
- data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +0 -73
- data/spec/spec_helper.rb +6 -0
- data/spec/support/builders.rb +6 -6
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +17 -0
- data/spec/support/server_mocks/rails_mock.rb +7 -0
- data/spec/support/server_mocks/thin_mock.rb +7 -0
- data/spec/support/server_mocks/unicorn_mock.rb +11 -0
- metadata +27 -14
- data/lib/tcell_agent/authlogic.rb +0 -23
- data/lib/tcell_agent/config/unknown_options.rb +0 -119
- data/lib/tcell_agent/devise.rb +0 -33
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -1,25 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
tcell_server = ENV['TCELL_AGENT_SERVER']
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
if (tcell_server && tcell_server == 'webrick') || defined?(Rails::Server)
|
6
|
-
require('tcell_agent/servers/rails_server')
|
5
|
+
TCellAgent.thread_agent.instrument_built_ins if tcell_server &&
|
6
|
+
tcell_server == 'mock'
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
require('tcell_agent/servers/rails_server') if (tcell_server && tcell_server == 'webrick') ||
|
9
|
+
defined?(Rails::Server)
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
require('tcell_agent/servers/thin') if (tcell_server && tcell_server == 'thin') ||
|
12
|
+
defined?(Thin)
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
require('tcell_agent/servers/puma') if (tcell_server && tcell_server == 'puma') ||
|
15
|
+
defined?(Puma)
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
17
|
+
require('tcell_agent/servers/unicorn') if (tcell_server && tcell_server == 'unicorn') ||
|
18
|
+
defined?(Unicorn)
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
require('tcell_agent/servers/unicorn')
|
25
|
-
end
|
20
|
+
require('tcell_agent/servers/passenger') if (tcell_server && tcell_server == 'passenger') ||
|
21
|
+
defined?(PhusionPassenger)
|
@@ -25,18 +25,18 @@ module TCellAgent
|
|
25
25
|
cmd = ''
|
26
26
|
|
27
27
|
TCellAgent::Instrumentation.safe_block('CMDI Parsing *args') do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if args_copy.first.is_a?(Array)
|
34
|
-
cmd_n_argv0 = args_copy.shift
|
35
|
-
args_copy.unshift(cmd_n_argv0.first)
|
36
|
-
end
|
28
|
+
return cmd if args.nil? || args.empty?
|
29
|
+
|
30
|
+
args_copy = Array.new(args)
|
31
|
+
args_copy.shift if args_copy.first.is_a?(Hash)
|
32
|
+
args_copy.pop if args_copy.last.is_a?(Hash)
|
37
33
|
|
38
|
-
|
34
|
+
if args_copy.first.is_a?(Array)
|
35
|
+
cmd_n_argv0 = args_copy.shift
|
36
|
+
args_copy.unshift(cmd_n_argv0.first)
|
39
37
|
end
|
38
|
+
|
39
|
+
cmd = args_copy.join(' ')
|
40
40
|
end
|
41
41
|
|
42
42
|
cmd
|
@@ -46,12 +46,12 @@ module TCellAgent
|
|
46
46
|
cmd = ''
|
47
47
|
|
48
48
|
TCellAgent::Instrumentation.safe_block('CMDI Parsing *args') do
|
49
|
-
|
50
|
-
args_copy = Array.new(args)
|
51
|
-
first_arg = args_copy.shift
|
49
|
+
return cmd if args.nil? || args.empty?
|
52
50
|
|
53
|
-
|
54
|
-
|
51
|
+
args_copy = Array.new(args)
|
52
|
+
first_arg = args_copy.shift
|
53
|
+
|
54
|
+
cmd = first_arg[1..-1] if first_arg && (first_arg.is_a? String) && first_arg[0] == '|'
|
55
55
|
end
|
56
56
|
|
57
57
|
cmd
|
@@ -26,15 +26,23 @@ module TCellAgent
|
|
26
26
|
path = ''
|
27
27
|
mode = ''
|
28
28
|
|
29
|
-
return ['', ''] if args.empty?
|
30
|
-
|
31
29
|
TCellAgent::Instrumentation.safe_block('LFI Parsing *args') do
|
30
|
+
return ['', ''] if args.nil? || args.empty?
|
31
|
+
|
32
32
|
args_copy = Array.new(args)
|
33
33
|
path = args_copy.shift
|
34
34
|
mode = args_copy.shift || 'r'
|
35
35
|
|
36
36
|
if path && path.to_s[0] != '|'
|
37
|
-
|
37
|
+
path = File.expand_path(path.to_s)
|
38
|
+
|
39
|
+
mode = if mode && mode.is_a?(Hash)
|
40
|
+
convert_mode(mode[:mode])
|
41
|
+
else
|
42
|
+
convert_mode(mode)
|
43
|
+
end
|
44
|
+
|
45
|
+
[path, mode]
|
38
46
|
else
|
39
47
|
['', '']
|
40
48
|
end
|
@@ -53,8 +61,11 @@ module TCellAgent
|
|
53
61
|
path = ARGF.filename
|
54
62
|
end
|
55
63
|
|
56
|
-
path
|
57
|
-
|
64
|
+
if path && path.to_s[0] != '|'
|
65
|
+
[File.expand_path(path.to_s), mode]
|
66
|
+
else
|
67
|
+
['', '']
|
68
|
+
end
|
58
69
|
end
|
59
70
|
end
|
60
71
|
|
@@ -1,76 +1,52 @@
|
|
1
1
|
module Kernel
|
2
|
-
|
3
|
-
alias_method :tcell_original_1_open, :open
|
4
|
-
def open(*args, &block)
|
5
|
-
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
|
6
|
-
|
7
|
-
if !path.strip.empty? && TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
|
8
|
-
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
9
|
-
end
|
10
|
-
|
11
|
-
if path.empty?
|
12
|
-
cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
|
13
|
-
if cmd && TCellAgent::Cmdi.block_command?(cmd)
|
14
|
-
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
15
|
-
end
|
16
|
-
end
|
2
|
+
private
|
17
3
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
|
26
|
-
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
27
|
-
end
|
28
|
-
|
29
|
-
tcell_original_1_gets(*args, &block)
|
30
|
-
end
|
4
|
+
alias_method :tcell_original_backtick, :`
|
5
|
+
alias_method :tcell_original_exec, :exec
|
6
|
+
alias_method :tcell_original_open, :open
|
7
|
+
alias_method :tcell_original_gets, :gets
|
8
|
+
alias_method :tcell_original_readline, :readline
|
9
|
+
alias_method :tcell_original_spawn, :spawn
|
10
|
+
alias_method :tcell_original_system, :system
|
31
11
|
|
12
|
+
class << self
|
13
|
+
alias_method :tcell_original_exec, :exec
|
14
|
+
alias_method :tcell_original_open, :open
|
15
|
+
alias_method :tcell_original_gets, :gets
|
32
16
|
alias_method :tcell_original_readline, :readline
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
|
37
|
-
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
38
|
-
end
|
17
|
+
alias_method :tcell_original_spawn, :spawn
|
18
|
+
alias_method :tcell_original_system, :system
|
19
|
+
end
|
39
20
|
|
40
|
-
|
21
|
+
def `(cmd)
|
22
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
23
|
+
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
41
24
|
end
|
42
25
|
|
43
|
-
|
44
|
-
|
45
|
-
cmd = TCellAgent::Cmdi.parse_command(*args)
|
46
|
-
if TCellAgent::Cmdi.block_command?(cmd)
|
47
|
-
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
48
|
-
end
|
49
|
-
|
50
|
-
tcell_original_1_spawn(*args)
|
51
|
-
end
|
26
|
+
tcell_original_backtick(cmd)
|
27
|
+
end
|
52
28
|
|
53
|
-
|
54
|
-
def
|
29
|
+
if TCellAgent.configuration.should_instrument?('kernel_exec')
|
30
|
+
def exec(*args)
|
55
31
|
cmd = TCellAgent::Cmdi.parse_command(*args)
|
56
32
|
if TCellAgent::Cmdi.block_command?(cmd)
|
57
33
|
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
58
34
|
end
|
59
35
|
|
60
|
-
|
36
|
+
tcell_original_exec(*args)
|
61
37
|
end
|
62
38
|
end
|
63
39
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
40
|
+
def gets(*args, &block)
|
41
|
+
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
|
42
|
+
|
43
|
+
if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
|
44
|
+
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
68
45
|
end
|
69
46
|
|
70
|
-
|
47
|
+
tcell_original_gets(*args, &block)
|
71
48
|
end
|
72
49
|
|
73
|
-
alias_method :tcell_original_2_open, :open
|
74
50
|
def open(*args, &block)
|
75
51
|
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
|
76
52
|
|
@@ -85,21 +61,9 @@ module Kernel
|
|
85
61
|
end
|
86
62
|
end
|
87
63
|
|
88
|
-
|
64
|
+
tcell_original_open(*args, &block)
|
89
65
|
end
|
90
66
|
|
91
|
-
alias_method :tcell_original_2_gets, :gets
|
92
|
-
def gets(*args, &block)
|
93
|
-
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
|
94
|
-
|
95
|
-
if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
|
96
|
-
raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
|
97
|
-
end
|
98
|
-
|
99
|
-
tcell_original_2_gets(*args, &block)
|
100
|
-
end
|
101
|
-
|
102
|
-
alias_method :tcell_original_readline, :readline
|
103
67
|
def readline(*args, &block)
|
104
68
|
path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
|
105
69
|
|
@@ -110,54 +74,29 @@ module Kernel
|
|
110
74
|
tcell_original_readline(*args, &block)
|
111
75
|
end
|
112
76
|
|
113
|
-
alias_method :tcell_original_2_spawn, :spawn
|
114
77
|
def spawn(*args)
|
115
78
|
cmd = TCellAgent::Cmdi.parse_command(*args)
|
116
79
|
if TCellAgent::Cmdi.block_command?(cmd)
|
117
80
|
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
118
81
|
end
|
119
82
|
|
120
|
-
|
83
|
+
tcell_original_spawn(*args)
|
121
84
|
end
|
122
85
|
|
123
|
-
alias_method :tcell_original_2_system, :system
|
124
86
|
def system(*args)
|
125
87
|
cmd = TCellAgent::Cmdi.parse_command(*args)
|
126
88
|
if TCellAgent::Cmdi.block_command?(cmd)
|
127
89
|
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
128
90
|
end
|
129
91
|
|
130
|
-
|
92
|
+
tcell_original_system(*args)
|
131
93
|
end
|
132
|
-
end
|
133
|
-
|
134
|
-
if TCellAgent.configuration.should_instrument_cmdi_exec?
|
135
|
-
module Kernel
|
136
|
-
class << self
|
137
|
-
alias_method :tcell_original_exec, :exec
|
138
|
-
def exec(*args)
|
139
|
-
cmd = TCellAgent::Cmdi.parse_command(*args)
|
140
|
-
if TCellAgent::Cmdi.block_command?(cmd)
|
141
|
-
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
142
|
-
end
|
143
|
-
|
144
|
-
tcell_original_exec(*args)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
alias_method :tcell_original_exec, :exec
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def exec(*args)
|
153
|
-
cmd = TCellAgent::Cmdi.parse_command(*args)
|
154
|
-
if TCellAgent::Cmdi.block_command?(cmd)
|
155
|
-
raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
|
156
|
-
end
|
157
94
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
95
|
+
module_function :`
|
96
|
+
module_function :exec
|
97
|
+
module_function :gets
|
98
|
+
module_function :open
|
99
|
+
module_function :readline
|
100
|
+
module_function :spawn
|
101
|
+
module_function :system
|
163
102
|
end
|
data/lib/tcell_agent/logger.rb
CHANGED
@@ -14,7 +14,6 @@ module TCellAgent
|
|
14
14
|
def initialize(logger, module_name)
|
15
15
|
@logger = logger
|
16
16
|
@module_name = module_name
|
17
|
-
@module_name = "#{TCellAgent.configuration.log_tag} #{module_name}" if TCellAgent.configuration.log_tag
|
18
17
|
end
|
19
18
|
|
20
19
|
%i[exception debug info warn error].each do |method_name|
|
@@ -80,7 +79,7 @@ module TCellAgent
|
|
80
79
|
@native_logger
|
81
80
|
end
|
82
81
|
|
83
|
-
def self.
|
82
|
+
def self.native_logger=(native_agent)
|
84
83
|
@native_logger = NativeLogger.new(native_agent)
|
85
84
|
end
|
86
85
|
end
|
@@ -1,56 +1,61 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require 'tcell_agent/configuration'
|
4
|
+
require 'tcell_agent/instrumentation'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
module TCellAgent
|
7
|
+
require 'tcell_agent/agent'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
Authlogic::Session::Base.class_eval do
|
10
|
+
alias_method :tcell_save, :save
|
11
|
+
def save(&block)
|
12
|
+
return tcell_save(&block) unless TCellAgent.configuration.should_intercept_requests?
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
user_logged_in_before = !user.nil?
|
15
|
+
success = tcell_save(&block)
|
16
|
+
user_logged_in_after = !user.nil?
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
TCellAgent::Instrumentation.safe_block('Authlogic login info') do
|
19
|
+
user_id = nil
|
20
|
+
password = nil
|
21
|
+
user_valid = nil
|
22
|
+
TCellAgent::Instrumentation.safe_block('getting userid for login form') do
|
23
|
+
user_id = send(self.class.login_field.to_sym)
|
24
|
+
end
|
25
|
+
|
26
|
+
request = Authlogic::Session::Base.controller.request
|
27
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
28
|
+
|
29
|
+
return success unless tcell_data
|
30
|
+
|
31
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
32
|
+
if user_logged_in_before && user_logged_in_after
|
33
|
+
# password changed or logged in as another user
|
34
|
+
elsif !user_logged_in_before && !user_logged_in_after
|
35
|
+
TCellAgent::Instrumentation.safe_block('checking if user is valid') do
|
36
|
+
error_messages = errors.messages[login_field]
|
25
37
|
|
26
|
-
|
27
|
-
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
28
|
-
|
29
|
-
return success unless tcell_data
|
30
|
-
|
31
|
-
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
32
|
-
if user_logged_in_before && user_logged_in_after
|
33
|
-
# password changed or logged in as another user
|
34
|
-
elsif !user_logged_in_before && !user_logged_in_after
|
35
|
-
login_policy.report_login_failure(
|
36
|
-
user_id,
|
37
|
-
password,
|
38
|
-
request.env,
|
39
|
-
user_valid,
|
40
|
-
tcell_data
|
41
|
-
)
|
42
|
-
elsif !user_logged_in_before && user_logged_in_after
|
43
|
-
login_policy.report_login_success(
|
44
|
-
user_id,
|
45
|
-
request.env,
|
46
|
-
tcell_data
|
47
|
-
)
|
38
|
+
user_valid = error_messages.empty?
|
48
39
|
end
|
49
|
-
end
|
50
40
|
|
51
|
-
|
41
|
+
login_policy.report_login_failure(
|
42
|
+
user_id,
|
43
|
+
password,
|
44
|
+
request.env,
|
45
|
+
user_valid,
|
46
|
+
tcell_data
|
47
|
+
)
|
48
|
+
elsif !user_logged_in_before && user_logged_in_after
|
49
|
+
tcell_data.user_id = user_id if user_id && tcell_data.user_id.nil?
|
50
|
+
login_policy.report_login_success(
|
51
|
+
user_id,
|
52
|
+
request.env,
|
53
|
+
tcell_data
|
54
|
+
)
|
55
|
+
end
|
52
56
|
end
|
57
|
+
|
58
|
+
success
|
53
59
|
end
|
54
60
|
end
|
55
|
-
|
56
61
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'tcell_agent/rails/auth/userinfo'
|
2
|
+
|
3
|
+
module TCellAgent
|
4
|
+
TCellAgent::UserInformation.class_eval do
|
5
|
+
class << self
|
6
|
+
alias_method :original_get_user_from_request, :get_user_from_request
|
7
|
+
def get_user_from_request(request)
|
8
|
+
orig_user_id = original_get_user_from_request(request)
|
9
|
+
begin
|
10
|
+
if request.session && request.session.key?('user_credentials_id')
|
11
|
+
return request.session['user_credentials_id'].to_s
|
12
|
+
end
|
13
|
+
rescue StandardError
|
14
|
+
return orig_user_id
|
15
|
+
end
|
16
|
+
orig_user_id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|