tcell_agent 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
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