tcell_agent 0.2.29 → 0.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/Readme.txt +7 -0
- data/bin/tcell_agent +9 -0
- data/lib/tcell_agent/agent/policy_manager.rb +3 -0
- data/lib/tcell_agent/agent/policy_types.rb +4 -1
- data/lib/tcell_agent/appsensor/injections_matcher.rb +20 -0
- data/lib/tcell_agent/appsensor/injections_reporter.rb +15 -56
- data/lib/tcell_agent/appsensor/meta_data.rb +56 -2
- data/lib/tcell_agent/appsensor/rules/baserules.json +371 -138
- data/lib/tcell_agent/cmdi.rb +113 -0
- data/lib/tcell_agent/config/unknown_options.rb +2 -0
- data/lib/tcell_agent/configuration.rb +30 -16
- data/lib/tcell_agent/hooks/login_fraud.rb +79 -0
- data/lib/tcell_agent/instrumentation.rb +6 -11
- data/lib/tcell_agent/patches/meta_data.rb +14 -11
- data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +5 -9
- data/lib/tcell_agent/policies/appsensor_policy.rb +22 -206
- data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -2
- data/lib/tcell_agent/policies/command_injection_policy.rb +196 -0
- data/lib/tcell_agent/policies/content_security_policy.rb +3 -2
- data/lib/tcell_agent/policies/dataloss_policy.rb +3 -1
- data/lib/tcell_agent/policies/honeytokens_policy.rb +3 -1
- data/lib/tcell_agent/policies/http_redirect_policy.rb +51 -37
- data/lib/tcell_agent/policies/http_tx_policy.rb +5 -1
- data/lib/tcell_agent/policies/login_fraud_policy.rb +6 -1
- data/lib/tcell_agent/policies/patches_policy.rb +3 -1
- data/lib/tcell_agent/policies/policy.rb +10 -0
- data/lib/tcell_agent/policies/secure_headers_policy.rb +5 -2
- data/lib/tcell_agent/rails/auth/devise.rb +12 -23
- data/lib/tcell_agent/rails/csrf_exception.rb +1 -1
- data/lib/tcell_agent/rails/dlp.rb +50 -54
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +0 -1
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +0 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +7 -10
- data/lib/tcell_agent/rails/on_start.rb +0 -1
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -4
- data/lib/tcell_agent/rails.rb +0 -2
- data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
- data/lib/tcell_agent/rust/libtcellagent-0.6.1.so +0 -0
- data/lib/tcell_agent/rust/models.rb +61 -0
- data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
- data/lib/tcell_agent/rust/whisperer.rb +112 -0
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +25 -21
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +31 -24
- data/lib/tcell_agent/sensor_events/command_injection.rb +58 -0
- data/lib/tcell_agent/sensor_events/discovery.rb +1 -1
- data/lib/tcell_agent/sensor_events/login_fraud.rb +3 -13
- data/lib/tcell_agent/sensor_events/sensor.rb +81 -77
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +8 -0
- data/lib/tcell_agent/start_background_thread.rb +12 -3
- data/lib/tcell_agent/utils/io.rb +4 -1
- data/lib/tcell_agent/utils/params.rb +1 -0
- data/lib/tcell_agent/version.rb +1 -1
- data/lib/tcell_agent.rb +0 -1
- data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +27 -9
- data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +143 -193
- data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +67 -0
- data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -10
- data/spec/lib/tcell_agent/cmdi_spec.rb +748 -0
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +8 -0
- data/spec/lib/tcell_agent/configuration_spec.rb +138 -6
- data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +357 -0
- data/spec/lib/tcell_agent/patches/block_rule_spec.rb +70 -87
- data/spec/lib/tcell_agent/patches_spec.rb +9 -4
- data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +186 -9
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +309 -484
- data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +736 -0
- data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +222 -41
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +56 -32
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +161 -85
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +40 -72
- data/spec/lib/tcell_agent/rust/whisperer_spec.rb +267 -0
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +20 -15
- data/spec/spec_helper.rb +0 -9
- data/tcell_agent.gemspec +8 -3
- metadata +40 -39
- data/lib/tcell_agent/appsensor/sensor.rb +0 -52
- data/lib/tcell_agent/policies/appsensor/database_sensor.rb +0 -56
- data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +0 -59
- data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +0 -150
- data/lib/tcell_agent/policies/appsensor/request_size_sensor.rb +0 -25
- data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +0 -73
- data/lib/tcell_agent/policies/appsensor/response_size_sensor.rb +0 -25
- data/lib/tcell_agent/policies/appsensor/size_sensor.rb +0 -71
- data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +0 -47
- data/lib/tcell_agent/rails/auth/hooks.rb +0 -79
- data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +0 -22
- data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +0 -165
- data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +0 -429
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_apply_spec.rb +0 -466
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_from_json_spec.rb +0 -890
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_log_spec.rb +0 -417
- data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +0 -236
- data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +0 -297
- data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +0 -241
- data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +0 -172
- data/spec/lib/tcell_agent/rails/auth/hooks_spec.rb +0 -246
- data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +0 -25
- data/spec/support/resources/baserules.json +0 -155
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'tcell_agent/agent/policy_types'
|
|
2
|
+
require 'tcell_agent/utils/strings'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module TCellAgent
|
|
6
|
+
module Cmdi
|
|
7
|
+
def self.block_command?(cmd)
|
|
8
|
+
TCellAgent::Instrumentation.safe_block("Checking Command Injection Policy") do
|
|
9
|
+
if TCellAgent::Utils::Strings.present?(cmd)
|
|
10
|
+
command_injection_policy = TCellAgent.policy(TCellAgent::PolicyTypes::CommandInjection)
|
|
11
|
+
if command_injection_policy && command_injection_policy.enabled
|
|
12
|
+
request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, {})
|
|
13
|
+
tcell_context = request_env[TCellAgent::Instrumentation::TCELL_ID]
|
|
14
|
+
return command_injection_policy.block?(cmd, tcell_context)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
return false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.parse_command(*args)
|
|
23
|
+
cmd = ""
|
|
24
|
+
|
|
25
|
+
TCellAgent::Instrumentation.safe_block("CMDI Parsing *args") do
|
|
26
|
+
if args.size > 0
|
|
27
|
+
args_copy = Array.new(args)
|
|
28
|
+
args_copy.shift if args_copy.first.is_a?(Hash)
|
|
29
|
+
args_copy.pop if args_copy.last.is_a?(Hash)
|
|
30
|
+
|
|
31
|
+
if args_copy.first.is_a?(Array)
|
|
32
|
+
cmd_n_argv0 = args_copy.shift
|
|
33
|
+
args_copy.unshift(cmd_n_argv0.first)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
cmd = args_copy.join(" ")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
cmd
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module Kernel
|
|
46
|
+
alias_method :tcell_original_backtick, :`
|
|
47
|
+
def `(cmd)
|
|
48
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
|
49
|
+
raise Errno::ENOENT.new("tCell.io Agent: Command not allowed by policy: #{cmd}")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
tcell_original_backtick(cmd)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
alias_method :tcell_original_exec, :exec
|
|
56
|
+
def exec(*args)
|
|
57
|
+
cmd = TCellAgent::Cmdi.parse_command(*args)
|
|
58
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
|
59
|
+
raise Errno::ENOENT.new("tCell.io Agent: Command not allowed by policy: #{cmd}")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
tcell_original_exec(*args)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias_method :tcell_original_system, :system
|
|
66
|
+
def system(*args)
|
|
67
|
+
cmd = TCellAgent::Cmdi.parse_command(*args)
|
|
68
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
|
69
|
+
raise Errno::ENOENT.new("tCell.io Agent: Command not allowed by policy: #{cmd}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
tcell_original_system(*args)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
alias_method :tcell_original_spawn, :spawn
|
|
76
|
+
def spawn(*args)
|
|
77
|
+
cmd = TCellAgent::Cmdi.parse_command(*args)
|
|
78
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
|
79
|
+
raise Errno::ENOENT.new("tCell.io Agent: Command not allowed by policy: #{cmd}")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
return tcell_original_spawn(*args)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class IO
|
|
87
|
+
class << self
|
|
88
|
+
alias_method :tcell_original_popen, :popen
|
|
89
|
+
def popen(*args)
|
|
90
|
+
if args.size > 0
|
|
91
|
+
cmd = ""
|
|
92
|
+
|
|
93
|
+
TCellAgent::Instrumentation.safe_block("CMDI Parsing popen *args") do
|
|
94
|
+
args_copy = Array.new(args)
|
|
95
|
+
args_copy.shift if args_copy.first.is_a?(Hash)
|
|
96
|
+
args_copy.pop if args_copy.last.is_a?(Hash)
|
|
97
|
+
|
|
98
|
+
if args_copy.first.is_a?(String)
|
|
99
|
+
cmd = args_copy.shift
|
|
100
|
+
else
|
|
101
|
+
cmd = TCellAgent::Cmdi.parse_command(*args_copy.shift)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if TCellAgent::Cmdi.block_command?(cmd)
|
|
106
|
+
raise Errno::ENOENT.new("tCell.io Agent: Command not allowed by policy: #{cmd}")
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return tcell_original_popen(*args)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -21,6 +21,7 @@ module TCellAgent
|
|
|
21
21
|
"TCELL_AGENT_CONFIG",
|
|
22
22
|
"TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS",
|
|
23
23
|
"TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS",
|
|
24
|
+
"TCELL_AGENT_ALLOW_PAYLOADS",
|
|
24
25
|
"TCELL_AGENT_HOME_OWNER"])
|
|
25
26
|
|
|
26
27
|
ENV.keys.each do |environment_key|
|
|
@@ -64,6 +65,7 @@ module TCellAgent
|
|
|
64
65
|
"event_batch_size_limit",
|
|
65
66
|
"allow_unencrypted_appsensor_payloads",
|
|
66
67
|
"allow_unencrypted_appfirewall_payloads",
|
|
68
|
+
"allow_payloads",
|
|
67
69
|
"reverse_proxy",
|
|
68
70
|
"reverse_proxy_ip_address_header",
|
|
69
71
|
"demomode",
|
|
@@ -36,8 +36,6 @@ module TCellAgent
|
|
|
36
36
|
:js_agent_api_base_url,
|
|
37
37
|
:js_agent_url,
|
|
38
38
|
:startup_js_agent_url,
|
|
39
|
-
:raise_exceptions,
|
|
40
|
-
:allow_unencrypted_appfirewall_payloads,
|
|
41
39
|
:config_filename,
|
|
42
40
|
:agent_log_dir,
|
|
43
41
|
:max_data_ex_db_records_per_request,
|
|
@@ -48,7 +46,8 @@ module TCellAgent
|
|
|
48
46
|
:log_file_name,
|
|
49
47
|
:log_tag,
|
|
50
48
|
:max_csp_header_bytes,
|
|
51
|
-
:demomode
|
|
49
|
+
:demomode,
|
|
50
|
+
:allow_payloads
|
|
52
51
|
|
|
53
52
|
attr_accessor :disable_all,
|
|
54
53
|
:enabled,
|
|
@@ -145,12 +144,10 @@ module TCellAgent
|
|
|
145
144
|
@event_batch_size_limit = 50
|
|
146
145
|
@event_time_limit_seconds = 15
|
|
147
146
|
|
|
148
|
-
@raise_exceptions = false
|
|
149
|
-
|
|
150
147
|
@max_data_ex_db_records_per_request = 1000
|
|
151
148
|
@reverse_proxy = true
|
|
152
149
|
@reverse_proxy_ip_address_header = nil
|
|
153
|
-
@
|
|
150
|
+
@allow_payloads = true
|
|
154
151
|
|
|
155
152
|
@max_csp_header_bytes = nil
|
|
156
153
|
|
|
@@ -158,14 +155,21 @@ module TCellAgent
|
|
|
158
155
|
read_config_from_file(@config_filename)
|
|
159
156
|
|
|
160
157
|
if ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"]
|
|
161
|
-
puts "tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS is deprecated
|
|
158
|
+
puts "tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS is deprecated and will be removed in a future release. Please switch to TCELL_AGENT_ALLOW_PAYLOADS."
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS"])
|
|
162
|
+
puts "tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS is deprecated and will be removed in a future release. Please switch to TCELL_AGENT_ALLOW_PAYLOADS."
|
|
162
163
|
end
|
|
163
164
|
|
|
164
165
|
if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"] != nil)
|
|
165
|
-
@
|
|
166
|
+
@allow_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"])
|
|
166
167
|
end
|
|
167
168
|
if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS"] != nil)
|
|
168
|
-
@
|
|
169
|
+
@allow_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS"])
|
|
170
|
+
end
|
|
171
|
+
if (ENV["TCELL_AGENT_ALLOW_PAYLOADS"] != nil)
|
|
172
|
+
@allow_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_PAYLOADS"])
|
|
169
173
|
end
|
|
170
174
|
|
|
171
175
|
@tcell_api_url ||= "https://api.tcell.io/api/v1"
|
|
@@ -213,8 +217,6 @@ module TCellAgent
|
|
|
213
217
|
@event_batch_size_limit = 2
|
|
214
218
|
@event_time_limit_seconds = 5
|
|
215
219
|
end
|
|
216
|
-
|
|
217
|
-
@raise_exceptions = [true, "true", "yes", "1"].include?(ENV["TCELL_RAISE_EXCEPTIONS"])
|
|
218
220
|
end
|
|
219
221
|
|
|
220
222
|
def read_config_from_file(filename)
|
|
@@ -265,15 +267,17 @@ module TCellAgent
|
|
|
265
267
|
|
|
266
268
|
@max_csp_header_bytes = app_data.fetch("max_csp_header_bytes", @max_csp_header_bytes)
|
|
267
269
|
|
|
268
|
-
@
|
|
269
|
-
app_data.fetch('allow_unencrypted_appsensor_payloads', @
|
|
270
|
-
@
|
|
271
|
-
app_data.fetch('allow_unencrypted_appfirewall_payloads', @
|
|
270
|
+
@allow_payloads =
|
|
271
|
+
app_data.fetch('allow_unencrypted_appsensor_payloads', @allow_payloads)
|
|
272
|
+
@allow_payloads =
|
|
273
|
+
app_data.fetch('allow_unencrypted_appfirewall_payloads', @allow_payloads)
|
|
274
|
+
@allow_payloads =
|
|
275
|
+
app_data.fetch('allow_payloads', @allow_payloads)
|
|
272
276
|
|
|
273
277
|
data_exposure = app_data.fetch('data_exposure', {})
|
|
274
278
|
@max_data_ex_db_records_per_request = data_exposure.fetch('max_data_ex_db_records_per_request', @max_data_ex_db_records_per_request)
|
|
275
279
|
|
|
276
|
-
@enabled_instrumentations = app_data.fetch('enabled_instrumentations',
|
|
280
|
+
@enabled_instrumentations = app_data.fetch('enabled_instrumentations', @enabled_instrumentations)
|
|
277
281
|
|
|
278
282
|
@reverse_proxy = app_data.fetch('reverse_proxy', @reverse_proxy)
|
|
279
283
|
@reverse_proxy_ip_address_header = app_data.fetch('reverse_proxy_ip_address_header', @reverse_proxy_ip_address_header)
|
|
@@ -315,6 +319,16 @@ module TCellAgent
|
|
|
315
319
|
end # filename exist
|
|
316
320
|
end #def read
|
|
317
321
|
|
|
322
|
+
# old value could be set via initializers, this makes sure those initializers still work
|
|
323
|
+
# properly
|
|
324
|
+
def allow_unencrypted_appfirewall_payloads=(val)
|
|
325
|
+
@allow_payloads = val
|
|
326
|
+
end
|
|
327
|
+
# keep this around in case the value was read as well
|
|
328
|
+
def allow_unencrypted_appfirewall_payloads
|
|
329
|
+
@allow_payloads
|
|
330
|
+
end
|
|
331
|
+
|
|
318
332
|
def log_filename
|
|
319
333
|
@agent_log_dir ||= File.join(@agent_home_dir, "logs")
|
|
320
334
|
File.join(@agent_log_dir, @log_file_name)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'tcell_agent/agent'
|
|
2
|
+
require 'tcell_agent/sensor_events/login_fraud'
|
|
3
|
+
|
|
4
|
+
module TCellAgent
|
|
5
|
+
module Hooks
|
|
6
|
+
module LoginFraud
|
|
7
|
+
|
|
8
|
+
def self.report_login_event(status, env_or_header_keys, tcell_data, user_id)
|
|
9
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
|
10
|
+
login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
|
|
11
|
+
|
|
12
|
+
if (login_fraud_policy && login_fraud_policy.enabled)
|
|
13
|
+
if tcell_data
|
|
14
|
+
if ![TCellAgent::Hooks::V1::Login::LOGIN_FAILURE, TCellAgent::Hooks::V1::Login::LOGIN_SUCCESS].include?(status)
|
|
15
|
+
TCellAgent.logger.error("Unkown login status: #{status}")
|
|
16
|
+
elsif (status == TCellAgent::Hooks::V1::Login::LOGIN_FAILURE) && login_fraud_policy.login_failed_enabled
|
|
17
|
+
TCellAgent.send_event(
|
|
18
|
+
TCellAgent::SensorEvents::LoginFailure.new(env_or_header_keys, tcell_data, user_id)
|
|
19
|
+
)
|
|
20
|
+
elsif (status == TCellAgent::Hooks::V1::Login::LOGIN_SUCCESS) && login_fraud_policy.login_success_enabled
|
|
21
|
+
TCellAgent.send_event(
|
|
22
|
+
TCellAgent::SensorEvents::LoginSuccess.new(env_or_header_keys, tcell_data, user_id)
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if defined?(TCellAgent::Hooks::V1::Frameworks::Rails::Login)
|
|
35
|
+
TCellAgent::Hooks::V1::Frameworks::Rails::Login.module_eval do
|
|
36
|
+
class << self
|
|
37
|
+
|
|
38
|
+
alias_method :tcell_register_login_event, :register_login_event
|
|
39
|
+
def register_login_event(status, rails_request, user_id, user_valid=nil)
|
|
40
|
+
TCellAgent::Instrumentation.safe_block("Rails Auth Hooks") do
|
|
41
|
+
tcell_data = rails_request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
42
|
+
TCellAgent::Hooks::LoginFraud.report_login_event(status, rails_request.env, tcell_data, user_id)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if defined?(TCellAgent::Hooks::V1::Login)
|
|
51
|
+
TCellAgent::Hooks::V1::Login.module_eval do
|
|
52
|
+
class << self
|
|
53
|
+
|
|
54
|
+
alias_method :tcell_register_login_event, :register_login_event
|
|
55
|
+
def register_login_event(
|
|
56
|
+
status,
|
|
57
|
+
session_id,
|
|
58
|
+
user_agent,
|
|
59
|
+
referrer,
|
|
60
|
+
remote_address,
|
|
61
|
+
header_keys,
|
|
62
|
+
user_id,
|
|
63
|
+
document_uri,
|
|
64
|
+
user_valid=nil)
|
|
65
|
+
TCellAgent::Instrumentation.safe_block("Login Auth Hooks") do
|
|
66
|
+
tcell_data = TCellAgent::Instrumentation::TCellData.new
|
|
67
|
+
tcell_data.user_agent = user_agent
|
|
68
|
+
tcell_data.referrer = referrer
|
|
69
|
+
tcell_data.ip_address = remote_address
|
|
70
|
+
tcell_data.path = document_uri
|
|
71
|
+
tcell_data.hmac_session_id = TCellAgent::SensorEvents::Util.hmac(session_id)
|
|
72
|
+
|
|
73
|
+
TCellAgent::Hooks::LoginFraud.report_login_event(status, header_keys, tcell_data, user_id)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -61,7 +61,8 @@ module TCellAgent
|
|
|
61
61
|
class TCellData
|
|
62
62
|
attr_accessor :transaction_id, :session_id, :hmac_session_id, :user_id, :route_id,
|
|
63
63
|
:uri, :context_filters_by_term, :database_filters, :ip_address, :user_agent, :request_method,
|
|
64
|
-
:path_parameters, :ip_blocking_triggered, :grape_mount_endpoint, :referrer, :path
|
|
64
|
+
:path_parameters, :ip_blocking_triggered, :grape_mount_endpoint, :referrer, :path,
|
|
65
|
+
:csrf_exception_name, :sql_exceptions, :database_result_sizes
|
|
65
66
|
|
|
66
67
|
def self.filterx(sanitize_string, event_flag, replace_flag, term)
|
|
67
68
|
send_event = false
|
|
@@ -80,6 +81,8 @@ module TCellAgent
|
|
|
80
81
|
def initialize
|
|
81
82
|
@ip_blocking_triggered = false
|
|
82
83
|
@context_filters_by_term = Hash.new{|h,k| h[k] = Set.new}
|
|
84
|
+
@sql_exceptions = []
|
|
85
|
+
@database_result_sizes = []
|
|
83
86
|
end
|
|
84
87
|
def is_valid_term?(term)
|
|
85
88
|
if term != nil && term != '' and term.to_s.length >= 5
|
|
@@ -222,13 +225,8 @@ module TCellAgent
|
|
|
222
225
|
block.call()
|
|
223
226
|
|
|
224
227
|
rescue Exception => ex
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
else
|
|
229
|
-
TCellAgent.logger.debug "Exception in safe_block #{message}: #{ex.class} happened, message is #{ex.message}"
|
|
230
|
-
TCellAgent.logger.debug(ex.backtrace)
|
|
231
|
-
end
|
|
228
|
+
TCellAgent.logger.debug "Exception in safe_block #{message}: #{ex.class} happened, message is #{ex.message}"
|
|
229
|
+
TCellAgent.logger.debug(ex.backtrace)
|
|
232
230
|
end
|
|
233
231
|
end
|
|
234
232
|
|
|
@@ -236,9 +234,6 @@ module TCellAgent
|
|
|
236
234
|
begin
|
|
237
235
|
block.call()
|
|
238
236
|
rescue Exception => e
|
|
239
|
-
if TCellAgent.configuration.raise_exceptions
|
|
240
|
-
raise e
|
|
241
|
-
end
|
|
242
237
|
end
|
|
243
238
|
end
|
|
244
239
|
end
|
|
@@ -12,23 +12,27 @@ module TCellAgent
|
|
|
12
12
|
|
|
13
13
|
class << self
|
|
14
14
|
def build(request)
|
|
15
|
-
|
|
15
|
+
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
16
|
+
meta_event = MetaData.new(
|
|
17
|
+
request.request_method,
|
|
18
|
+
TCellAgent::Utils::Rails.better_ip(request),
|
|
19
|
+
tcell_context.route_id,
|
|
20
|
+
tcell_context.hmac_session_id,
|
|
21
|
+
tcell_context.user_id,
|
|
22
|
+
tcell_context.transaction_id
|
|
23
|
+
)
|
|
16
24
|
|
|
17
|
-
meta_event.remote_address = TCellAgent::Utils::Rails.better_ip(request)
|
|
18
|
-
meta_event.method = request.request_method
|
|
19
25
|
meta_event.path = request.path
|
|
20
26
|
meta_event.user_agent = request.env['HTTP_USER_AGENT']
|
|
27
|
+
|
|
21
28
|
meta_event.get_dict = request.GET
|
|
22
29
|
meta_event.cookie_dict = request.cookies
|
|
30
|
+
meta_event.set_headers_dict(request.env)
|
|
23
31
|
|
|
24
32
|
meta_event.post_dict = request.POST
|
|
25
33
|
|
|
26
34
|
meta_event.path_parameters = request.env[TCellAgent::Instrumentation::TCELL_ID].path_parameters
|
|
27
35
|
|
|
28
|
-
meta_event.route_id = request.env[TCellAgent::Instrumentation::TCELL_ID].route_id
|
|
29
|
-
meta_event.transaction_id = request.env[TCellAgent::Instrumentation::TCELL_ID].transaction_id
|
|
30
|
-
meta_event.session_id = request.env[TCellAgent::Instrumentation::TCELL_ID].hmac_session_id
|
|
31
|
-
meta_event.user_id = request.env[TCellAgent::Instrumentation::TCELL_ID].user_id
|
|
32
36
|
|
|
33
37
|
# Positions strio to the beginning of input, resetting lineno to zero.
|
|
34
38
|
# rails 4.1 seems to read the stringIO directly and so body.gets is empty
|
|
@@ -46,11 +50,10 @@ module TCellAgent
|
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
|
|
49
|
-
attr_accessor :
|
|
50
|
-
:request_content_bytes_len, :user_agent
|
|
53
|
+
attr_accessor :path, :request_content_bytes_len, :user_agent
|
|
51
54
|
|
|
52
|
-
def initialize
|
|
53
|
-
super
|
|
55
|
+
def initialize(method, remote_address, route_id, session_id, user_id, transaction_id)
|
|
56
|
+
super(method, remote_address, route_id, session_id, user_id, transaction_id)
|
|
54
57
|
|
|
55
58
|
@request_content_bytes_len = 0
|
|
56
59
|
@user_agent = nil
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'tcell_agent/utils/params'
|
|
2
|
-
require 'tcell_agent/appsensor/sensor'
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
module TCellAgent
|
|
@@ -25,14 +24,7 @@ module TCellAgent
|
|
|
25
24
|
JSON_PARAM = TCellAgent::Utils::Params::JSON_PARAM
|
|
26
25
|
COOKIE_PARAM = TCellAgent::Utils::Params::COOKIE_PARAM
|
|
27
26
|
URI_PARAM = TCellAgent::Utils::Params::URI_PARAM
|
|
28
|
-
|
|
29
|
-
PARAM_TYPE_TO_L = {
|
|
30
|
-
GET_PARAM => 'query',
|
|
31
|
-
POST_PARAM => 'body',
|
|
32
|
-
JSON_PARAM => 'body',
|
|
33
|
-
URI_PARAM => 'uri',
|
|
34
|
-
COOKIE_PARAM => 'cookie'
|
|
35
|
-
}
|
|
27
|
+
HEADER_PARAM = TCellAgent::Utils::Params::HEADER_PARAM
|
|
36
28
|
|
|
37
29
|
attr_accessor :enabled, :detection_point, :exclude_headers, :exclude_forms,
|
|
38
30
|
:exclude_cookies, :exclusions, :active_pattern_ids, :v1_compatability_enabled,
|
|
@@ -99,6 +91,10 @@ module TCellAgent
|
|
|
99
91
|
return false
|
|
100
92
|
end
|
|
101
93
|
|
|
94
|
+
if @exclude_headers && HEADER_PARAM == type_of_param
|
|
95
|
+
return false
|
|
96
|
+
end
|
|
97
|
+
|
|
102
98
|
vuln_results = find_vulnerability(param_name, param_value)
|
|
103
99
|
|
|
104
100
|
if vuln_results
|