tcell_agent 0.2.9 → 0.2.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffa24423fa841f2a9bdb3b19d44b1250ba2bc4ff
4
- data.tar.gz: ae260430c31ff45f822cf49efd0735664a181a8c
3
+ metadata.gz: 4acf90271f7e52d11433efda8b0345eac7c10267
4
+ data.tar.gz: 9b409662d96c032d94aa4f4fc1dc02cea5cbd752
5
5
  SHA512:
6
- metadata.gz: bfd43837abf1c1ee7297c09d6960f1bb37673ad0b3dd805b93980bed531f216e57e54384f532e74f3c1f5d435564b177925070d0ab24354fc68dfc06122f0f18
7
- data.tar.gz: 0b745e26beb71868ede7f5703a7292462d07c830a3374a0e2a98a3ddedb655695a7b2320a0bbf222926bd3bbeba7dc8462621cd52d465e3295e25a69d25a66e6
6
+ metadata.gz: 41a77673225c1970dddfb9341db54b2a7834984f5d48eb2242125ffa4d32e1869bac719027496c2aa142f09c76a450a3cf0fd252784c8dbd5c710331068e0881
7
+ data.tar.gz: c6e6d7b2c23da1d4866181521a5c803589a3753873740e7bc31c9b994a41ac3982ee36283a0810d8098091c06218f52703e9363eef626edca0cad596e939067d
@@ -42,6 +42,11 @@ CONFIG_FILE = 'config/tcell_agent.config'
42
42
 
43
43
  global = OptionParser.new do |opts|
44
44
  opts.banner = "Usage: tcell_agent [options] [subcommand [options]]"
45
+ opts.on("--version", "Print version") do |v|
46
+ require 'tcell_agent/version'
47
+ puts "TCell.io Ruby Agent (Version #{TCellAgent::VERSION})"
48
+ Kernel.exit(1)
49
+ end
45
50
  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
46
51
  options[:verbose] = v
47
52
  end
@@ -54,6 +54,7 @@ module TCellAgent
54
54
  attr_accessor :event_dispatch_monitor
55
55
 
56
56
  attr_accessor :stop_agent
57
+ attr_accessor :complete_policy_cache
57
58
 
58
59
 
59
60
  def initialize(start_pid=Process.pid)
@@ -90,6 +91,8 @@ module TCellAgent
90
91
  end
91
92
 
92
93
  def initialize_processor_variables
94
+ @complete_policy_cache = {}
95
+
93
96
  @metricsLock = Monitor.new
94
97
  @stop_agent = false
95
98
  @route_table = TCellAgent::Routes::RouteTable.new
@@ -98,8 +101,11 @@ module TCellAgent
98
101
  @event_dispatch_monitor = Monitor.new
99
102
  @mutex = Monitor.new
100
103
 
104
+
101
105
  @response_time_table = {}
102
106
  @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
107
+ @sessions_metrics_mutex = Monitor.new
108
+
103
109
  @dispatchEvents = []
104
110
  @eventQueue = BoundedQueue.new(200)
105
111
 
@@ -58,6 +58,38 @@ module TCellAgent
58
58
  end
59
59
  end
60
60
 
61
+ def send_dispatch_events(tapi)
62
+ events_to_send = []
63
+ @event_dispatch_monitor.synchronize {
64
+ events_to_send = @dispatchEvents
65
+ @dispatchEvents = []
66
+ }
67
+ if (@response_time_table.size > 0)
68
+ metrics_event = TCellAgent::SensorEvents::MetricsEvent.new
69
+ metrics_event.set_route_count_table(@response_time_table)
70
+ events_to_send.push( metrics_event )
71
+ @mutex.synchronize do
72
+ @response_time_table = {}
73
+ end
74
+ end
75
+ if @sessions_metrics.has_sessions?
76
+ sessions_to_send = []
77
+ @sessions_metrics_mutex.synchronize do
78
+ sessions_to_send = @sessions_metrics
79
+ @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
80
+ end
81
+ events_to_send.push( sessions_to_send )
82
+ end
83
+ success = tapi.sendEventSet(events_to_send)
84
+ if ( success == false )
85
+ ensured_events = events_to_send.find_all{|item| item.ensure == true }
86
+ @event_dispatch_monitor.synchronize {
87
+ @dispatchEvents.push(*ensured_events)
88
+ }
89
+ end
90
+ end
91
+
92
+
61
93
  def start_event_processor(send_empties=true)
62
94
  return if TCellAgent.configuration.should_start_event_manager? == false
63
95
 
@@ -79,46 +111,11 @@ module TCellAgent
79
111
  now = Time.now
80
112
  wait_for = @dispatchEventsTimeout - (now - last_run_time).to_i.abs
81
113
  event = @eventQueue.pop([wait_for, 1].max)
82
-
83
114
  if event == nil
115
+ if (@events_send_empties || @dispatchEvents.length > 0)
84
116
  last_run_time = Time.now
85
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
86
- if (@events_send_empties || @dispatchEvents.length > 0)
87
- if (@response_time_table.size > 0)
88
- metrics_event = TCellAgent::SensorEvents::MetricsEvent.new
89
- metrics_event.set_route_count_table(@response_time_table)
90
- @event_dispatch_monitor.synchronize {
91
- @dispatchEvents.push( metrics_event )
92
- }
93
- @mutex.synchronize do
94
- @response_time_table = {}
95
- end
96
- end
97
- if @sessions_metrics.has_sessions?
98
- sessions_to_send = nil
99
- @mutex.synchronize do
100
- sessions_to_send = @sessions_metrics
101
- @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
102
- end
103
- @event_dispatch_monitor.synchronize {
104
- @dispatchEvents.push( sessions_to_send )
105
- }
106
- end
107
- @event_dispatch_monitor.synchronize {
108
- events_to_send = @dispatchEvents
109
- result = tapi.sendEventSet(events_to_send)
110
- if ( result )
111
- @event_dispatch_monitor.synchronize {
112
- @dispatchEvents = []
113
- }
114
- else
115
- @event_dispatch_monitor.synchronize {
116
- @dispatchEvents = @dispatchEvents.find_all{|item| item.ensure == true }
117
- }
118
- end
119
- }
120
- end
121
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
117
+ self.send_dispatch_events(tapi)
118
+ end
122
119
  else
123
120
  event.post_process
124
121
  if event.send == true
@@ -128,39 +125,7 @@ module TCellAgent
128
125
  end
129
126
  if (event.flush or @dispatchEvents.length >= @dispatchEventsLimit or wait_for < 0)
130
127
  last_run_time = Time.now
131
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
132
- if (@events_send_empties || @dispatchEvents.length > 0)
133
- if (@response_time_table.size > 0)
134
- metrics_event = TCellAgent::SensorEvents::MetricsEvent.new
135
- metrics_event.set_route_count_table(@response_time_table)
136
- @event_dispatch_monitor.synchronize {
137
- @dispatchEvents.push( metrics_event )
138
- }
139
- @mutex.synchronize do
140
- @response_time_table = {}
141
- end
142
- end
143
- if @sessions_metrics.has_sessions?
144
- sessions_to_send = nil
145
- @mutex.synchronize do
146
- sessions_to_send = @sessions_metrics
147
- @sessions_metrics = TCellAgent::SensorEvents::SessionsMetric.new
148
- end
149
- @event_dispatch_monitor.synchronize {
150
- @dispatchEvents.push( sessions_to_send )
151
- }
152
- end
153
- @event_dispatch_monitor.synchronize {
154
- events_to_send = @dispatchEvents
155
- result = tapi.sendEventSet(events_to_send)
156
- if ( result )
157
- @dispatchEvents = []
158
- else
159
- @dispatchEvents = @dispatchEvents.find_all{|item| item.ensure == true }
160
- end
161
- }
162
- end
163
- # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
128
+ self.send_dispatch_events(tapi)
164
129
  end
165
130
  end
166
131
  rescue ThreadError
@@ -169,7 +134,6 @@ module TCellAgent
169
134
  @dispatchEvents = []
170
135
  }
171
136
  end
172
-
173
137
  rescue Exception => e
174
138
  last_run_time = Time.now
175
139
  TCellAgent.logger.error("Exception while processing events: #{e.message}")
@@ -333,7 +297,7 @@ module TCellAgent
333
297
  return
334
298
  end
335
299
 
336
- @mutex.synchronize do
300
+ @sessions_metrics_mutex.synchronize do
337
301
  @sessions_metrics.add_session_info(hmac_session_id, user_id, ip_address, user_agent)
338
302
  end
339
303
 
@@ -354,7 +318,6 @@ module TCellAgent
354
318
  })
355
319
  return
356
320
  end
357
-
358
321
  @mutex.synchronize do
359
322
  if (route_id == nil || route_id == "")
360
323
  route_id = "?"
@@ -127,23 +127,32 @@ module TCellAgent
127
127
  policy_cache = {}
128
128
  existing_policy = f1.read
129
129
 
130
- if !existing_policy.nil? && existing_policy != ""
131
- policy_jsons = JSON.parse(existing_policy)
132
- if policy_jsons
133
- if policy_jsons.key?("result")
134
- policy_cache = policy_jsons["result"]
135
- else
136
- policy_cache = policy_jsons
130
+ begin
131
+ if !existing_policy.nil? && existing_policy != ""
132
+ policy_jsons = JSON.parse(existing_policy)
133
+ if policy_jsons
134
+ if policy_jsons.key?("result")
135
+ policy_cache = policy_jsons["result"]
136
+ else
137
+ policy_cache = policy_jsons
138
+ end
137
139
  end
138
140
  end
141
+ policy_cache[policy_name] = policy
142
+ @complete_policy_cache = policy_cache
143
+ rescue Exception => e
144
+ TCellAgent.logger.warn(e.message)
145
+ if @complete_policy_cache
146
+ policy_cache = @complete_policy_cache
147
+ end
139
148
  end
140
- policy_cache[policy_name] = policy
141
149
 
142
150
  f1.rewind
143
- f1.puts( JSON.dump(policy_cache) )
144
-
151
+ f1.write( JSON.dump(policy_cache) )
152
+ f1.flush
153
+ f1.truncate(f1.pos)
145
154
  rescue Exception => e
146
- TCellAgent.logger.error(e.message)
155
+ TCellAgent.logger.warn(e.message)
147
156
 
148
157
  ensure
149
158
  f1.close unless f1.nil?
@@ -169,10 +178,11 @@ module TCellAgent
169
178
  if policy_jsons.key?("result")
170
179
  return policy_jsons["result"]
171
180
  end
181
+ @complete_policy_cache = policy_jsons
172
182
  return policy_jsons
173
183
 
174
184
  rescue Exception => e
175
- TCellAgent.logger.error(e.message)
185
+ TCellAgent.logger.warn(e.message)
176
186
  end
177
187
 
178
188
  return nil
@@ -64,10 +64,13 @@ module TCellAgent
64
64
  raise "Config Information Not Found, can't send events"
65
65
  end
66
66
  current_time = DateTime.now.to_time.to_i
67
- if (events)
68
- events.each { |event| event.calculateOffset(current_time) }
69
- else
70
- events = []
67
+ #if (events)
68
+ # events.each { |event| event.calculateOffset(current_time) }
69
+ #else
70
+ # events = []
71
+ #end
72
+ if (events == nil)
73
+ return false
71
74
  end
72
75
  eventset = { "uuid"=>TCellAgent.configuration.uuid,
73
76
  "hostname"=>TCellAgent.configuration.host_identifier,
@@ -33,7 +33,8 @@ module TCellAgent
33
33
  :raise_exceptions,
34
34
  :allow_unencrypted_appsensor_payloads
35
35
 
36
- attr_accessor :enabled,
36
+ attr_accessor :disable_all,
37
+ :enabled,
37
38
  :enable_event_manager, # false = Do not start the even manager
38
39
  :enable_event_consumer, # false = Do not consume events, drop them
39
40
  :enable_policy_polling, # false = Do not poll for policies
@@ -67,11 +68,10 @@ module TCellAgent
67
68
  @exp_config_settings = true
68
69
  @demomode = false
69
70
 
70
- @allow_unencrypted_appsensor_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"])
71
-
72
71
  @fetch_policies_from_tcell = true
73
72
  @instrument_for_events = true
74
73
 
74
+ @disable_all = false
75
75
  @enabled = true
76
76
  @enable_event_manager = true
77
77
  @enable_event_consumer = true
@@ -90,6 +90,15 @@ module TCellAgent
90
90
  read_config_using_env
91
91
  read_config_from_file(filename)
92
92
 
93
+ # Because ENV can override this one
94
+ env_unencrypted_firewall =
95
+ if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"] != nil)
96
+ @allow_unencrypted_appsensor_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"])
97
+ end
98
+ if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS"] != nil)
99
+ @allow_unencrypted_appsensor_payloads = [true, "true", "yes", "1"].include?(ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS"])
100
+ end
101
+
93
102
  @tcell_api_url ||= "https://api.tcell.io/api/v1"
94
103
  @tcell_input_url ||= "https://input.tcell.io/api/v1"
95
104
  @js_agent_api_base_url ||= nil
@@ -155,6 +164,7 @@ module TCellAgent
155
164
  # Optional
156
165
  @preload_policy_filename = app_data.fetch("preload_policy_filename", nil)
157
166
 
167
+ @disable_all = app_data.fetch("disable_all", @disable_all)
158
168
  @enabled = app_data.fetch("enabled", @enabled)
159
169
  @enable_event_manager = app_data.fetch("enable_event_manager", @enable_event_manager)
160
170
  @enable_event_consumer = app_data.fetch("enable_event_consumer", @enable_event_consumer)
@@ -176,6 +186,10 @@ module TCellAgent
176
186
 
177
187
  @use_websockets = app_data["use_websockets"]
178
188
 
189
+ @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appsensor_payloads', @allow_unencrypted_appsensor_payloads)
190
+ @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appfirewall_payloads', @allow_unencrypted_appsensor_payloads)
191
+
192
+
179
193
  @host_identifier = @host_identifier || app_data.fetch("host_identifier", @host_identifier)
180
194
  if (@host_identifier == nil)
181
195
  @host_identifier = (Socket.gethostname() || "localhost")
@@ -122,7 +122,8 @@ module TCellAgent
122
122
  TCellAgent::SensorEvents::DlpEvent.new(
123
123
  self.route_id,
124
124
  self.uri,
125
- TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY
125
+ TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
126
+ session_id_actions.action_id
126
127
  ).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
127
128
  )
128
129
  end
@@ -166,7 +167,8 @@ module TCellAgent
166
167
  TCellAgent::SensorEvents::DlpEvent.new(
167
168
  self.route_id,
168
169
  self.uri,
169
- TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG
170
+ TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
171
+ session_id_actions.action_id
170
172
  ).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
171
173
  )
172
174
  end
@@ -205,10 +205,12 @@ module TCellAgent
205
205
  data_discovery_json = data_json["data_discovery"]
206
206
  policy.database_discovery_enabled = data_discovery_json.fetch('database_enabled', false)
207
207
  end
208
- if data_json.has_key?("session_id_protection")
209
- session_id_protection = data_json["session_id_protection"]
208
+ if data_json.has_key?("session_id_protections")
209
+ session_id_protection = data_json["session_id_protections"]
210
+ rule_id = session_id_protection.fetch("id",nil)
210
211
  filter_actions = DataLossPolicy.actions_from_json(session_id_protection)
211
212
  if filter_actions != nil
213
+ filter_actions.action_id = rule_id
212
214
  policy.session_id_filter_actions = filter_actions
213
215
  end
214
216
  end
@@ -217,6 +219,7 @@ module TCellAgent
217
219
  context = protection.fetch('variable_context', nil)
218
220
  variables = protection.fetch('variables', nil)
219
221
  scope = protection.fetch('scope', "global")
222
+ rule_id = protection.fetch("id",nil)
220
223
  options = protection.fetch('actions', nil)
221
224
  route_ids = []
222
225
  if (scope == "global")
@@ -229,6 +232,7 @@ module TCellAgent
229
232
  if context && policy.request_filter_actions.has_key?(context) && variables && options
230
233
  filter_actions = DataLossPolicy.actions_from_json(options)
231
234
  if filter_actions != nil
235
+ filter_actions.action_id = rule_id
232
236
  variables.each do |variable|
233
237
  route_ids.each do |route_id|
234
238
  if (context == RequestProtectionManager::COOKIE)
@@ -252,7 +256,7 @@ module TCellAgent
252
256
  _schemas = protection_json.fetch("schemas",["*"])
253
257
  _tables = protection_json.fetch("tables",["*"])
254
258
  _fields = protection_json.fetch("fields",nil)
255
- rule_id = protection_json.fetch("rule_id",nil)
259
+ rule_id = protection_json.fetch("id",nil)
256
260
  actions = protection_json.fetch("actions",{})
257
261
  filter_actions = DataLossPolicy.actions_from_json(actions)
258
262
  _route_ids = ["*"]
@@ -66,22 +66,6 @@ module TCellAgent
66
66
  TCellAgent.send_event(event)
67
67
  end
68
68
  end
69
- appsensor_policy = TCellAgent.policy(TCellAgent::PolicyTypes::AppSensor)
70
- if (appsensor_policy && appsensor_policy.enabled && appsensor_policy.option_enabled?("login_failure"))
71
- hmac_session_id = request.env["tcell.request_data"].hmac_session_id
72
- event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
73
- request.fullpath,
74
- TCellAgent::Policies::AppSensorPolicy::DP_LOGIN_FAILURE,
75
- request.request_method,
76
- request.remote_ip,
77
- tcell_username,
78
- request.env["tcell.request_data"].route_id,
79
- data=nil,
80
- transaction_id=nil,
81
- session_id=hmac_session_id,
82
- user_id=nil)
83
- TCellAgent.send_event(event)
84
- end
85
69
  }
86
70
  end
87
71
  end
@@ -203,7 +203,6 @@ module TCellAgent
203
203
  around_filter :global_request_logging
204
204
  def global_request_logging
205
205
  begin
206
-
207
206
  yield
208
207
 
209
208
  if TCellAgent.configuration.enabled &&
@@ -1,6 +1,85 @@
1
1
  require 'tcell_agent/configuration'
2
2
 
3
3
  module TCellAgent
4
+ module AroundFilters
5
+ def self.handle_request_dlp_parameters(request)
6
+ def self.loop_params_hash(method, param_hash, prefix, &block)
7
+ param_hash.each do |param_name, param_value|
8
+ if param_value && param_value.is_a?(Hash)
9
+ loop_params_hash(method, param_value, 'hash', &block)
10
+ elsif !param_value || !param_value.instance_of?(String) || param_value == ""
11
+ next
12
+ else
13
+ block.call(method, param_name, param_value)
14
+ end
15
+ end
16
+ end
17
+ def self.for_params(request, &block)
18
+ get_params = request.GET
19
+ if get_params
20
+ self.loop_params_hash('get', get_params, nil, &block)
21
+ end
22
+ post_params = request.POST
23
+ if post_params
24
+ self.loop_params_hash('post', post_params, nil, &block)
25
+ end
26
+ end
27
+ def self._handle_dataexpsure_forms(request)
28
+ dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
29
+ tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
30
+ if tcell_context && dataex_policy && dataex_policy.has_actions_for_form_parameter?
31
+ for_params(request) { |method, param_name, param_value|
32
+ actions = dataex_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
33
+ if actions
34
+ actions.each { |action|
35
+ tcell_context.add_filter_for_request_parameter(param_value, action, param_name)
36
+ }
37
+ end
38
+ }
39
+ end
40
+ end
41
+ TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request forms)") {
42
+ _handle_dataexpsure_forms(request)
43
+ }
44
+ def self._handle_dataexpsure_headers(request)
45
+ dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
46
+ tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
47
+ if tcell_context && dataex_policy && dataex_policy.has_actions_for_headers?
48
+ headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
49
+ headers.each { |header_name, header_value|
50
+ header_name = header_name.sub(/^HTTP_/, '').gsub('_','-')
51
+ actions = dataex_policy.get_actions_for_header(header_name)
52
+ if actions
53
+ actions.each { |action|
54
+ tcell_context.add_filter_for_header_value(header_value, action, header_name)
55
+ }
56
+ end
57
+ }
58
+ end
59
+ end
60
+ TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request headers)") {
61
+ _handle_dataexpsure_headers(request)
62
+ }
63
+ def self._handler_dataexposure_cookies(request)
64
+ dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
65
+ tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
66
+ if tcell_context && dataex_policy && dataex_policy.has_actions_for_cookie?
67
+ request.cookies.each { |cookie_name, cookie_value|
68
+ actions = dataex_policy.get_actions_for_cookie(cookie_name)
69
+ if actions
70
+ actions.each { |action|
71
+ tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
72
+ }
73
+ end
74
+ }
75
+ end
76
+ end
77
+ TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request cookies)") {
78
+ _handler_dataexposure_cookies(request)
79
+ }
80
+ end
81
+ end
82
+
4
83
  ActiveSupport.on_load(:action_controller) do
5
84
  ActionController::Base.class_eval do
6
85
 
@@ -19,82 +98,8 @@ module TCellAgent
19
98
  end
20
99
  end
21
100
  }
22
- def loop_params_hash(method, param_hash, prefix, &block)
23
- param_hash.each do |param_name, param_value|
24
- if param_value && param_value.is_a?(Hash)
25
- loop_params_hash(method, param_value, 'hash', &block)
26
- elsif !param_value || !param_value.instance_of?(String) || param_value == ""
27
- next
28
- else
29
- block.call(method, param_name, param_value)
30
- end
31
- end
32
- end
33
- def for_params(request, &block)
34
- get_params = request.GET
35
- if get_params
36
- self.loop_params_hash('get', get_params, nil, &block)
37
- end
38
- post_params = request.POST
39
- if post_params
40
- self.loop_params_hash('post', post_params, nil, &block)
41
- end
42
- end
43
- def _handle_dataexpsure_forms(request)
44
- dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
45
- tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
46
- if tcell_context && dataex_policy && dataex_policy.has_actions_for_form_parameter?
47
- for_params(request) { |method, param_name, param_value|
48
- actions = dataex_policy.get_actions_for_request("form",param_name)
49
- if actions
50
- actions.each { |action|
51
- tcell_context.add_filter_for_request_parameter(param_value, action, param_name)
52
- }
53
- end
54
- }
55
- end
56
- end
57
- TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request forms)") {
58
- _handle_dataexpsure_forms(request)
59
- }
60
- def _handle_dataexpsure_headers(request)
61
- dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
62
- tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
63
- if tcell_context && dataex_policy && dataex_policy.has_actions_for_headers?
64
- headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
65
- headers.each { |header_name, header_value|
66
- header_name = header_name.sub(/^HTTP_/, '').gsub('_','-')
67
- actions = dataex_policy.get_actions_for_header(header_name)
68
- if actions
69
- actions.each { |action|
70
- tcell_context.add_filter_for_header_value(header_value, action, header_name)
71
- }
72
- end
73
- }
74
- end
75
- end
76
- TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request headers)") {
77
- _handle_dataexpsure_headers(request)
78
- }
79
- def _handler_dataexposure_cookies(request)
80
- dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
81
- tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
82
- if tcell_context && dataex_policy && dataex_policy.has_actions_for_cookie?
83
- request.cookies.each { |cookie_name, cookie_value|
84
- actions = dataex_policy.get_actions_for_cookie(cookie_name)
85
- if actions
86
- actions.each { |action|
87
- tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
88
- }
89
- end
90
- }
91
- end
92
- end
93
- TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request cookies)") {
94
- _handler_dataexposure_cookies(request)
95
- }
101
+ TCellAgent::AroundFilters.handle_request_dlp_parameters(request)
96
102
  end
97
-
98
103
  yield
99
104
  end
100
105
  end
@@ -30,7 +30,7 @@ module TCellAgent
30
30
  self["uid"] = user_id
31
31
  end
32
32
  if id
33
- self["id"] = id
33
+ self["rule"] = id
34
34
  end
35
35
  end
36
36
  def for_database(database, schema, table, field)
@@ -54,7 +54,6 @@ module TCellAgent
54
54
  @object_counter.add_object
55
55
  ips.push(ip_address)
56
56
  end
57
-
58
57
  else
59
58
  @object_counter.add_object
60
59
  @user_agents[truncated_agent] = [truncated_agent, [ip_address]]
@@ -73,7 +72,6 @@ module TCellAgent
73
72
  if @user_ids.has_key?(user_id)
74
73
  user_id_info = @user_ids[user_id]
75
74
  user_id_info.add_user_agent_ip(truncated_agent, ip_address)
76
-
77
75
  else
78
76
  @object_counter.add_object
79
77
 
@@ -1,82 +1,83 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
-
3
- require 'tcell_agent/logger'
4
- require 'tcell_agent/agent'
5
2
  require 'tcell_agent/configuration'
6
- require 'thread'
7
3
 
8
- module TCellAgent
9
- #require 'tcell_agent/sinatra' if defined?(Sinatra)
10
- require 'tcell_agent/rails' if defined?(Rails)
4
+ if (TCellAgent.configuration.disable_all == false)
5
+ require 'tcell_agent/logger'
6
+ require 'tcell_agent/agent'
7
+ require 'thread'
8
+ module TCellAgent
9
+ #require 'tcell_agent/sinatra' if defined?(Sinatra)
10
+ require 'tcell_agent/rails' if defined?(Rails)
11
11
 
12
- def self.run_instrumentation(server_name)
12
+ def self.run_instrumentation(server_name)
13
13
 
14
- require 'tcell_agent/rails/on_start' if defined?(Rails)
14
+ require 'tcell_agent/rails/on_start' if defined?(Rails)
15
15
 
16
- begin
17
- TCellAgent.logger.debug("Instrumenting: #{server_name}")
18
- TCellAgent.thread_agent.start
19
- rescue Exception => e
20
- TCellAgent.logger.error("Could not start thread agent. #{e.message}")
21
- end
16
+ begin
17
+ TCellAgent.logger.debug("Instrumenting: #{server_name}")
18
+ TCellAgent.thread_agent.start
19
+ rescue Exception => e
20
+ TCellAgent.logger.error("Could not start thread agent. #{e.message}")
21
+ end
22
22
 
23
- if TCellAgent.configuration.should_instrument?
24
- Thread.abort_on_exception = TCellAgent.configuration.raise_exceptions
25
- Thread.new do
23
+ if TCellAgent.configuration.should_instrument?
24
+ Thread.abort_on_exception = TCellAgent.configuration.raise_exceptions
25
+ Thread.new do
26
26
 
27
- TCellAgent::Instrumentation.safe_block("Instrumenting Agent Details") do
28
- event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
29
- TCellAgent.send_event(event)
30
- end
27
+ TCellAgent::Instrumentation.safe_block("Instrumenting Agent Details") do
28
+ event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
29
+ TCellAgent.send_event(event)
30
+ end
31
31
 
32
- TCellAgent::Instrumentation.safe_block("Instrumenting Server Packages") do
33
- event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
34
- TCellAgent.send_event(event)
35
- end
32
+ TCellAgent::Instrumentation.safe_block("Instrumenting Server Packages") do
33
+ event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
34
+ TCellAgent.send_event(event)
35
+ end
36
36
 
37
- if defined?(Rails)
38
- TCellAgent::Instrumentation.safe_block("Instrumenting routes") do
39
- TCellAgent::Instrumentation::Rails.instrument_routes
37
+ if defined?(Rails)
38
+ TCellAgent::Instrumentation.safe_block("Instrumenting routes") do
39
+ TCellAgent::Instrumentation::Rails.instrument_routes
40
+ end
40
41
  end
41
42
  end
43
+
42
44
  end
43
45
 
44
46
  end
45
47
 
46
48
  end
47
49
 
48
- end
49
-
50
- tcell_server = ENV["TCELL_AGENT_SERVER"]
50
+ tcell_server = ENV["TCELL_AGENT_SERVER"]
51
51
 
52
- if TCellAgent.configuration.should_instrument?
53
- if (!(tcell_server && tcell_server == "mock"))
52
+ if TCellAgent.configuration.should_instrument?
53
+ if (!(tcell_server && tcell_server == "mock"))
54
54
 
55
- if (tcell_server && tcell_server == "webrick") || defined?(Rails::Server)
56
- require("tcell_agent/servers/rails_server")
55
+ if (tcell_server && tcell_server == "webrick") || defined?(Rails::Server)
56
+ require("tcell_agent/servers/rails_server")
57
57
 
58
- elsif (tcell_server && tcell_server == "thin") || defined?(Thin)
59
- require("tcell_agent/servers/thin")
58
+ elsif (tcell_server && tcell_server == "thin") || defined?(Thin)
59
+ require("tcell_agent/servers/thin")
60
60
 
61
- elsif (tcell_server && tcell_server == "puma") || defined?(Puma)
62
- require("tcell_agent/servers/puma")
61
+ elsif (tcell_server && tcell_server == "puma") || defined?(Puma)
62
+ require("tcell_agent/servers/puma")
63
63
 
64
- elsif (tcell_server && tcell_server == "unicorn") || defined?(Unicorn)
65
- require("tcell_agent/servers/unicorn")
64
+ elsif (tcell_server && tcell_server == "unicorn") || defined?(Unicorn)
65
+ require("tcell_agent/servers/unicorn")
66
66
 
67
- else
68
- puts "[tCell.io] **********************************************************************"
69
- puts "[tCell.io] Server used to launch rails not recognized."
70
- puts "[tCell.io] You can override this with the env variable"
71
- puts "[tCell.io] TCELL_AGENT_SERVER=thin|puma|unicorn"
72
- puts "[tCell.io] **********************************************************************"
67
+ else
68
+ puts "[tCell.io] **********************************************************************"
69
+ puts "[tCell.io] Server used to launch rails not recognized."
70
+ puts "[tCell.io] You can override this with the env variable"
71
+ puts "[tCell.io] TCELL_AGENT_SERVER=thin|puma|unicorn"
72
+ puts "[tCell.io] **********************************************************************"
73
+ end
73
74
  end
74
- end
75
75
 
76
- else
76
+ else
77
77
 
78
- # unicorn is always instrumented to support rolling restarts
79
- if (tcell_server && tcell_server == "unicorn") || defined?(Unicorn)
80
- require("tcell_agent/servers/unicorn")
78
+ # unicorn is always instrumented to support rolling restarts
79
+ if (tcell_server && tcell_server == "unicorn") || defined?(Unicorn)
80
+ require("tcell_agent/servers/unicorn")
81
+ end
81
82
  end
82
- end
83
+ end
@@ -1,5 +1,5 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
3
  module TCellAgent
4
- VERSION = "0.2.9"
4
+ VERSION = "0.2.10"
5
5
  end
@@ -52,7 +52,7 @@ module TCellAgent
52
52
 
53
53
  logger = double("logger")
54
54
  expect(TCellAgent).to receive(:logger).and_return(logger)
55
- expect(logger).to receive(:error).with("execution expired")
55
+ expect(logger).to receive(:warn).with("execution expired")
56
56
 
57
57
  TCellAgent.thread_agent.cache(
58
58
  "http-redirect",
@@ -141,7 +141,7 @@ module TCellAgent
141
141
 
142
142
  logger = double("logger")
143
143
  expect(TCellAgent).to receive(:logger).and_return(logger)
144
- expect(logger).to receive(:error).with("A JSON text must at least contain two octets!")
144
+ expect(logger).to receive(:warn).with("A JSON text must at least contain two octets!")
145
145
 
146
146
  expect_any_instance_of(TCellAgent::Agent).to_not receive(:processPolicyJson)
147
147
 
@@ -163,7 +163,7 @@ module TCellAgent
163
163
 
164
164
  logger = double("logger")
165
165
  expect(TCellAgent).to receive(:logger).and_return(logger)
166
- expect(logger).to receive(:error).with("757: unexpected token at 'bad_json'")
166
+ expect(logger).to receive(:warn).with("757: unexpected token at 'bad_json'")
167
167
  expect_any_instance_of(TCellAgent::Agent).to_not receive(:processPolicyJson)
168
168
 
169
169
  agent = TCellAgent::Agent.new(Process.pid)
@@ -17,7 +17,7 @@ module TCellAgent
17
17
  policy_json_two = {
18
18
  "policy_id"=>"x1a1",
19
19
  "data"=>{
20
- "session_id_protection"=>{"body"=>["redact"], "log"=>["event"]}
20
+ "session_id_protections"=>{"body"=>["redact"], "log"=>["event"]}
21
21
  }
22
22
  }
23
23
  session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
@@ -42,7 +42,7 @@ module TCellAgent
42
42
  policy_json_two = {
43
43
  "policy_id"=>"x1a1",
44
44
  "data"=>{
45
- "session_id_protection"=>{"body"=>["event"], "log"=>["redact"]}
45
+ "session_id_protections"=>{"body"=>["event"], "log"=>["redact"]}
46
46
  }
47
47
  }
48
48
  session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
@@ -69,7 +69,7 @@ module TCellAgent
69
69
  policy_json_two = {
70
70
  "policy_id"=>"x1a1",
71
71
  "data"=>{
72
- "session_id_protection"=>{"body"=>["redact"], "log"=>["redact"]}
72
+ "session_id_protections"=>{"body"=>["redact"], "log"=>["redact"]}
73
73
  }
74
74
  }
75
75
  session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
@@ -94,7 +94,7 @@ module TCellAgent
94
94
  policy_json_two = {
95
95
  "policy_id"=>"x1a1",
96
96
  "data"=>{
97
- "session_id_protection"=>{"body"=>["redact"], "log"=>["event"]}
97
+ "session_id_protections"=>{"body"=>["redact"], "log"=>["event"]}
98
98
  }
99
99
  }
100
100
  session_id_policy = TCellAgent::Policies::DataLossPolicy.fromJson(policy_json_two)
@@ -27,7 +27,7 @@ module TCellAgent
27
27
  policy_json_two = {
28
28
  "policy_id"=>"x1a1",
29
29
  "data"=>{
30
- "session_id_protection"=>{"body"=>["redact"], "log"=>["event"]}
30
+ "session_id_protections"=>{"body"=>["redact"], "log"=>["event"]}
31
31
  }
32
32
  }
33
33
  policy_two = DataLossPolicy.fromJson(policy_json_two)
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+ require 'rack'
4
+
5
+ module TCellAgent
6
+ module Instrumentation
7
+ module Rails
8
+ module Middleware
9
+
10
+
11
+ class MockDLPRackApp
12
+
13
+ attr_reader :request_body
14
+
15
+ def initialize(body="OK", route_id=nil, session_id=nil)
16
+ @route_id = route_id
17
+ @session_id = session_id
18
+ @request_headers = {}
19
+ @body = body
20
+ end
21
+
22
+ def loop_params_hash(method, param_hash, prefix, &block)
23
+ param_hash.each do |param_name, param_value|
24
+ if param_value && param_value.is_a?(Hash)
25
+ loop_params_hash(method, param_value, 'hash', &block)
26
+ elsif !param_value || !param_value.instance_of?(String) || param_value == ""
27
+ next
28
+ else
29
+ block.call(method, param_name, param_value)
30
+ end
31
+ end
32
+ end
33
+
34
+ def for_params(request, &block)
35
+ get_params = request.GET
36
+ if get_params
37
+ self.loop_params_hash('get', get_params, nil, &block)
38
+ end
39
+ post_params = request.POST
40
+ if post_params
41
+ self.loop_params_hash('post', post_params, nil, &block)
42
+ end
43
+ end
44
+
45
+ def call(env)
46
+ @env = env
47
+ rack_request = Rack::Request.new(env)
48
+ response_headers = {'Content-Type' => 'text/html'}
49
+ env["tcell.request_data"].transaction_id = "a-b-c-d-e-f"
50
+ env["tcell.request_data"].session_id = @session_id
51
+ env["tcell.request_data"].route_id = @route_id
52
+ tcell_context = env["tcell.request_data"]
53
+ dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
54
+ if dlp_policy
55
+ action_objs = dlp_policy.get_actions_for_table("*", "*", "tablex", "columnb", tcell_context.route_id)
56
+ if action_objs
57
+ action_objs.each do |action_obj|
58
+ tcell_context.add_response_db_filter("secretvalue", action_obj, "databx", "*", "tablex", "columnb")
59
+ end
60
+ end
61
+ TCellAgent::AroundFilters.handle_request_dlp_parameters(rack_request)
62
+ #if tcell_context && dlp_policy && dlp_policy.has_actions_for_form_parameter?
63
+ # for_params(rack_request) { |method, param_name, param_value|
64
+ # actions = dlp_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
65
+ # if actions
66
+ # actions.each { |action|
67
+ # puts action.action_id
68
+ # tcell_context.add_filter_for_request_parameter(param_value, action, param_name)
69
+ # }
70
+ # end
71
+ # }
72
+ #end
73
+ end
74
+ tcell_context.filter_body(@body)
75
+ [200, response_headers, [@body]]
76
+ end
77
+
78
+ def [](key)
79
+ @env[key]
80
+ end
81
+
82
+ end
83
+
84
+ describe HeadersMiddleware do
85
+
86
+ let(:app) { MockDLPRackApp.new }
87
+ let(:app2) { MockDLPRackApp.new(body="My secretvalue othervalue test", route_id="myrouteid", session_id="plainsessionid") }
88
+
89
+ subject { withTCellMiddleware( app ) }
90
+
91
+ context "DLP Middleware" do
92
+ before(:each) do
93
+ TCellAgent.configuration = TCellAgent::Configuration.new
94
+ TCellAgent.configuration.read_config_from_file(get_test_resource_path("normal_config.json"))
95
+ end
96
+ let(:request) { Rack::MockRequest.new(subject) }
97
+ let(:request2) { Rack::MockRequest.new( withTCellMiddleware( app2 )) }
98
+ let(:agent) { ::TCellAgent::Agent.new }
99
+ context "Event" do
100
+ before(:each) do
101
+ TCellAgent.thread_agent.processPolicyJson({"dlp" => {
102
+ "policy_id"=>"x1a1",
103
+ "data"=>{
104
+ "db_protections"=>[
105
+ {
106
+ "scope"=>"route",
107
+ "route_ids"=>["myrouteid"],
108
+ "databases"=>["*"],
109
+ "schemas"=>["*"],
110
+ "tables"=>["tablex"],
111
+ "fields"=>["columnb"],
112
+ "id"=>"323213",
113
+ "actions"=>{
114
+ "log"=>["redact"],
115
+ "body"=>["redact"]
116
+ }
117
+ }
118
+ ]
119
+ }
120
+ }}, cache=false)
121
+ TCellAgent.empty_event_queue
122
+ end
123
+ it "redacts body" do
124
+ response = request2.get("/some/path2?x=abc", 'CONTENT_TYPE' => 'text/html', 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
125
+ expect(response.body).to eq("My [redacted] othervalue test")
126
+ #expect(response['Location']).to eq("https://www.google.com")
127
+ expected_as = {"event_type" => "dlp", "rid" => "myrouteid", "found_in" => "body", "rule" => "323213", "type" => "db", "db" => "databx", "schema" => "*", "table" => "tablex", "field" => "columnb", "uri" => "/some/path2?x="}
128
+ expect(TCellAgent.event_queue).to include(expected_as)
129
+ end
130
+ end #/conext
131
+
132
+
133
+ context "Event for request dlp" do
134
+ before(:each) do
135
+ TCellAgent.thread_agent.processPolicyJson({"dlp" => {
136
+ "policy_id"=>"x1a1",
137
+ "data"=>{
138
+ "request_protections"=>[
139
+ {
140
+ "variable_context"=>"form",
141
+ "scope"=>"route",
142
+ "route_ids"=>["myrouteid"],
143
+ "variables"=>["test333"],
144
+ "id"=>"08080808",
145
+ "actions"=>{
146
+ "log"=>["redact"],
147
+ "body"=>["event"]
148
+ }
149
+ }
150
+ ]
151
+ }
152
+ }}, cache=false)
153
+ TCellAgent.empty_event_queue
154
+ end
155
+ it "redacts body" do
156
+ response = request2.get("/some/path2?test333=othervalue", 'CONTENT_TYPE' => 'text/html', 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
157
+ expect(response.body).to eq("My secretvalue othervalue test")
158
+ expected_as = {"event_type" => "dlp", "rid" => "myrouteid", "found_in" => "body", "rule" => "08080808", "type" => "req", "context" => "form", "variable" => "test333", "uri" => "/some/path2?test333="}
159
+ expect(TCellAgent.event_queue).to include(expected_as)
160
+ end
161
+ end #/conext
162
+
163
+ end #/context
164
+ end #/describe
165
+
166
+
167
+ end
168
+ end
169
+ end
170
+ end
@@ -14,6 +14,7 @@ def get_test_resource_path(name)
14
14
  end
15
15
 
16
16
  require 'tcell_agent/agent'
17
+ require 'tcell_agent/rails/routes'
17
18
 
18
19
  if TCellAgent.configuration.raise_exceptions
19
20
  puts "[tCell.io] ******WARNING*************WARNING**************WARNING****************"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcell_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-01 00:00:00.000000000 Z
11
+ date: 2016-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -246,6 +246,7 @@ files:
246
246
  - spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
247
247
  - spec/lib/tcell_agent/rails/logger_spec.rb
248
248
  - spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb
249
+ - spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb
249
250
  - spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb
250
251
  - spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb
251
252
  - spec/lib/tcell_agent/rails_spec.rb
@@ -349,6 +350,7 @@ test_files:
349
350
  - spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
350
351
  - spec/lib/tcell_agent/rails/logger_spec.rb
351
352
  - spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb
353
+ - spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb
352
354
  - spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb
353
355
  - spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb
354
356
  - spec/lib/tcell_agent/rails_spec.rb