tcell_agent 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/tcell_agent +22 -0
- data/lib/tcell_agent/agent/event_processor.rb +7 -0
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +29 -29
- data/lib/tcell_agent/agent/policy_manager.rb +2 -1
- data/lib/tcell_agent/agent/route_manager.rb +35 -15
- data/lib/tcell_agent/configuration.rb +42 -2
- data/lib/tcell_agent/instrumentation.rb +4 -1
- data/lib/tcell_agent/logger.rb +1 -1
- data/lib/tcell_agent/rails.rb +12 -18
- data/lib/tcell_agent/rails/auth/authlogic.rb +2 -2
- data/lib/tcell_agent/rails/auth/devise.rb +1 -1
- data/lib/tcell_agent/rails/dlp.rb +133 -123
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +2 -1
- data/lib/tcell_agent/rails/on_start.rb +67 -69
- data/lib/tcell_agent/rails/routes.rb +91 -86
- data/lib/tcell_agent/rails/settings_reporter.rb +10 -0
- data/lib/tcell_agent/routes/table.rb +2 -0
- data/lib/tcell_agent/sensor_events/server_agent.rb +10 -0
- data/lib/tcell_agent/servers/thin.rb +1 -0
- data/lib/tcell_agent/servers/webrick.rb +0 -1
- data/lib/tcell_agent/start_background_thread.rb +44 -45
- data/lib/tcell_agent/system_info.rb +10 -0
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +99 -0
- data/spec/lib/tcell_agent/api/api_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation_spec.rb +176 -176
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +32 -32
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +63 -63
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +93 -93
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +222 -222
- data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +17 -17
- data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +57 -57
- data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +17 -17
- data/spec/lib/tcell_agent/policies/login_policy_spec.rb +3 -3
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +59 -59
- data/spec/lib/tcell_agent/rails/logger_spec.rb +148 -0
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +7 -7
- data/spec/lib/tcell_agent/rails_spec.rb +2 -2
- data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +9 -9
- data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +20 -20
- data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +52 -52
- data/spec/lib/tcell_agent_spec.rb +17 -17
- data/spec/spec_helper.rb +1 -0
- data/spec/support/resources/normal_config.json +5 -5
- data/tcell_agent.gemspec +4 -4
- metadata +31 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38bd348af6afc0394baa2b21028297f52c8bd869
|
4
|
+
data.tar.gz: 3a0cd72fe8d1c792a13a4a73492da78d2b773b13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd5eb354fe88c5822692bb5e74194d56f67645d92910e14f24d07d27c128735b5750d84a567e7a9dd4a2558c5af1b71f41ec92c47c9db1e5f4e1efc6c731d7f2
|
7
|
+
data.tar.gz: c570a523bdb36c1aebe4fcf457ececc053e3395cb56bc7f3fbc59d8100897fcda06a8a4fe0447f62acdee239ca4fba601c93892b92ea3d4a1a7c9f952915c9cb
|
data/bin/tcell_agent
CHANGED
@@ -14,6 +14,8 @@ Commonly used command are:
|
|
14
14
|
setup : Setup new config file
|
15
15
|
test : Run diagnostics classes and config
|
16
16
|
loglevel : Set the loglevel of the tcell agent
|
17
|
+
enable : Enable the agent
|
18
|
+
disable : Disable the agent
|
17
19
|
|
18
20
|
See 'tcell_agent COMMAND --help' for more information on a specific command.
|
19
21
|
|
@@ -69,6 +71,12 @@ subcommands = {
|
|
69
71
|
options[:off] = v
|
70
72
|
end
|
71
73
|
end,
|
74
|
+
'enable' => OptionParser.new do |opts|
|
75
|
+
opts.banner = "Usage: enable"
|
76
|
+
end,
|
77
|
+
'disable' => OptionParser.new do |opts|
|
78
|
+
opts.banner = "Usage: disable"
|
79
|
+
end,
|
72
80
|
'test' => OptionParser.new do |opts|
|
73
81
|
opts.banner = "Usage: test"
|
74
82
|
#opts.on("-q", "--[no-]quiet", "quietly run ") do |v|
|
@@ -165,6 +173,20 @@ elsif (command == 'preload')
|
|
165
173
|
File.open(CONFIG_FILE, 'w'){|f| f.puts JSON.pretty_generate(config_hash) }
|
166
174
|
puts "done."
|
167
175
|
|
176
|
+
elsif (command == 'enable')
|
177
|
+
file = File.read(CONFIG_FILE)
|
178
|
+
config_hash = JSON.parse(file)
|
179
|
+
config_hash["applications"][0].delete("enabled")
|
180
|
+
File.open(CONFIG_FILE, 'w'){|f| f.puts JSON.pretty_generate(config_hash) }
|
181
|
+
puts "Enabled, you will need to restart the server."
|
182
|
+
|
183
|
+
elsif (command == 'disable')
|
184
|
+
file = File.read(CONFIG_FILE)
|
185
|
+
config_hash = JSON.parse(file)
|
186
|
+
config_hash["applications"][0]["enabled"] = false
|
187
|
+
File.open(CONFIG_FILE, 'w'){|f| f.puts JSON.pretty_generate(config_hash) }
|
188
|
+
puts "Disabled, you will need to restart the server."
|
189
|
+
|
168
190
|
elsif (command == 'demomode')
|
169
191
|
file = File.read(CONFIG_FILE)
|
170
192
|
config_hash = JSON.parse(file)
|
@@ -34,6 +34,7 @@ module TCellAgent
|
|
34
34
|
|
35
35
|
def ensure_event_processor_running
|
36
36
|
return if event_processor_running?
|
37
|
+
return if TCellAgent.configuration.should_start_event_manager? == false
|
37
38
|
@worker_mutex.synchronize do
|
38
39
|
return if event_processor_running?
|
39
40
|
if self.is_parent_process? == false
|
@@ -51,6 +52,8 @@ module TCellAgent
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def start_event_processor(send_empties=true)
|
55
|
+
return if TCellAgent.configuration.should_start_event_manager? == false
|
56
|
+
|
54
57
|
if TCellAgent::Agent.is_parent_process? == false
|
55
58
|
return
|
56
59
|
end
|
@@ -245,6 +248,7 @@ module TCellAgent
|
|
245
248
|
end
|
246
249
|
|
247
250
|
def start_metrics_event_thread
|
251
|
+
return if TCellAgent.configuration.should_consume_event? == false
|
248
252
|
@metrics_event_thread = Thread.new do
|
249
253
|
begin
|
250
254
|
loop do
|
@@ -264,6 +268,7 @@ module TCellAgent
|
|
264
268
|
end
|
265
269
|
|
266
270
|
def _queue_metric(event)
|
271
|
+
return if TCellAgent.configuration.should_consume_event? == false
|
267
272
|
begin
|
268
273
|
self.ensure_metrics_event_thread_running
|
269
274
|
if (@metrics_event_queue.length() > 100)
|
@@ -277,6 +282,7 @@ module TCellAgent
|
|
277
282
|
end
|
278
283
|
|
279
284
|
def queueSensorEvent(event)
|
285
|
+
return if TCellAgent.configuration.should_consume_event? == false
|
280
286
|
begin
|
281
287
|
if TCellAgent::Agent.is_parent_process? == false
|
282
288
|
self.queue_forked_event(event)
|
@@ -299,6 +305,7 @@ module TCellAgent
|
|
299
305
|
end
|
300
306
|
|
301
307
|
def increment_session_info(hmac_session_id, user_id, ip_address, user_agent)
|
308
|
+
|
302
309
|
TCellAgent::Instrumentation.safe_block("Incrementing session info") do
|
303
310
|
|
304
311
|
if TCellAgent::Agent.is_parent_process? == false
|
@@ -17,9 +17,9 @@ module TCellAgent
|
|
17
17
|
@writep.set_encoding(::Encoding::ASCII_8BIT)
|
18
18
|
end
|
19
19
|
if is_parent?
|
20
|
-
|
20
|
+
self.start_listener(&block)
|
21
21
|
end
|
22
|
-
rescue Exception=>init_exception
|
22
|
+
rescue Exception => init_exception
|
23
23
|
TCellAgent.logger.error("Could not start listener for pipe to forks")
|
24
24
|
TCellAgent.logger.error(init_exception.message)
|
25
25
|
TCellAgent.logger.debug(init_exception.backtrace)
|
@@ -30,38 +30,38 @@ module TCellAgent
|
|
30
30
|
end
|
31
31
|
def start_listener(&block)
|
32
32
|
Thread.new {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
33
|
+
while true do
|
34
|
+
begin
|
35
|
+
packed_bytes = @readp.read(4)
|
36
|
+
event_length = packed_bytes.unpack("L>").first
|
37
|
+
packed_event = @readp.read(event_length)
|
38
|
+
event = Marshal.load(packed_event)
|
39
|
+
if block
|
40
|
+
block.call(event)
|
41
|
+
end
|
42
|
+
rescue Exception=>block_exception
|
43
|
+
TCellAgent.logger.error("Could not decode block")
|
44
|
+
TCellAgent.logger.error(block_exception.message)
|
45
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
46
|
+
sleep 0.5
|
48
47
|
end
|
48
|
+
end
|
49
49
|
}
|
50
50
|
end
|
51
51
|
def send_to_parent(event)
|
52
52
|
if is_parent?
|
53
|
-
|
54
|
-
|
53
|
+
#puts "Sending in pipe the wrong way"
|
54
|
+
return
|
55
55
|
else
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
begin
|
57
|
+
packed_event = Marshal.dump(event)
|
58
|
+
packed_bytes = [packed_event.bytesize].pack("L>")
|
59
|
+
@writep.write(packed_bytes+packed_event)
|
60
|
+
rescue Exception => block_exception
|
61
|
+
TCellAgent.logger.error("Could not write to pipe")
|
62
|
+
TCellAgent.logger.error(block_exception.message)
|
63
|
+
TCellAgent.logger.debug(block_exception.backtrace)
|
64
|
+
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -69,7 +69,7 @@ module TCellAgent
|
|
69
69
|
@@event_pipe_manager = ForkPipeManager.new { |event|
|
70
70
|
begin
|
71
71
|
TCellAgent.send_event(event)
|
72
|
-
rescue Exception=>block_exception
|
72
|
+
rescue Exception => block_exception
|
73
73
|
TCellAgent.logger.error("Could handle send_event_block")
|
74
74
|
TCellAgent.logger.error(block_exception.message)
|
75
75
|
TCellAgent.logger.debug(block_exception.backtrace)
|
@@ -31,6 +31,7 @@ module TCellAgent
|
|
31
31
|
|
32
32
|
def ensure_policy_polling_running
|
33
33
|
return if policy_polling_running?
|
34
|
+
return if TCellAgent.configuration.should_start_policy_poll? == false
|
34
35
|
@policy_polling_worker_mutex.synchronize do
|
35
36
|
return if policy_polling_running?
|
36
37
|
start_policy_polling
|
@@ -42,7 +43,7 @@ module TCellAgent
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def start_policy_polling
|
45
|
-
if TCellAgent.configuration.
|
46
|
+
if TCellAgent.configuration.should_start_policy_poll? == true
|
46
47
|
TCellAgent.logger.debug("Starting policy polling thread")
|
47
48
|
@policy_polling_thread = Thread.new do
|
48
49
|
last_poll_time = 0
|
@@ -13,14 +13,27 @@ require "tcell_agent"
|
|
13
13
|
|
14
14
|
module TCellAgent
|
15
15
|
class Agent
|
16
|
+
def self.get_database_discovery_identifier(database, schema, table, fields)
|
17
|
+
[
|
18
|
+
database,
|
19
|
+
schema,
|
20
|
+
table,
|
21
|
+
fields.join(",")
|
22
|
+
].join(",").hash
|
23
|
+
end
|
24
|
+
|
16
25
|
def discover_database_field(route_id, database, schema, table, field)
|
17
|
-
|
18
|
-
@route_table.routes[route_id].database[database][schema][table][field].discovered = true
|
19
|
-
event = (TCellAgent::SensorEvents::DiscoveryEvent.new(route_id)).for_database(database, schema, table, field)
|
20
|
-
TCellAgent.send_event(event)
|
21
|
-
end
|
26
|
+
discover_database_fields(route_id, database, schema, table, [field])
|
22
27
|
end
|
28
|
+
|
23
29
|
def discover_database_fields(route_id, database, schema, table, fields)
|
30
|
+
if (route_id == nil ||
|
31
|
+
database == nil ||
|
32
|
+
schema == nil ||
|
33
|
+
table == nil ||
|
34
|
+
fields == nil)
|
35
|
+
return
|
36
|
+
end
|
24
37
|
if TCellAgent::Agent.is_parent_process? == false
|
25
38
|
TCellAgent.queue_metric({"_type"=>"discover_database_fields",
|
26
39
|
"route_id"=>route_id,
|
@@ -30,16 +43,23 @@ module TCellAgent
|
|
30
43
|
"fields"=>fields})
|
31
44
|
return
|
32
45
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
query_hash = TCellAgent::Agent.get_database_discovery_identifier(database, schema, table, fields)
|
47
|
+
if (@route_table.routes[route_id].database_queries_discovered.fetch(query_hash, false) == false)
|
48
|
+
@route_table.routes[route_id].database_queries_discovered[query_hash] = true
|
49
|
+
event = (TCellAgent::SensorEvents::DiscoveryEvent.new(route_id)).for_database_fields(database, schema, table, fields)
|
50
|
+
TCellAgent.send_event(event)
|
51
|
+
end
|
52
|
+
#discovered_fields = fields.select { |field|
|
53
|
+
# @route_table.routes[route_id].database_queries_discoverd[database][schema][table][field].discovered != true
|
54
|
+
#}
|
55
|
+
#if (discovered_fields.length > 0)
|
56
|
+
# discovered_fields.each { |field|
|
57
|
+
# @route_table.routes[route_id].database[database][schema][table][field].discovered = true
|
58
|
+
# }
|
59
|
+
# event = (TCellAgent::SensorEvents::DiscoveryEvent.new(route_id)).for_database_fields(database, schema, table, fields)
|
60
|
+
# TCellAgent.send_event(event)
|
61
|
+
#end
|
43
62
|
end
|
63
|
+
|
44
64
|
end
|
45
65
|
end
|
@@ -17,7 +17,7 @@ module TCellAgent
|
|
17
17
|
class Configuration
|
18
18
|
attr_accessor :version, :app_id, :api_key, :hmac_key,
|
19
19
|
:tcell_api_url, :tcell_input_url,
|
20
|
-
:
|
20
|
+
:logging_options,
|
21
21
|
:fetch_policies_from_tcell, :instrument_for_events,
|
22
22
|
:preload_policy_filename,
|
23
23
|
:proxy_host, :proxy_port, :proxy_username, :proxy_password,
|
@@ -33,8 +33,35 @@ module TCellAgent
|
|
33
33
|
:raise_exceptions,
|
34
34
|
:allow_unencrypted_appsensor_payloads
|
35
35
|
|
36
|
+
attr_accessor :enabled,
|
37
|
+
:enable_event_manager, # false = Do not start the even manager
|
38
|
+
:enable_event_consumer, # false = Do not consume events, drop them
|
39
|
+
:enable_policy_polling, # false = Do not poll for policies
|
40
|
+
:enable_instrumentation, # false = Do not add instrumentation
|
41
|
+
:enable_intercept_requests # false = Do not insert middleware
|
42
|
+
|
36
43
|
attr_accessor :exp_config_settings
|
37
44
|
|
45
|
+
def should_start_event_manager?
|
46
|
+
@enabled && @enable_event_manager
|
47
|
+
end
|
48
|
+
|
49
|
+
def should_consume_event?
|
50
|
+
@enabled && @enable_event_manager && @enable_event_consumer
|
51
|
+
end
|
52
|
+
|
53
|
+
def should_start_policy_poll?
|
54
|
+
@enabled && @enable_policy_polling && @fetch_policies_from_tcell # fetch_policies_from_tcel = legacy
|
55
|
+
end
|
56
|
+
|
57
|
+
def should_instrument?
|
58
|
+
@enabled && @enable_instrumentation && @instrument_for_events # instrument_for_events = legacy
|
59
|
+
end
|
60
|
+
|
61
|
+
def should_intercept_requests?
|
62
|
+
@enabled && @enable_instrumentation && @enable_intercept_requests
|
63
|
+
end
|
64
|
+
|
38
65
|
def initialize(filename="config/tcell_agent.config", useapp=nil)
|
39
66
|
@version = 0
|
40
67
|
@exp_config_settings = true
|
@@ -44,7 +71,14 @@ module TCellAgent
|
|
44
71
|
|
45
72
|
@fetch_policies_from_tcell = true
|
46
73
|
@instrument_for_events = true
|
74
|
+
|
47
75
|
@enabled = true
|
76
|
+
@enable_event_manager = true
|
77
|
+
@enable_event_consumer = true
|
78
|
+
@enable_policy_polling = true
|
79
|
+
@enable_instrumentation = true
|
80
|
+
@enable_intercept_requests = true
|
81
|
+
|
48
82
|
@cache_filename = "tcell/cache/tcell_agent.cache"
|
49
83
|
@default_log_filename = "tcell/logs/tcell_agent.log"
|
50
84
|
|
@@ -107,8 +141,14 @@ module TCellAgent
|
|
107
141
|
@api_key ||= app_data["api_key"]
|
108
142
|
|
109
143
|
# Optional
|
110
|
-
@enabled = app_data.fetch("enabled", true)
|
111
144
|
@preload_policy_filename = app_data.fetch("preload_policy_filename", nil)
|
145
|
+
|
146
|
+
@enabled = app_data.fetch("enabled", @enabled)
|
147
|
+
@enable_event_manager = app_data.fetch("enable_event_manager", @enable_event_manager)
|
148
|
+
@enable_event_consumer = app_data.fetch("enable_event_consumer", @enable_event_consumer)
|
149
|
+
@enable_policy_polling = app_data.fetch("enable_policy_polling", @enable_policy_polling)
|
150
|
+
@enable_instrumentation = app_data.fetch("enable_instrumentation", @enable_instrumentation)
|
151
|
+
@enable_intercept_requests = app_data.fetch("enable_intercept_requests", @enable_intercept_requests)
|
112
152
|
@fetch_policies_from_tcell = app_data.fetch("fetch_policies_from_tcell", @fetch_policies_from_tcell)
|
113
153
|
@instrument_for_events = app_data.fetch("instrument_for_events", @instrument_for_events)
|
114
154
|
|
data/lib/tcell_agent/logger.rb
CHANGED
@@ -41,7 +41,7 @@ module TCellAgent
|
|
41
41
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
42
42
|
# ISO 8601 format
|
43
43
|
date_format = datetime.strftime("%Y-%m-%d %H:%M:%S,%L%z")
|
44
|
-
"[#{date_format}] #{severity}[#{@logger_pid}]: #{msg}\n"
|
44
|
+
"[#{date_format}] [#{TCellAgent::VERSION}] #{severity}[#{@logger_pid}]: #{msg}\n"
|
45
45
|
end
|
46
46
|
|
47
47
|
return @logger
|
data/lib/tcell_agent/rails.rb
CHANGED
@@ -24,27 +24,21 @@ require 'tcell_agent/userinfo'
|
|
24
24
|
require 'cgi'
|
25
25
|
require 'thread'
|
26
26
|
|
27
|
-
# ensure ActiveRecord's version has been required already
|
28
|
-
module TCellAgent
|
29
|
-
class MyRailtie < Rails::Railtie
|
30
|
-
initializer 'activeservice.autoload', :after => :set_autoload_paths do |app|
|
31
|
-
if (TCellAgent.configuration.enabled)
|
32
|
-
Rails.application.config.to_prepare do
|
33
|
-
end
|
34
|
-
Rails.application.config.after_initialize do
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
27
|
module TCellAgent
|
42
28
|
class Railtie < Rails::Railtie
|
43
29
|
initializer "tcell_agent.insert_middleware" do |app|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
30
|
+
if TCellAgent.configuration.should_intercept_requests?
|
31
|
+
app.config.to_prepare do
|
32
|
+
require 'tcell_agent/devise' if defined?(Devise)
|
33
|
+
require 'tcell_agent/rails/auth/devise' if defined?(Devise)
|
34
|
+
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
35
|
+
require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
|
36
|
+
end
|
37
|
+
app.config.middleware.insert_before(0, "TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware")
|
38
|
+
app.config.middleware.insert_after(0, "TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware")
|
39
|
+
app.config.middleware.use "TCellAgent::Instrumentation::Rails::Middleware::BodyFilterMiddleware"
|
40
|
+
app.config.middleware.use "TCellAgent::Instrumentation::Rails::Middleware::GlobalMiddleware"
|
41
|
+
end
|
48
42
|
end
|
49
43
|
end
|
50
44
|
end
|
@@ -6,8 +6,8 @@ require 'tcell_agent/instrumentation'
|
|
6
6
|
|
7
7
|
module TCellAgent
|
8
8
|
if defined?(Authlogic)
|
9
|
-
TCellAgent.
|
10
|
-
|
9
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
10
|
+
TCellAgent.logger.debug("Instrumenting Authlogic")
|
11
11
|
require 'tcell_agent/agent'
|
12
12
|
require 'tcell_agent/sensor_events/login_fraud'
|
13
13
|
Authlogic::Session::Base.class_eval do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module TCellAgent
|
2
2
|
if defined?(Devise)
|
3
|
-
if (TCellAgent.configuration.enabled && TCellAgent.configuration.
|
3
|
+
if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
|
4
4
|
TCellAgent.logger.debug("Instrumenting Devise")
|
5
5
|
|
6
6
|
require 'tcell_agent/agent'
|
@@ -51,31 +51,35 @@ require 'thread'
|
|
51
51
|
# end
|
52
52
|
# end
|
53
53
|
|
54
|
+
require 'tcell_agent/configuration'
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
if
|
66
|
-
|
67
|
-
if
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
action_objs.
|
78
|
-
|
56
|
+
if TCellAgent.configuration.enabled && TCellAgent.configuration.should_instrument? && TCellAgent.configuration.should_intercept_requests?
|
57
|
+
|
58
|
+
class ActiveRecord::Base
|
59
|
+
# after_initialize do |user|
|
60
|
+
# puts "You have initialized an object!"
|
61
|
+
# puts "ASDF"
|
62
|
+
# end
|
63
|
+
after_find do |record|
|
64
|
+
database_name = self.class.connection_config().fetch(:database,"*").split('/').last
|
65
|
+
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
66
|
+
if dlp_policy
|
67
|
+
request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, nil)
|
68
|
+
if request_env
|
69
|
+
tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
70
|
+
if tcell_context
|
71
|
+
model = record.class
|
72
|
+
column_names = model.columns.map { |col| col.name }
|
73
|
+
if (dlp_policy.database_discovery_enabled)
|
74
|
+
TCellAgent.discover_database_fields(tcell_context.route_id, database_name,"*",model.table_name, column_names)
|
75
|
+
end
|
76
|
+
model.columns.each do |col|
|
77
|
+
#puts "#{model.table_name} .. #{col.name}"
|
78
|
+
action_objs = dlp_policy.get_actions_for_table(database_name, "*", model.table_name, col.name, tcell_context.route_id)
|
79
|
+
if action_objs
|
80
|
+
action_objs.each do |action_obj|
|
81
|
+
tcell_context.add_response_db_filter(record[col.name.to_sym], action_obj, database_name, "*", model.table_name, col.name)
|
82
|
+
end
|
79
83
|
end
|
80
84
|
end
|
81
85
|
end
|
@@ -83,126 +87,132 @@ class ActiveRecord::Base
|
|
83
87
|
end
|
84
88
|
end
|
85
89
|
end
|
86
|
-
end
|
87
90
|
|
88
|
-
# - Request
|
89
|
-
# - Session Id event
|
90
|
-
# - Session Id redact
|
91
|
-
# - Session Id hash
|
92
|
-
# - Session Id mask
|
93
|
-
# - Database-Stuff - [event, redact]
|
94
|
-
#
|
95
|
-
# - Log
|
96
|
-
#
|
97
|
-
|
98
|
-
module TCellAgent
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
91
|
+
# - Request
|
92
|
+
# - Session Id event
|
93
|
+
# - Session Id redact
|
94
|
+
# - Session Id hash
|
95
|
+
# - Session Id mask
|
96
|
+
# - Database-Stuff - [event, redact]
|
97
|
+
#
|
98
|
+
# - Log
|
99
|
+
#
|
100
|
+
|
101
|
+
module TCellAgent
|
102
|
+
module Policies
|
103
|
+
class DataLossPolicy
|
104
|
+
def log_enforce(tcell_context, sanitize_string)
|
105
|
+
if (tcell_context && tcell_context.session_id)
|
106
|
+
session_id_actions = self.get_actions_for_session_id
|
107
|
+
if session_id_actions
|
108
|
+
send_event = false
|
109
|
+
sanitize_string.gsub!(tcell_context.session_id) {|m|
|
110
|
+
if session_id_actions.log_redact
|
111
|
+
send_event = true
|
112
|
+
m = "[session_id]"
|
113
|
+
elsif session_id_actions.log_hash
|
114
|
+
send_event = true
|
115
|
+
m = "[hash]"
|
116
|
+
elsif session_id_actions.log_event
|
117
|
+
send_event = true
|
118
|
+
end
|
119
|
+
m
|
120
|
+
}
|
121
|
+
if send_event
|
122
|
+
TCellAgent.send_event(
|
123
|
+
TCellAgent::SensorEvents::DlpEvent.new(
|
124
|
+
tcell_context.route_id,
|
125
|
+
tcell_context.uri,
|
126
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
|
127
|
+
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
128
|
+
)
|
115
129
|
end
|
116
|
-
|
117
|
-
|
130
|
+
end
|
131
|
+
end
|
132
|
+
sanitize_string
|
133
|
+
end
|
134
|
+
def response_body_enforce(tcell_context, sanitize_string)
|
135
|
+
if (tcell_context && tcell_context.session_id)
|
136
|
+
session_id_actions = self.get_actions_for_session_id
|
137
|
+
if session_id_actions
|
138
|
+
send_event = false
|
139
|
+
sanitize_string.gsub!(tcell_context.session_id) {|m|
|
140
|
+
if session_id_actions.body_redact
|
141
|
+
# m = "[session_id]"
|
142
|
+
send_event = true
|
143
|
+
elsif session_id_actions.body_hash
|
144
|
+
# m = "[hash]"
|
145
|
+
send_event = true
|
146
|
+
elsif session_id_actions.body_event
|
147
|
+
send_event = true
|
148
|
+
end
|
149
|
+
m
|
150
|
+
}
|
151
|
+
end
|
118
152
|
if send_event
|
119
153
|
TCellAgent.send_event(
|
120
154
|
TCellAgent::SensorEvents::DlpEvent.new(
|
121
155
|
tcell_context.route_id,
|
122
156
|
tcell_context.uri,
|
123
|
-
TCellAgent::SensorEvents::DlpEvent::
|
157
|
+
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY
|
124
158
|
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
125
159
|
)
|
126
160
|
end
|
127
161
|
end
|
162
|
+
sanitize_string
|
128
163
|
end
|
129
|
-
sanitize_string
|
130
|
-
end
|
131
|
-
def response_body_enforce(tcell_context, sanitize_string)
|
132
|
-
if (tcell_context && tcell_context.session_id)
|
133
|
-
session_id_actions = self.get_actions_for_session_id
|
134
|
-
if session_id_actions
|
135
|
-
send_event = false
|
136
|
-
sanitize_string.gsub!(tcell_context.session_id) {|m|
|
137
|
-
if session_id_actions.body_redact
|
138
|
-
# m = "[session_id]"
|
139
|
-
send_event = true
|
140
|
-
elsif session_id_actions.body_hash
|
141
|
-
# m = "[hash]"
|
142
|
-
send_event = true
|
143
|
-
elsif session_id_actions.body_event
|
144
|
-
send_event = true
|
145
|
-
end
|
146
|
-
m
|
147
|
-
}
|
148
|
-
end
|
149
|
-
if send_event
|
150
|
-
TCellAgent.send_event(
|
151
|
-
TCellAgent::SensorEvents::DlpEvent.new(
|
152
|
-
tcell_context.route_id,
|
153
|
-
tcell_context.uri,
|
154
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY
|
155
|
-
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
156
|
-
)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
sanitize_string
|
160
164
|
end
|
161
165
|
end
|
162
166
|
end
|
163
|
-
end
|
164
167
|
|
165
|
-
module TCellAgent
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
168
|
+
module TCellAgent
|
169
|
+
ActiveSupport.on_load(:action_controller) do
|
170
|
+
ActionController::Base.class_eval do
|
171
|
+
around_filter :global_request_logging
|
172
|
+
def global_request_logging
|
173
|
+
begin
|
174
|
+
yield
|
175
|
+
TCellAgent::Instrumentation.safe_block("Running DLP Logging Filters") {
|
176
|
+
tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
177
|
+
if tcell_context
|
178
|
+
response.body = tcell_context.filter_body(response.body)
|
179
|
+
end
|
180
|
+
}
|
181
|
+
end
|
178
182
|
end
|
179
183
|
end
|
180
184
|
end
|
181
|
-
|
182
|
-
|
185
|
+
end
|
186
|
+
|
187
|
+
class Logger
|
188
|
+
alias_method :tcell_old_add, :add
|
189
|
+
def add(severity, message = nil, progname = nil, &block)
|
190
|
+
if severity < self.level
|
191
|
+
tcell_old_add(severity, message, progname)
|
183
192
|
|
184
|
-
class Logger
|
185
|
-
alias_method :tcell_old_add, :add
|
186
|
-
def add(severity, message = nil, progname = nil, &block)
|
187
|
-
progname ||= @progname
|
188
|
-
if message.nil?
|
189
|
-
if block_given?
|
190
|
-
message = yield
|
191
193
|
else
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
201
|
-
if tcell_context
|
202
|
-
tcell_context.filter_log(message)
|
194
|
+
progname ||= @progname
|
195
|
+
if message.nil?
|
196
|
+
if block_given?
|
197
|
+
message = yield
|
198
|
+
else
|
199
|
+
message = progname
|
200
|
+
progname = @progname
|
201
|
+
end
|
203
202
|
end
|
203
|
+
|
204
|
+
TCellAgent::Instrumentation.safe_block_no_log("Handling JSAgent add") {
|
205
|
+
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
206
|
+
request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, nil)
|
207
|
+
if message && dlp_policy && request_env
|
208
|
+
tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
209
|
+
if tcell_context
|
210
|
+
tcell_context.filter_log(message)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
}
|
214
|
+
tcell_old_add(severity, message, progname)
|
204
215
|
end
|
205
|
-
|
206
|
-
tcell_old_add(severity, message, progname)
|
216
|
+
end
|
207
217
|
end
|
208
|
-
end
|
218
|
+
end
|