tcell_agent 2.1.1 → 2.4.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/LICENSE +2 -2
- data/bin/tcell_agent +41 -150
- data/lib/tcell_agent.rb +8 -16
- data/lib/tcell_agent/agent.rb +87 -52
- data/lib/tcell_agent/config_initializer.rb +62 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
- data/lib/tcell_agent/instrumentation/lfi.rb +68 -11
- 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/logger.rb +3 -4
- 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/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 -57
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp.rb +48 -52
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- 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 +3 -4
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- 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 +5 -12
- data/lib/tcell_agent/rails/settings_reporter.rb +0 -8
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +52 -32
- data/lib/tcell_agent/rust/{libtcellagent-4.18.0.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/libtcellagent-x64.dll +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.18.0.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.18.0.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +58 -50
- data/lib/tcell_agent/rust/native_library.rb +8 -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 +30 -13
- data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -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 +12 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -93
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +16 -7
- 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/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +46 -4
- 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 +120 -2
- 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 +14 -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/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +9 -1
- data/spec/support/builders.rb +8 -7
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +21 -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
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +44 -27
- data/Rakefile +0 -18
- 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/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 -163
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/lib/tcell_agent/rust/tcellagent-4.18.0.dll +0 -0
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
|
@@ -16,12 +16,4 @@ module TCellAgent
|
|
|
16
16
|
super if defined?(super)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
-
|
|
20
|
-
class MyRailtie < Rails::Railtie
|
|
21
|
-
initializer 'tcell.sensors' do |_app|
|
|
22
|
-
ActiveSupport.on_load :action_controller do
|
|
23
|
-
ActionController::Base.send(:include, TCellAgent::CsrfExceptionReporter)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
19
|
end
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# See the file "LICENSE" for the full license governing this code.
|
|
2
2
|
|
|
3
|
-
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
|
4
|
-
require 'tcell_agent/devise' if defined?(Devise)
|
|
5
|
-
|
|
6
3
|
require 'rails'
|
|
7
4
|
require 'uri'
|
|
8
5
|
require 'tcell_agent/agent'
|
|
@@ -21,7 +18,6 @@ require 'tcell_agent/rails/settings_reporter'
|
|
|
21
18
|
|
|
22
19
|
require 'tcell_agent/instrumentation'
|
|
23
20
|
|
|
24
|
-
require 'tcell_agent/userinfo'
|
|
25
21
|
require 'cgi'
|
|
26
22
|
require 'thread'
|
|
27
23
|
|
|
@@ -84,6 +80,7 @@ module TCellAgent
|
|
|
84
80
|
normalized_column_names[namespaced_column_name] = column_name
|
|
85
81
|
|
|
86
82
|
next unless column_name && (!namespace || namespace == table_name)
|
|
83
|
+
|
|
87
84
|
rules = dlp_policy.get_actions_for_table(
|
|
88
85
|
database_name,
|
|
89
86
|
'*',
|
|
@@ -194,6 +191,7 @@ module TCellAgent
|
|
|
194
191
|
results[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
|
|
195
192
|
column_name_to_rules.each do |column_name, rules|
|
|
196
193
|
next unless rules
|
|
194
|
+
|
|
197
195
|
rules.each do |rule|
|
|
198
196
|
tcell_context.add_response_db_filter(
|
|
199
197
|
record[column_name.to_sym],
|
|
@@ -305,31 +303,29 @@ module TCellAgent
|
|
|
305
303
|
def log_enforce(tcell_context, sanitize_string)
|
|
306
304
|
if TCellAgent.configuration.should_instrument? &&
|
|
307
305
|
TCellAgent.configuration.should_intercept_requests?
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
send_event = true
|
|
321
|
-
end
|
|
322
|
-
m
|
|
323
|
-
end
|
|
324
|
-
if send_event
|
|
325
|
-
TCellAgent.send_event(
|
|
326
|
-
TCellAgent::SensorEvents::DlpEvent.new(
|
|
327
|
-
tcell_context.route_id,
|
|
328
|
-
tcell_context.uri,
|
|
329
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
|
|
330
|
-
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
|
331
|
-
)
|
|
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
|
|
332
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
|
+
)
|
|
333
329
|
end
|
|
334
330
|
end
|
|
335
331
|
end
|
|
@@ -340,32 +336,32 @@ module TCellAgent
|
|
|
340
336
|
def response_body_enforce(tcell_context, sanitize_string)
|
|
341
337
|
if TCellAgent.configuration.should_instrument? &&
|
|
342
338
|
TCellAgent.configuration.should_intercept_requests?
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
end
|
|
357
|
-
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
|
|
358
352
|
end
|
|
353
|
+
# rubocop:enable Lint/DuplicateBranch
|
|
354
|
+
m
|
|
359
355
|
end
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
)
|
|
368
|
-
|
|
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
|
+
)
|
|
369
365
|
end
|
|
370
366
|
end
|
|
371
367
|
|
|
@@ -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
|
|
@@ -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
|
|
@@ -7,7 +7,7 @@ require 'tcell_agent/sensor_events/sensor'
|
|
|
7
7
|
require 'tcell_agent/sensor_events/server_agent'
|
|
8
8
|
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
|
9
9
|
|
|
10
|
-
require 'tcell_agent/userinfo'
|
|
10
|
+
require 'tcell_agent/rails/auth/userinfo'
|
|
11
11
|
require 'cgi'
|
|
12
12
|
|
|
13
13
|
require 'tcell_agent/instrumentation'
|
|
@@ -24,6 +24,7 @@ module TCellAgent
|
|
|
24
24
|
def call(env)
|
|
25
25
|
if TCellAgent.configuration.should_intercept_requests?
|
|
26
26
|
request = Rack::Request.new(env)
|
|
27
|
+
|
|
27
28
|
TCellAgent::Instrumentation.safe_block('Setting session_id & user_id') do
|
|
28
29
|
if request.session
|
|
29
30
|
env[TCellAgent::Instrumentation::TCELL_ID].session_id =
|
|
@@ -41,9 +42,7 @@ module TCellAgent
|
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
response
|
|
45
|
+
@app.call(env)
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
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|
|
|
@@ -2,36 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rails'
|
|
4
4
|
|
|
5
|
-
require 'tcell_agent/rails/routes'
|
|
6
|
-
|
|
7
5
|
require 'tcell_agent/rails/middleware/global_middleware'
|
|
8
6
|
require 'tcell_agent/rails/middleware/body_filter_middleware'
|
|
9
7
|
require 'tcell_agent/rails/middleware/headers_middleware'
|
|
10
8
|
require 'tcell_agent/rails/middleware/context_middleware'
|
|
11
9
|
|
|
10
|
+
require 'tcell_agent/rails/routes'
|
|
12
11
|
require 'tcell_agent/rails/settings_reporter'
|
|
13
12
|
require 'tcell_agent/rails/dlp'
|
|
14
13
|
require 'tcell_agent/rails/csrf_exception'
|
|
15
14
|
|
|
16
|
-
require 'tcell_agent/userinfo'
|
|
17
15
|
require 'cgi'
|
|
18
16
|
require 'thread'
|
|
19
17
|
|
|
20
18
|
module TCellAgent
|
|
21
19
|
class TCellAgentStartupRailtie < Rails::Railtie
|
|
22
|
-
# TCellAgent config can be specified thru
|
|
23
|
-
# Rails initializer's (https://guides.rubyonrails.org/v2.3/configuring.html#using-initializers)
|
|
24
|
-
# so those need to run first since this relies on configuration
|
|
25
|
-
initializer :tcell_instrument_auth_frameworks, :after => :load_config_initializers do |_app|
|
|
26
|
-
next unless TCellAgent.configuration.should_instrument?
|
|
27
|
-
|
|
28
|
-
require 'tcell_agent/devise'
|
|
29
|
-
require 'tcell_agent/rails/auth/devise'
|
|
30
|
-
require 'tcell_agent/authlogic'
|
|
31
|
-
require 'tcell_agent/rails/auth/authlogic'
|
|
32
|
-
require 'tcell_agent/rails/auth/doorkeeper'
|
|
33
|
-
end
|
|
34
|
-
|
|
35
20
|
initializer :tcell_insert_middleware, :before => :build_middleware_stack do |app|
|
|
36
21
|
app.config.middleware.insert_before(0, TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware)
|
|
37
22
|
app.config.middleware.insert_after(0, TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware)
|
|
@@ -39,4 +24,12 @@ module TCellAgent
|
|
|
39
24
|
app.config.middleware.use TCellAgent::Instrumentation::Rails::Middleware::GlobalMiddleware
|
|
40
25
|
end
|
|
41
26
|
end
|
|
27
|
+
|
|
28
|
+
class TCellAgentCSRFRailtie < Rails::Railtie
|
|
29
|
+
initializer 'tcell.sensors' do |_app|
|
|
30
|
+
ActiveSupport.on_load :action_controller do
|
|
31
|
+
ActionController::Base.send(:include, TCellAgent::CsrfExceptionReporter)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
42
35
|
end
|
|
@@ -136,8 +136,7 @@ module TCellAgent
|
|
|
136
136
|
prepend_around_filter :tcell_around_filter_routes
|
|
137
137
|
end
|
|
138
138
|
def tcell_around_filter_routes
|
|
139
|
-
if TCellAgent.configuration.
|
|
140
|
-
TCellAgent.configuration.should_intercept_requests?
|
|
139
|
+
if TCellAgent.configuration.should_intercept_requests?
|
|
141
140
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
|
142
141
|
_match, parameters, route = ::Rails.application.routes.router.recognize(request) { |r, _| r }.first
|
|
143
142
|
|
|
@@ -192,8 +191,7 @@ module TCellAgent
|
|
|
192
191
|
ActionDispatch::Journey::Router.class_eval do
|
|
193
192
|
alias_method :tcell_serve, :serve
|
|
194
193
|
def serve(req)
|
|
195
|
-
if TCellAgent.configuration.
|
|
196
|
-
TCellAgent.configuration.should_intercept_requests?
|
|
194
|
+
if TCellAgent.configuration.should_intercept_requests?
|
|
197
195
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
|
198
196
|
_match, parameters, route = find_routes(req).first
|
|
199
197
|
|
|
@@ -220,8 +218,7 @@ module TCellAgent
|
|
|
220
218
|
def call(env)
|
|
221
219
|
env['PATH_INFO'] = ActionDispatch::Journey::Router::Utils.normalize_path(env['PATH_INFO'])
|
|
222
220
|
|
|
223
|
-
if TCellAgent.configuration.
|
|
224
|
-
TCellAgent.configuration.should_intercept_requests?
|
|
221
|
+
if TCellAgent.configuration.should_intercept_requests?
|
|
225
222
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
|
226
223
|
_match, parameters, route = find_routes(env).first
|
|
227
224
|
|
|
@@ -5,16 +5,11 @@ module TCellAgent
|
|
|
5
5
|
def self.grape_route?(route)
|
|
6
6
|
if defined?(Grape::API)
|
|
7
7
|
begin
|
|
8
|
-
if ::Rails::VERSION::MAJOR == 4 &&
|
|
9
|
-
|
|
10
|
-
route.app < Grape::API
|
|
11
|
-
else
|
|
12
|
-
# does app inherit from Grape::API?
|
|
13
|
-
route.app.app < Grape::API
|
|
14
|
-
end
|
|
8
|
+
return route.app < Grape::API if ::Rails::VERSION::MAJOR == 4 &&
|
|
9
|
+
::Rails::VERSION::MINOR < 2
|
|
15
10
|
|
|
16
|
-
return
|
|
17
|
-
rescue StandardError
|
|
11
|
+
return route.app.app < Grape::API
|
|
12
|
+
rescue StandardError
|
|
18
13
|
# do nothing
|
|
19
14
|
end
|
|
20
15
|
end
|
|
@@ -76,9 +71,7 @@ module TCellAgent
|
|
|
76
71
|
Grape::Endpoint.class_eval do
|
|
77
72
|
alias_method :tcell_call!, :call!
|
|
78
73
|
def call!(env)
|
|
79
|
-
if TCellAgent.configuration.
|
|
80
|
-
TCellAgent.configuration.should_intercept_requests?
|
|
81
|
-
|
|
74
|
+
if TCellAgent.configuration.should_intercept_requests?
|
|
82
75
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
|
83
76
|
tcell_context = env[TCellAgent::Instrumentation::TCELL_ID]
|
|
84
77
|
if tcell_context && tcell_context.grape_mount_endpoint && respond_to?(:routes)
|
|
@@ -6,14 +6,6 @@ require 'tcell_agent/sensor_events/server_agent'
|
|
|
6
6
|
module TCellAgent
|
|
7
7
|
module Instrumentation
|
|
8
8
|
module Rails
|
|
9
|
-
def self.send_framework_info
|
|
10
|
-
TCellAgent.send_event(
|
|
11
|
-
TCellAgent::SensorEvents::ServerAgentAppFrameworkEvent.new(
|
|
12
|
-
'Rails', ::Rails.version
|
|
13
|
-
)
|
|
14
|
-
)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
9
|
def self.send_settings
|
|
18
10
|
TCellAgent::Instrumentation.safe_block('Reporting Rails settings') do
|
|
19
11
|
rails_config = ::Rails.application.config
|
|
@@ -31,7 +31,6 @@ module TCellAgent
|
|
|
31
31
|
TCellAgent::Instrumentation.safe_block('Running AppSensor deferred due to streaming') do
|
|
32
32
|
if @meta_data
|
|
33
33
|
@meta_data.response_content_bytes_len = @content_length
|
|
34
|
-
|
|
35
34
|
appfirewall_policy = TCellAgent.policy(TCellAgent::PolicyTypes::APPSENSOR)
|
|
36
35
|
appfirewall_policy.check_appfirewall_injections(@meta_data)
|
|
37
36
|
end
|
|
@@ -54,18 +53,16 @@ module TCellAgent
|
|
|
54
53
|
@body.respond_to?(method_name, include_all)
|
|
55
54
|
end
|
|
56
55
|
|
|
57
|
-
def method_missing(method_name, *args, &block)
|
|
56
|
+
def method_missing(method_name, *args, &block)
|
|
58
57
|
@body.__send__(method_name, *args, &block)
|
|
59
58
|
end
|
|
60
59
|
|
|
61
60
|
def process_body(body)
|
|
62
61
|
TCellAgent::Instrumentation.safe_block('Processing tcell body proxy body') do
|
|
63
62
|
chunked_response_match = nil
|
|
64
|
-
if body.class.name == 'String'
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
@content_length += chunked_response_match.to_i(16)
|
|
68
|
-
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)
|
|
69
66
|
end
|
|
70
67
|
|
|
71
68
|
new_body = body
|