tcell_agent 2.2.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +6 -11
- data/lib/tcell_agent/agent.rb +18 -13
- data/lib/tcell_agent/config_initializer.rb +2 -5
- data/lib/tcell_agent/configuration.rb +6 -6
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
- data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +1 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp.rb +48 -48
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -5
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/routes/grape.rb +2 -1
- data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -6
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +20 -2
- data/lib/tcell_agent/rust/{libtcellagent-5.0.2.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{tcellagent-5.0.2.dll → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-5.0.2.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-5.0.2.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/native_agent.rb +51 -59
- data/lib/tcell_agent/rust/native_library.rb +7 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +25 -8
- data/lib/tcell_agent/servers/rack_puma_handler.rb +13 -3
- data/lib/tcell_agent/servers/webrick.rb +13 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -14
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +15 -6
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +1 -1
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -16
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +3 -1
- data/spec/support/builders.rb +2 -1
- data/spec/support/server_mocks/puma_mock.rb +4 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +23 -19
- data/Rakefile +0 -18
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
@@ -37,6 +37,7 @@ module TCellAgent
|
|
37
37
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
38
38
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
39
39
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_form_parameter?
|
40
|
+
|
40
41
|
for_params(request) do |_method, param_name, param_value|
|
41
42
|
actions = dataex_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
|
42
43
|
if actions
|
@@ -51,11 +52,13 @@ module TCellAgent
|
|
51
52
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
52
53
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
53
54
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_headers?
|
55
|
+
|
54
56
|
headers = request.env.select { |k, _v| k.start_with? 'HTTP_' }
|
55
57
|
headers.each do |header_name, header_value|
|
56
58
|
header_name = header_name.sub(/^HTTP_/, '').tr('_', '-')
|
57
59
|
actions = dataex_policy.get_actions_for_header(header_name)
|
58
60
|
next unless actions
|
61
|
+
|
59
62
|
actions.each do |action|
|
60
63
|
tcell_context.add_filter_for_header_value(header_value, action, header_name)
|
61
64
|
end
|
@@ -66,9 +69,11 @@ module TCellAgent
|
|
66
69
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
67
70
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
68
71
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_cookie?
|
72
|
+
|
69
73
|
request.cookies.each do |cookie_name, cookie_value|
|
70
74
|
actions = dataex_policy.get_actions_for_cookie(cookie_name)
|
71
75
|
next unless actions
|
76
|
+
|
72
77
|
actions.each do |action|
|
73
78
|
tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
|
74
79
|
end
|
@@ -80,6 +80,7 @@ module TCellAgent
|
|
80
80
|
normalized_column_names[namespaced_column_name] = column_name
|
81
81
|
|
82
82
|
next unless column_name && (!namespace || namespace == table_name)
|
83
|
+
|
83
84
|
rules = dlp_policy.get_actions_for_table(
|
84
85
|
database_name,
|
85
86
|
'*',
|
@@ -190,6 +191,7 @@ module TCellAgent
|
|
190
191
|
results[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
|
191
192
|
column_name_to_rules.each do |column_name, rules|
|
192
193
|
next unless rules
|
194
|
+
|
193
195
|
rules.each do |rule|
|
194
196
|
tcell_context.add_response_db_filter(
|
195
197
|
record[column_name.to_sym],
|
@@ -301,31 +303,29 @@ module TCellAgent
|
|
301
303
|
def log_enforce(tcell_context, sanitize_string)
|
302
304
|
if TCellAgent.configuration.should_instrument? &&
|
303
305
|
TCellAgent.configuration.should_intercept_requests?
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
send_event = true
|
317
|
-
end
|
318
|
-
m
|
319
|
-
end
|
320
|
-
if send_event
|
321
|
-
TCellAgent.send_event(
|
322
|
-
TCellAgent::SensorEvents::DlpEvent.new(
|
323
|
-
tcell_context.route_id,
|
324
|
-
tcell_context.uri,
|
325
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
|
326
|
-
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
327
|
-
)
|
306
|
+
session_id_actions = get_actions_for_session_id
|
307
|
+
if tcell_context && tcell_context.session_id && session_id_actions
|
308
|
+
send_event = false
|
309
|
+
sanitize_string.gsub!(tcell_context.session_id) do |m|
|
310
|
+
if session_id_actions.log_redact
|
311
|
+
send_event = true
|
312
|
+
m = '[session_id]'
|
313
|
+
elsif session_id_actions.log_hash
|
314
|
+
send_event = true
|
315
|
+
m = '[hash]'
|
316
|
+
elsif session_id_actions.log_event
|
317
|
+
send_event = true
|
328
318
|
end
|
319
|
+
m
|
320
|
+
end
|
321
|
+
if send_event
|
322
|
+
TCellAgent.send_event(
|
323
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
324
|
+
tcell_context.route_id,
|
325
|
+
tcell_context.uri,
|
326
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
|
327
|
+
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
328
|
+
)
|
329
329
|
end
|
330
330
|
end
|
331
331
|
end
|
@@ -336,32 +336,32 @@ module TCellAgent
|
|
336
336
|
def response_body_enforce(tcell_context, sanitize_string)
|
337
337
|
if TCellAgent.configuration.should_instrument? &&
|
338
338
|
TCellAgent.configuration.should_intercept_requests?
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
end
|
353
|
-
m
|
339
|
+
session_id_actions = get_actions_for_session_id
|
340
|
+
if tcell_context && tcell_context.session_id && session_id_actions
|
341
|
+
send_event = false
|
342
|
+
sanitize_string.gsub!(tcell_context.session_id) do |m|
|
343
|
+
# rubocop:disable Lint/DuplicateBranch
|
344
|
+
if session_id_actions.body_redact
|
345
|
+
# m = "[session_id]"
|
346
|
+
send_event = true
|
347
|
+
elsif session_id_actions.body_hash
|
348
|
+
# m = "[hash]"
|
349
|
+
send_event = true
|
350
|
+
elsif session_id_actions.body_event
|
351
|
+
send_event = true
|
354
352
|
end
|
353
|
+
# rubocop:enable Lint/DuplicateBranch
|
354
|
+
m
|
355
355
|
end
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
)
|
364
|
-
|
356
|
+
end
|
357
|
+
if send_event
|
358
|
+
TCellAgent.send_event(
|
359
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
360
|
+
tcell_context.route_id,
|
361
|
+
tcell_context.uri,
|
362
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY
|
363
|
+
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
364
|
+
)
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
@@ -39,19 +39,18 @@ module TCellAgent
|
|
39
39
|
|
40
40
|
TCellAgent::Instrumentation.safe_block('DLP Handler get handler and context') do
|
41
41
|
if TCellAgent.configuration.should_instrument? &&
|
42
|
-
TCellAgent.configuration.should_intercept_requests?
|
42
|
+
TCellAgent.configuration.should_intercept_requests? &&
|
43
|
+
TCellAgent::Utils::Rails.processable_response?(response_headers)
|
43
44
|
|
44
45
|
# do all this work so that dlp doesn't run at all unless it's on and there
|
45
46
|
# are rules to run
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
end
|
47
|
+
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
48
|
+
if dlp_policy && dlp_policy.get_actions_for_session_id
|
49
|
+
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
50
|
+
if tcell_context && tcell_context.session_id
|
51
|
+
dlp_handler = proc { |tc, resp|
|
52
|
+
handle_dlp!(tc, resp)
|
53
|
+
}
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
@@ -4,8 +4,7 @@ module TCellAgent
|
|
4
4
|
module Instrumentation
|
5
5
|
module Rails
|
6
6
|
module JSAgent
|
7
|
-
HEAD_SEARCH_REGEX =
|
8
|
-
|
7
|
+
HEAD_SEARCH_REGEX = Regexp.new('(<head>|<head( |\n).*?>)', Regexp::IGNORECASE)
|
9
8
|
def self.insert_now(js_agent_handler, script_insert, rack_body, content_length)
|
10
9
|
TCellAgent::Instrumentation.safe_block('Handling JSAgent Insert Now') do
|
11
10
|
if js_agent_handler
|
@@ -32,7 +31,7 @@ module TCellAgent
|
|
32
31
|
TCellAgent::Instrumentation.safe_block('Handling JSAgent insert') do
|
33
32
|
new_response = response.sub(
|
34
33
|
TCellAgent::Instrumentation::Rails::JSAgent::HEAD_SEARCH_REGEX,
|
35
|
-
"
|
34
|
+
"\\1#{script_insert}"
|
36
35
|
)
|
37
36
|
end
|
38
37
|
|
@@ -26,7 +26,8 @@ module TCellAgent
|
|
26
26
|
env[TCellAgent::Instrumentation::TCELL_ID].path = request.path
|
27
27
|
env[TCellAgent::Instrumentation::TCELL_ID].user_agent = request.user_agent
|
28
28
|
env[TCellAgent::Instrumentation::TCELL_ID].referrer = request.referrer
|
29
|
-
env[TCellAgent::Instrumentation::TCELL_ID].remote_address =
|
29
|
+
env[TCellAgent::Instrumentation::TCELL_ID].remote_address = request.ip
|
30
|
+
env[TCellAgent::Instrumentation::TCELL_ID].reverse_proxy_header_value = TCellAgent::Utils::Rails.reverse_proxy_header(request)
|
30
31
|
if request.request_method
|
31
32
|
env[TCellAgent::Instrumentation::TCELL_ID].request_method = request.request_method
|
32
33
|
end
|
@@ -25,8 +25,6 @@ module TCellAgent
|
|
25
25
|
if TCellAgent.configuration.should_intercept_requests?
|
26
26
|
request = Rack::Request.new(env)
|
27
27
|
|
28
|
-
request['init'] = true
|
29
|
-
|
30
28
|
TCellAgent::Instrumentation.safe_block('Setting session_id & user_id') do
|
31
29
|
if request.session
|
32
30
|
env[TCellAgent::Instrumentation::TCELL_ID].session_id =
|
@@ -44,9 +42,7 @@ module TCellAgent
|
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
response
|
45
|
+
@app.call(env)
|
50
46
|
end
|
51
47
|
end
|
52
48
|
end
|
@@ -39,6 +39,7 @@ module TCellAgent
|
|
39
39
|
TCellAgent::Instrumentation.safe_block('Handling headers') do
|
40
40
|
headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HEADERS)
|
41
41
|
policy_headers = headers_policy.get_headers(
|
42
|
+
headers['Content-Type'],
|
42
43
|
request.env[TCellAgent::Instrumentation::TCELL_ID]
|
43
44
|
)
|
44
45
|
policy_headers.each do |header_info|
|
@@ -7,8 +7,9 @@ module TCellAgent
|
|
7
7
|
begin
|
8
8
|
return route.app < Grape::API if ::Rails::VERSION::MAJOR == 4 &&
|
9
9
|
::Rails::VERSION::MINOR < 2
|
10
|
+
|
10
11
|
return route.app.app < Grape::API
|
11
|
-
rescue StandardError
|
12
|
+
rescue StandardError
|
12
13
|
# do nothing
|
13
14
|
end
|
14
15
|
end
|
@@ -6,12 +6,9 @@ require 'tcell_agent/sensor_events/server_agent'
|
|
6
6
|
module TCellAgent
|
7
7
|
module Instrumentation
|
8
8
|
module Rails
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
'Rails', ::Rails.version
|
13
|
-
)
|
14
|
-
)
|
9
|
+
def self.framework_details
|
10
|
+
{ 'app_framework' => 'Rails',
|
11
|
+
'app_framework_version' => ::Rails.version }
|
15
12
|
end
|
16
13
|
|
17
14
|
def self.send_settings
|
@@ -53,18 +53,16 @@ module TCellAgent
|
|
53
53
|
@body.respond_to?(method_name, include_all)
|
54
54
|
end
|
55
55
|
|
56
|
-
def method_missing(method_name, *args, &block)
|
56
|
+
def method_missing(method_name, *args, &block)
|
57
57
|
@body.__send__(method_name, *args, &block)
|
58
58
|
end
|
59
59
|
|
60
60
|
def process_body(body)
|
61
61
|
TCellAgent::Instrumentation.safe_block('Processing tcell body proxy body') do
|
62
62
|
chunked_response_match = nil
|
63
|
-
if body.class.name == 'String'
|
64
|
-
|
65
|
-
|
66
|
-
@content_length += chunked_response_match.to_i(16)
|
67
|
-
end
|
63
|
+
if body.class.name == 'String' && body =~ /^([[:xdigit:]]+)(;.+)?\r\n/
|
64
|
+
chunked_response_match = Regexp.last_match(1)
|
65
|
+
@content_length += chunked_response_match.to_i(16)
|
68
66
|
end
|
69
67
|
|
70
68
|
new_body = body
|
@@ -2,6 +2,7 @@ module TCellAgent
|
|
2
2
|
module Routes
|
3
3
|
class FieldEndpoint
|
4
4
|
attr_accessor :discovered
|
5
|
+
|
5
6
|
def initialize
|
6
7
|
super()
|
7
8
|
@discovered = false
|
@@ -11,6 +12,7 @@ module TCellAgent
|
|
11
12
|
class RouteEndpoint
|
12
13
|
attr_accessor :database
|
13
14
|
attr_accessor :database_queries_discovered
|
15
|
+
|
14
16
|
def initialize
|
15
17
|
@database_queries_discovered = {}
|
16
18
|
@database = Hash.new do |d_h, d_k| # Database
|
@@ -27,6 +29,7 @@ module TCellAgent
|
|
27
29
|
|
28
30
|
class RouteTable
|
29
31
|
attr_accessor :routes
|
32
|
+
|
30
33
|
def initialize
|
31
34
|
@routes = Hash.new { |h, k| h[k] = RouteEndpoint.new }
|
32
35
|
end
|
@@ -19,8 +19,23 @@ module TCellAgent
|
|
19
19
|
self['overrides'] = overrides
|
20
20
|
else
|
21
21
|
self['overrides'] = { 'applications' => [{ :enable_json_body_inspection => true }],
|
22
|
-
'
|
22
|
+
'config_file_path' => configuration.get_config_file_path }
|
23
23
|
end
|
24
|
+
|
25
|
+
set_agent_details
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_agent_details
|
29
|
+
framework_details = if defined?(Rails)
|
30
|
+
TCellAgent::Instrumentation::Rails.framework_details
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
|
35
|
+
self['agent_details'] = { 'language' => 'Ruby',
|
36
|
+
'language_version' => RUBY_VERSION,
|
37
|
+
'app_framework' => framework_details['app_framework'],
|
38
|
+
'app_framework_version' => framework_details['app_framework_version'] }
|
24
39
|
end
|
25
40
|
end
|
26
41
|
|
@@ -40,7 +55,7 @@ module TCellAgent
|
|
40
55
|
|
41
56
|
self['api_url'] = configuration.tcell_api_url
|
42
57
|
self['applications'] = [Models.clean_nils(applications)]
|
43
|
-
self['
|
58
|
+
self['config_file_path'] = configuration.get_config_file_path
|
44
59
|
self['disabled_instrumentation'] = configuration.disabled_instrumentation
|
45
60
|
self['enabled'] = configuration.enabled
|
46
61
|
self['host_identifier'] = configuration.host_identifier
|
@@ -53,6 +68,9 @@ module TCellAgent
|
|
53
68
|
self['log_enabled'] = configuration.logging_options[:enabled]
|
54
69
|
self['log_filename'] = configuration.logging_options[:log_filename]
|
55
70
|
self['log_level'] = configuration.logging_options[:level]
|
71
|
+
self['proxy_url'] = configuration.proxy_url
|
72
|
+
self['proxy_username'] = configuration.proxy_username
|
73
|
+
self['proxy_password'] = configuration.proxy_password
|
56
74
|
self['update_policy'] = configuration.fetch_policies_from_tcell
|
57
75
|
end
|
58
76
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -9,55 +9,6 @@ require 'tcell_agent/utils/headers'
|
|
9
9
|
module TCellAgent
|
10
10
|
module Rust
|
11
11
|
class NativeAgent # rubocop:disable Metrics/ClassLength
|
12
|
-
def self.test_event_sender(events)
|
13
|
-
config = TCellAgent.configuration
|
14
|
-
event_sender = {
|
15
|
-
:uuid => config.uuid,
|
16
|
-
:hostname => config.host_identifier,
|
17
|
-
:agent_type => 'Ruby',
|
18
|
-
:agent_version => TCellAgent::VERSION,
|
19
|
-
:app_id => config.app_id,
|
20
|
-
:api_key => config.api_key,
|
21
|
-
:tcell_input_url => config.tcell_input_url,
|
22
|
-
:events => events
|
23
|
-
}
|
24
|
-
event_sender_pointer = FFI::MemoryPointer.from_string(
|
25
|
-
JSON.dump(event_sender)
|
26
|
-
)
|
27
|
-
|
28
|
-
buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
|
29
|
-
# config_pointer.size - 1: strips null terminator
|
30
|
-
result_size = TCellAgent::Rust::NativeLibrary.test_event_sender(
|
31
|
-
event_sender_pointer, event_sender_pointer.size - 1, buf, buf.size
|
32
|
-
)
|
33
|
-
|
34
|
-
response = NativeAgentResponse.new('test_event_sender', buf, result_size)
|
35
|
-
|
36
|
-
response.errors
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.test_policies
|
40
|
-
config = TCellAgent.configuration
|
41
|
-
policies_info = {
|
42
|
-
:app_id => config.app_id,
|
43
|
-
:api_key => config.api_key,
|
44
|
-
:tcell_api_url => config.tcell_api_url
|
45
|
-
}
|
46
|
-
policies_info_pointer = FFI::MemoryPointer.from_string(
|
47
|
-
JSON.dump(policies_info)
|
48
|
-
)
|
49
|
-
|
50
|
-
buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
|
51
|
-
# config_pointer.size - 1: strips null terminator
|
52
|
-
result_size = TCellAgent::Rust::NativeLibrary.test_policies(
|
53
|
-
policies_info_pointer, policies_info_pointer.size - 1, buf, buf.size
|
54
|
-
)
|
55
|
-
|
56
|
-
response = NativeAgentResponse.new('test_event_sender', buf, result_size)
|
57
|
-
|
58
|
-
response.errors
|
59
|
-
end
|
60
|
-
|
61
12
|
def self.test_agent(config)
|
62
13
|
agent_config = TCellAgent::Rust::AgentConfig.new(config)
|
63
14
|
|
@@ -133,6 +84,7 @@ module TCellAgent
|
|
133
84
|
:headers => header_params,
|
134
85
|
:cookies => cookie_params,
|
135
86
|
:path_params => path_params,
|
87
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
136
88
|
:remote_address => appsensor_meta.remote_address,
|
137
89
|
:full_uri => appsensor_meta.location,
|
138
90
|
:session_id => appsensor_meta.session_id,
|
@@ -143,7 +95,6 @@ module TCellAgent
|
|
143
95
|
:content_type => appsensor_meta.content_type,
|
144
96
|
:request_body => appsensor_meta.raw_request_body
|
145
97
|
}
|
146
|
-
|
147
98
|
request_response_json[:sql_exceptions] = appsensor_meta.sql_exceptions if appsensor_meta.sql_exceptions
|
148
99
|
request_response_json[:database_result_sizes] = appsensor_meta.database_result_sizes if appsensor_meta.database_result_sizes
|
149
100
|
|
@@ -184,13 +135,15 @@ module TCellAgent
|
|
184
135
|
:method => appsensor_meta.method,
|
185
136
|
:path => appsensor_meta.path,
|
186
137
|
:remote_address => appsensor_meta.remote_address,
|
138
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
187
139
|
:request_bytes_length => appsensor_meta.request_content_bytes_len,
|
188
140
|
:query_params => query_params,
|
189
|
-
:post_params =>
|
141
|
+
:post_params => post_params,
|
190
142
|
:headers => header_params,
|
191
143
|
:cookies => cookie_params,
|
192
144
|
:content_type => appsensor_meta.content_type,
|
193
|
-
:full_uri => appsensor_meta.location
|
145
|
+
:full_uri => appsensor_meta.location,
|
146
|
+
:request_body => appsensor_meta.raw_request_body
|
194
147
|
}
|
195
148
|
|
196
149
|
patches_request_pointer = FFI::MemoryPointer.from_string(
|
@@ -213,6 +166,37 @@ module TCellAgent
|
|
213
166
|
response.response
|
214
167
|
end
|
215
168
|
|
169
|
+
def apply_suspicious_quick_check(appsensor_meta)
|
170
|
+
return {} unless appsensor_meta
|
171
|
+
|
172
|
+
sus_quick_check_request_json = {
|
173
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
174
|
+
:method => appsensor_meta.method,
|
175
|
+
:path => appsensor_meta.path,
|
176
|
+
:full_uri => appsensor_meta.location,
|
177
|
+
:request_bytes_length => appsensor_meta.request_content_bytes_len
|
178
|
+
}
|
179
|
+
|
180
|
+
if appsensor_meta.reverse_proxy_header_value.nil?
|
181
|
+
sus_quick_check_request_json.merge(
|
182
|
+
{
|
183
|
+
:client_ip_override => appsensor_meta.remote_address
|
184
|
+
}
|
185
|
+
)
|
186
|
+
end
|
187
|
+
|
188
|
+
sus_quick_check_request_ptr = FFI::MemoryPointer.from_string(
|
189
|
+
JSON.dump(sus_quick_check_request_json)
|
190
|
+
)
|
191
|
+
|
192
|
+
# sus_quick_check_request_ptr.size - 1: strips null terminator
|
193
|
+
TCellAgent::Rust::NativeLibrary.suspicious_quick_check_apply(
|
194
|
+
FFI::Pointer.new(@agent_ptr),
|
195
|
+
sus_quick_check_request_ptr,
|
196
|
+
sus_quick_check_request_ptr.size - 1
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
216
200
|
def apply_cmdi(command, tcell_context)
|
217
201
|
return unless TCellAgent::Utils::Strings.present?(command)
|
218
202
|
|
@@ -220,6 +204,7 @@ module TCellAgent
|
|
220
204
|
:command => command,
|
221
205
|
:method => tcell_context.request_method,
|
222
206
|
:path => tcell_context.path,
|
207
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
223
208
|
:remote_address => tcell_context.remote_address,
|
224
209
|
:route_id => tcell_context.route_id,
|
225
210
|
:session_id => tcell_context.session_id,
|
@@ -247,10 +232,11 @@ module TCellAgent
|
|
247
232
|
response.response
|
248
233
|
end
|
249
234
|
|
250
|
-
def get_headers(tcell_context)
|
235
|
+
def get_headers(content_type, tcell_context)
|
251
236
|
return unless tcell_context
|
252
237
|
|
253
238
|
headers_request = {
|
239
|
+
:content_type => content_type,
|
254
240
|
:method => tcell_context.request_method,
|
255
241
|
:path => tcell_context.path,
|
256
242
|
:route_id => tcell_context.route_id.to_s,
|
@@ -288,8 +274,9 @@ module TCellAgent
|
|
288
274
|
:status_code => status_code,
|
289
275
|
:method => tcell_context.request_method,
|
290
276
|
:path => tcell_context.path,
|
277
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
291
278
|
:remote_addr => tcell_context.remote_address,
|
292
|
-
:full_uri => tcell_context.
|
279
|
+
:full_uri => tcell_context.uri,
|
293
280
|
:route_id => tcell_context.route_id,
|
294
281
|
:session_id => tcell_context.session_id,
|
295
282
|
:user_id => tcell_context.user_id
|
@@ -353,11 +340,12 @@ module TCellAgent
|
|
353
340
|
:event_name => event_name,
|
354
341
|
:user_id => user_id,
|
355
342
|
:user_agent => tcell_context.user_agent,
|
343
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
356
344
|
:remote_address => tcell_context.remote_address,
|
357
345
|
:header_keys => header_keys,
|
358
|
-
:
|
346
|
+
:password => password,
|
359
347
|
:session_id => tcell_context.session_id,
|
360
|
-
:full_uri => tcell_context.
|
348
|
+
:full_uri => tcell_context.uri,
|
361
349
|
:referrer => tcell_context.referrer,
|
362
350
|
:user_valid => user_valid
|
363
351
|
}
|
@@ -395,11 +383,14 @@ module TCellAgent
|
|
395
383
|
if tcell_context
|
396
384
|
file_access_info = file_access_info.merge(
|
397
385
|
{
|
398
|
-
:full_uri => tcell_context.
|
386
|
+
:full_uri => tcell_context.uri,
|
387
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
399
388
|
:remote_address => tcell_context.remote_address,
|
400
389
|
:route_id => tcell_context.route_id,
|
401
390
|
:session_id => tcell_context.session_id,
|
402
|
-
:user_id => tcell_context.user_id
|
391
|
+
:user_id => tcell_context.user_id,
|
392
|
+
:method => tcell_context.request_method,
|
393
|
+
:request_path => tcell_context.path
|
403
394
|
}
|
404
395
|
)
|
405
396
|
end
|
@@ -471,6 +462,7 @@ module TCellAgent
|
|
471
462
|
:session_id => tcell_context && tcell_context.session_id,
|
472
463
|
:user_id => tcell_context && tcell_context.user_id,
|
473
464
|
:user_agent => tcell_context && tcell_context.user_agent,
|
465
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
474
466
|
:remote_address => tcell_context && tcell_context.remote_address
|
475
467
|
}
|
476
468
|
message_pointer = FFI::MemoryPointer.from_string(
|
@@ -522,7 +514,7 @@ module TCellAgent
|
|
522
514
|
end
|
523
515
|
end
|
524
516
|
|
525
|
-
#
|
517
|
+
# NOTE: for tests
|
526
518
|
def update_policies(policies)
|
527
519
|
return {} unless TCellAgent::Utils::Strings.present?(policies)
|
528
520
|
|