tcell_agent 0.2.10 → 0.2.11

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: 4acf90271f7e52d11433efda8b0345eac7c10267
4
- data.tar.gz: 9b409662d96c032d94aa4f4fc1dc02cea5cbd752
3
+ metadata.gz: d554725aca1909bfd60fe8c8eaea0a31d9f81db4
4
+ data.tar.gz: 49d5a1f379e3fe812f705bf8455574d14c5af44c
5
5
  SHA512:
6
- metadata.gz: 41a77673225c1970dddfb9341db54b2a7834984f5d48eb2242125ffa4d32e1869bac719027496c2aa142f09c76a450a3cf0fd252784c8dbd5c710331068e0881
7
- data.tar.gz: c6e6d7b2c23da1d4866181521a5c803589a3753873740e7bc31c9b994a41ac3982ee36283a0810d8098091c06218f52703e9363eef626edca0cad596e939067d
6
+ metadata.gz: ba72d99a1a9d4b280010f35ef9c748baa8127445afe5a24f717819a3e10655d5a179a055bf777a2f492d2114fb4a05bfad4f34f597e322085426bfc70e2720bc
7
+ data.tar.gz: d9a76ef1c4ba6037d6f13bb43fbf01895d29e625da2cc3174767e1cf1edee54d9ee4bfe2bd55441fe3587ce21db40a578a1156566cd98f6f2982d8be40bf7689
@@ -1,6 +1,7 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
  require 'fileutils'
3
3
  require 'json'
4
+ require 'yaml'
4
5
  require 'socket'
5
6
  require 'securerandom'
6
7
 
@@ -15,7 +16,7 @@ module TCellAgent
15
16
  end
16
17
 
17
18
  class Configuration
18
- attr_accessor :version, :app_id, :api_key, :hmac_key,
19
+ attr_accessor :version, :app_id, :api_key, :hmac_key,
19
20
  :tcell_api_url, :tcell_input_url,
20
21
  :logging_options,
21
22
  :fetch_policies_from_tcell, :instrument_for_events,
@@ -25,13 +26,18 @@ module TCellAgent
25
26
  :uuid,
26
27
  :company,
27
28
  :event_batch_size_limit, :event_time_limit_seconds,
28
- :default_log_filename,
29
+ :log_filename,
29
30
  :base_dir,
30
31
  :cache_filename,
31
32
  :js_agent_api_base_url,
32
33
  :js_agent_url,
33
34
  :raise_exceptions,
34
- :allow_unencrypted_appsensor_payloads
35
+ :allow_unencrypted_appsensor_payloads,
36
+ :blacklisted_params,
37
+ :whitelisted_params,
38
+ :whitelist_present,
39
+ :config_filename,
40
+ :max_data_ex_db_records_per_request
35
41
 
36
42
  attr_accessor :disable_all,
37
43
  :enabled,
@@ -79,16 +85,23 @@ module TCellAgent
79
85
  @enable_instrumentation = true
80
86
  @enable_intercept_requests = true
81
87
 
82
- @cache_filename = "tcell/cache/tcell_agent.cache"
83
- @default_log_filename = "tcell/logs/tcell_agent.log"
88
+
89
+ @agent_home_dir = File.join(Dir.getwd, "tcell")
90
+ @agent_log_dir = File.join(@agent_home_dir, "logs")
91
+ @config_filename = File.join(Dir.getwd, filename)
84
92
 
85
93
  @event_batch_size_limit = 50
86
94
  @event_time_limit_seconds = 15
87
95
 
88
96
  @raise_exceptions = false
89
97
 
98
+ @max_data_ex_db_records_per_request = 1000
99
+
90
100
  read_config_using_env
91
- read_config_from_file(filename)
101
+ read_config_from_file(@config_filename)
102
+
103
+ @cache_filename = File.join(@agent_home_dir, "cache", "tcell_agent.cache")
104
+ @log_filename = File.join(@agent_log_dir, "tcell_agent.log")
92
105
 
93
106
  # Because ENV can override this one
94
107
  env_unencrypted_firewall =
@@ -115,11 +128,13 @@ module TCellAgent
115
128
  @uuid = SecureRandom.uuid
116
129
 
117
130
  FileUtils::mkdir_p File.dirname(@cache_filename)
118
- if @logging_options and @logging_options["filename"]
131
+ if @logging_options && @logging_options["filename"]
119
132
  FileUtils::mkdir_p File.dirname(@logging_options["filename"])
120
133
  else
121
- FileUtils::mkdir_p File.dirname(@default_log_filename)
134
+ FileUtils::mkdir_p File.dirname(@log_filename)
122
135
  end
136
+
137
+ load_app_sensor_restrictions
123
138
  end
124
139
 
125
140
  def cache_filename_with_app_id
@@ -139,6 +154,10 @@ module TCellAgent
139
154
  @tcell_input_url = ENV["TCELL_INPUT_URL"]
140
155
  @demomode = ENV["TCELL_DEMOMODE"] || @demomode
141
156
 
157
+ @agent_home_dir = ENV["TCELL_AGENT_HOME"] || @agent_home_dir
158
+ @agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"] || File.join(@agent_home_dir, "logs")
159
+ @config_filename = ENV["TCELL_AGENT_CONFIG"] || @config_filename
160
+
142
161
  if @demomode
143
162
  @event_batch_size_limit = 2
144
163
  @event_time_limit_seconds = 5
@@ -151,7 +170,7 @@ module TCellAgent
151
170
  if File.file?(filename)
152
171
  #puts "tCell.io: Loading from file"
153
172
  begin
154
- config_text = open(filename).read
173
+ config_text = File.open(filename).read
155
174
  config = JSON.parse(config_text)
156
175
  if (config["version"] == 1)
157
176
  # Required
@@ -189,6 +208,8 @@ module TCellAgent
189
208
  @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appsensor_payloads', @allow_unencrypted_appsensor_payloads)
190
209
  @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appfirewall_payloads', @allow_unencrypted_appsensor_payloads)
191
210
 
211
+ data_exposure = app_data.fetch('data_exposure', {})
212
+ @max_data_ex_db_records_per_request = data_exposure.fetch('max_data_ex_db_records_per_request', @max_data_ex_db_records_per_request)
192
213
 
193
214
  @host_identifier = @host_identifier || app_data.fetch("host_identifier", @host_identifier)
194
215
  if (@host_identifier == nil)
@@ -218,7 +239,7 @@ module TCellAgent
218
239
  @event_batch_size_limit = 2
219
240
  @event_time_limit_seconds = 5
220
241
  end
221
- else
242
+ else
222
243
  puts " ********* ********* ********* *********"
223
244
  puts "* tCell.io *"
224
245
  puts "* Unsupported config file version *"
@@ -233,6 +254,50 @@ module TCellAgent
233
254
  end #begin
234
255
  end # filename exist
235
256
  end #def read
257
+
258
+ def load_app_sensor_restrictions
259
+ payloads_config_filename = ENV["TCELL_AGENT_PAYLOADS_CONFIG"] || "config/tcell_agent_payloads.config"
260
+
261
+ @blacklisted_params = {
262
+ "token" => true,
263
+ "client_secret" => true,
264
+ "password" => true,
265
+ "passwd" => true,
266
+ "refresh_token" => true,
267
+ "pf.pass" => true,
268
+ "user.password" => true
269
+ }
270
+ @whitelisted_params = {}
271
+ @whitelist_present = false
272
+
273
+ if File.file?(payloads_config_filename)
274
+ begin
275
+ payloads_config = YAML.load(File.open(payloads_config_filename).read)
276
+ if payloads_config.has_key?("blacklisted")
277
+ @blacklisted_params = {}
278
+ payloads_config["blacklisted"].each do |param_name|
279
+ @blacklisted_params[param_name.downcase] = true
280
+ end
281
+ end
282
+ if payloads_config.has_key?("whitelisted")
283
+ @whitelist_present = true
284
+ payloads_config["whitelisted"].each do |param_name|
285
+ @whitelisted_params[param_name.downcase] = true
286
+ end
287
+ end
288
+
289
+ rescue Exception => e
290
+ @allow_unencrypted_appsensor_payloads = false
291
+
292
+ puts " ********* ********* ********* **********"
293
+ puts "* tCell.io *"
294
+ puts "* Could not load payloads config file *"
295
+ puts " ********* ********* ********* **********"
296
+ puts e
297
+ end
298
+ end
299
+ end
300
+
236
301
  end # class
237
302
 
238
303
  TCellAgent.configuration ||= TCellAgent::Configuration.new
@@ -5,6 +5,7 @@ require 'tcell_agent/logger'
5
5
  require 'tcell_agent/configuration'
6
6
  require 'tcell_agent/version'
7
7
  require 'date'
8
+ require 'cgi'
8
9
 
9
10
  module TCellAgent
10
11
  module Instrumentation
@@ -126,6 +127,7 @@ module TCellAgent
126
127
  session_id_actions.action_id
127
128
  ).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
128
129
  )
130
+
129
131
  end
130
132
  end
131
133
  end
@@ -133,6 +135,7 @@ module TCellAgent
133
135
  replace_filters = (context_filters.select {|context_filter| context_filter.rule.body_redact == true })
134
136
  event_filters = (context_filters.select {|context_filter| (context_filter.rule.body_redact != true && context_filter.rule.body_event == true) })
135
137
  send_flag = TCellData.filterx(body, event_filters.length > 0, replace_filters.length > 0, term)
138
+ send_flag = send_flag || TCellData.filterx(body, event_filters.length > 0, replace_filters.length > 0, CGI.escapeHTML(term))
136
139
  if send_flag
137
140
  (replace_filters + event_filters).each { |filter|
138
141
  base_event = TCellAgent::SensorEvents::DlpEvent.new(
@@ -34,7 +34,7 @@ module TCellAgent
34
34
  if logging_options && logging_options["enabled"]
35
35
  FileUtils.mkdir_p 'tcell/logs'
36
36
  level = loggingLevelFromString(logging_options["level"])
37
- logging_file = logging_options["filename"] || TCellAgent.configuration.default_log_filename
37
+ logging_file = logging_options["filename"] || TCellAgent.configuration.log_filename
38
38
  # limit the total log file to about 9 * 5 = 45 mb
39
39
  @logger = Logger.new(logging_file, shift_age=9, shift_size=5242880)
40
40
  @logger.level = level
@@ -47,7 +47,7 @@ module TCellAgent
47
47
  return @logger
48
48
  end
49
49
 
50
- logger = Logger.new(TCellAgent.configuration.default_log_filename)
50
+ logger = Logger.new(TCellAgent.configuration.log_filename)
51
51
  logger.level = Logger::ERROR
52
52
  return logger
53
53
  end
@@ -51,58 +51,97 @@ require 'thread'
51
51
  require 'tcell_agent/configuration'
52
52
 
53
53
 
54
-
55
- module TCellAgent
56
- class MyRailtie < Rails::Railtie
57
- initializer 'activeservice.autoload', :after => :set_autoload_paths do |app|
58
- def database_exists?
59
- database_yaml = "#{Rails.root}/config/database.yml"
60
- File.exists?database_yaml
61
- end
62
-
63
- if (database_exists?)
64
- class ActiveRecord::Base
65
- # after_initialize do |user|
66
- # puts "You have initialized an object!"
67
- # puts "ASDF"
68
- # end
69
- after_find do |record|
70
- if TCellAgent.configuration.enabled &&
71
- TCellAgent.configuration.should_instrument? &&
72
- TCellAgent.configuration.should_intercept_requests?
73
-
74
- database_name = self.class.connection_config().fetch(:database,"*").split('/').last
75
- dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
76
- if dlp_policy
77
- request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, nil)
78
- if request_env
79
- tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
80
- if tcell_context
81
- model = record.class
82
- column_names = model.columns.map { |col| col.name }
83
- if (dlp_policy.database_discovery_enabled)
84
- TCellAgent.discover_database_fields(tcell_context.route_id, database_name,"*",model.table_name, column_names)
85
- end
86
- model.columns.each do |col|
87
- #puts "#{model.table_name} .. #{col.name}"
88
- action_objs = dlp_policy.get_actions_for_table(database_name, "*", model.table_name, col.name, tcell_context.route_id)
89
- if action_objs
90
- action_objs.each do |action_obj|
91
- tcell_context.add_response_db_filter(record[col.name.to_sym], action_obj, database_name, "*", model.table_name, col.name)
54
+ module TCellAgent
55
+ class MyRailtie < Rails::Railtie
56
+ initializer 'activeservice.autoload', :after => :set_autoload_paths do |app|
57
+
58
+ if defined?(ActiveRecord)
59
+ ActiveRecord::Relation.class_eval do
60
+
61
+ alias_method :original_exec_queries, :exec_queries
62
+ def exec_queries
63
+ @records = original_exec_queries
64
+
65
+ TCellAgent::Instrumentation.safe_block("Running DLP on query") do
66
+ if @records.size > 0
67
+
68
+ if TCellAgent.configuration.enabled &&
69
+ TCellAgent.configuration.should_instrument? &&
70
+ TCellAgent.configuration.should_intercept_requests?
71
+
72
+ dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
73
+
74
+ if dlp_policy
75
+ request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, nil)
76
+
77
+ if request_env
78
+ tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
79
+
80
+ if tcell_context
81
+ first_record = @records.first
82
+ database_name = first_record.class.connection_config().fetch(:database,"*").split('/').last
83
+ model = first_record.class
84
+ column_names = model.columns.map { |col| col.name }
85
+ table_name = model.table_name
86
+
87
+ if dlp_policy.database_discovery_enabled
88
+ TCellAgent.discover_database_fields(
89
+ tcell_context.route_id,
90
+ database_name,
91
+ "*",
92
+ table_name,
93
+ column_names
94
+ )
95
+ end
96
+
97
+ column_name_to_rules = first_record.attributes.keys.inject({}) do |memo, column_name|
98
+ memo[column_name] = dlp_policy.get_actions_for_table(
99
+ database_name,
100
+ "*",
101
+ table_name,
102
+ column_name,
103
+ tcell_context.route_id
104
+ )
105
+
106
+ memo
107
+ end
108
+
109
+ if @records.size > TCellAgent.configuration.max_data_ex_db_records_per_request
110
+ TCellAgent.logger.warn("Route (#{tcell_context.route_id}) retrieved too many records")
111
+ end
112
+
113
+ @records[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
114
+ column_name_to_rules.each do |column_name, rules|
115
+ if rules
116
+ rules.each do |rule|
117
+ tcell_context.add_response_db_filter(
118
+ record[column_name.to_sym],
119
+ rule,
120
+ database_name,
121
+ "*",
122
+ table_name,
123
+ column_name
124
+ )
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
92
131
  end
93
132
  end
94
133
  end
95
134
  end
135
+
136
+ @records
96
137
  end
97
- end # /if dlp_policy
98
- end # /enabled
99
- end # /after_find
100
- end # /class
101
- end
102
138
 
139
+ end
103
140
  end
141
+
104
142
  end
105
143
  end
144
+ end
106
145
 
107
146
 
108
147
 
@@ -145,18 +145,19 @@ module TCellAgent
145
145
  rack_response = Rack::Response.new(response)
146
146
 
147
147
  if appsensor_policy && appsensor_policy.enabled
148
- event = TCellAgent::SensorEvents::TCellAppSensorEventProcessor.new
148
+ event = TCellAgent::SensorEvents::TCellAppSensorEventProcessor.new
149
149
  event.request_headers = request.env
150
150
  event.request_content_length = (request.content_length || "0").to_i
151
151
  event.response_content_length = (rack_response.length || "0").to_i
152
+ event.request_content_type = request.content_type
152
153
  event.remote_addr = request.ip
153
- event.uri = request.fullpath
154
+ event.uri = "#{request.base_url}#{request.fullpath}"
154
155
  event.get_params = request.GET
155
156
  event.post_params = request.POST
157
+ event.request_body = request.body.gets
156
158
  event.cookies = request.cookies
157
159
  event.request_method = request.request_method
158
-
159
- request_body = request.body
160
+
160
161
  event.request_size = event.request_content_length
161
162
  #status, headers, active_response = response
162
163
  #if active_response.class != ActionDispatch::Response
@@ -54,20 +54,33 @@ module TCellAgent
54
54
  end
55
55
  end
56
56
  class TCellAppSensorEventProcessor < TCellSensorEvent
57
- attr_accessor :request_headers, :request_size, :remote_addr,
57
+ attr_accessor :request_headers, :request_size, :remote_addr,
58
58
  :uri, :get_params, :post_params, :cookies,
59
59
  :request_content_length, :request_content_type,
60
- :request_method
60
+ :request_method, :request_body
61
61
  attr_accessor :status_code, :response_headers,
62
62
  :response_content_length,
63
63
  :route_id, :transaction_id, :session_id, :user_id
64
+
64
65
  def initialize
65
66
  @request_content_length=0
66
67
  @response_content_length = 0
67
68
  @send = false
69
+ @body_params = nil
68
70
  end
71
+
69
72
  def appsensor_event(dp, param, data, payload=nil)
70
73
  TCellAgent::Instrumentation.safe_block("AppSensor Sending Event") {
74
+ unless payload.nil?
75
+ if TCellAgent.configuration.blacklisted_params.has_key?(param.downcase)
76
+ payload = "BLACKLISTED"
77
+
78
+ elsif TCellAgent.configuration.whitelist_present &&
79
+ !TCellAgent.configuration.whitelisted_params.has_key?(param.downcase)
80
+ payload = "NOT_WHITELISTED"
81
+ end
82
+ end
83
+
71
84
  event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
72
85
  @uri,
73
86
  dp,
@@ -84,6 +97,7 @@ module TCellAgent
84
97
  TCellAgent.send_event(event)
85
98
  }
86
99
  end
100
+
87
101
  def loop_params_hash(method, param_hash, prefix, &block)
88
102
  param_hash.each do |param_name, param_value|
89
103
  if param_value && param_value.is_a?(Hash)
@@ -95,6 +109,7 @@ module TCellAgent
95
109
  end
96
110
  end
97
111
  end
112
+
98
113
  def for_params(&block)
99
114
  if @get_params
100
115
  self.loop_params_hash('get', @get_params, nil, &block)
@@ -102,13 +117,40 @@ module TCellAgent
102
117
  if @post_params
103
118
  self.loop_params_hash('post', @post_params, nil, &block)
104
119
  end
120
+ if body_params.length > 0
121
+ self.loop_params_hash('body', body_params, nil, &block)
122
+ end
105
123
  end
124
+
106
125
  def for_get_params(&block)
107
126
  if @get_params
108
127
  self.loop_params_hash('get', @get_params, nil, &block)
109
128
  end
110
129
  end
111
130
 
131
+ def body_params
132
+ if @body_params
133
+ @body_params
134
+
135
+ elsif @request_content_length > 2000000
136
+ @body_params = {}
137
+
138
+ else
139
+ if @request_content_type =~ %r{application/json}i && @request_body
140
+ begin
141
+ @body_params = JSON.parse(@request_body)
142
+ rescue
143
+ TCellAgent.logger.debug("JSON body parameter parsing failed")
144
+ @body_params = {}
145
+ end
146
+ else
147
+ @body_params = {}
148
+ end
149
+
150
+ @body_params
151
+ end
152
+ end
153
+
112
154
  def test_response_size
113
155
  if (@response_content_length && @response_content_length > TCellAgent::Policies::AppSensorPolicy::MAX_NORMAL_RESPONSE_BYTES)
114
156
  appsensor_event(TCellAgent::Policies::AppSensorPolicy::DP_UNUSUAL_RESPONSE_SIZE, response_content_length.to_s, nil)
@@ -35,7 +35,13 @@ if defined?(Puma.cli_config)
35
35
 
36
36
  # Runs initial instrumentation only once on the master process
37
37
  puma_server_starting = Proc.new { TCellAgent.run_instrumentation("Puma Cluster Mode") }
38
- Puma.cli_config.options[:before_fork].push(puma_server_starting)
38
+
39
+ # before_fork was added in Puma v2.13.0
40
+ if Puma.cli_config.options[:before_fork]
41
+ Puma.cli_config.options[:before_fork].push(puma_server_starting)
42
+ else
43
+ Puma.cli_config.options[:before_fork] = [puma_server_starting]
44
+ end
39
45
 
40
46
  # Each puma worker still needs the agent started but no need to run
41
47
  # initial instrumentation again
@@ -58,4 +64,3 @@ if defined?(Puma.cli_config)
58
64
 
59
65
  end
60
66
  end
61
-
@@ -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.10"
4
+ VERSION = "0.2.11"
5
5
  end
@@ -79,7 +79,7 @@ module TCellAgent
79
79
  end
80
80
 
81
81
  context "with 10 processes updating the cached file" do
82
- it "should update the cached file with all updates" do
82
+ xit "should update the cached file with all updates" do
83
83
  processes = 5.times.map do |process_number|
84
84
  ForkBreak::Process.new do |breakpoints|
85
85
  original_dump = JSON.method(:dump)
@@ -0,0 +1,371 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+
5
+ describe Configuration do
6
+ describe "#load_app_sensor_restrictions" do
7
+ before(:each) do
8
+ @config_file = double("config", read: {
9
+ version: 1,
10
+ applications: [
11
+ {
12
+ allow_unencrypted_appsensor_payloads: true
13
+ }
14
+ ]
15
+ }.to_json)
16
+ end
17
+
18
+ context "with no payloads file present" do
19
+ it "should set blacklist to default params and whitelist to empty" do
20
+ expect(File).to receive(:file?).with(
21
+ File.join(Dir.getwd, "config/tcell_agent.config")
22
+ ).and_return(true)
23
+ expect(File).to receive(:open).with(
24
+ File.join(Dir.getwd, "config/tcell_agent.config")
25
+ ).and_return(@config_file)
26
+ expect(File).to receive(:file?).with(
27
+ "config/tcell_agent_payloads.config"
28
+ ).and_return(false)
29
+ expect(File).to_not receive(:open)
30
+ configuration = TCellAgent::Configuration.new
31
+
32
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
33
+ expect(configuration.blacklisted_params).to eq({
34
+ "token" => true,
35
+ "client_secret" => true,
36
+ "password" => true,
37
+ "passwd" => true,
38
+ "refresh_token" => true,
39
+ "pf.pass" => true,
40
+ "user.password" => true
41
+ })
42
+ expect(configuration.whitelisted_params).to eq({})
43
+ expect(configuration.whitelist_present).to eq(false)
44
+ end
45
+ end
46
+
47
+ context "with a payloads file present" do
48
+ context "with a malformed payloads file" do
49
+ it "should set blacklist to default params and whitelist to empty" do
50
+ payloads_file = double("payloads", read: "{ whitelist: { test } ")
51
+ expect(File).to receive(:file?).with(
52
+ File.join(Dir.getwd, "config/tcell_agent.config")
53
+ ).and_return(true)
54
+ expect(File).to receive(:open).with(
55
+ File.join(Dir.getwd, "config/tcell_agent.config")
56
+ ).and_return(@config_file)
57
+ expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
58
+ expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
59
+ configuration = TCellAgent::Configuration.new
60
+
61
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(false)
62
+ expect(configuration.blacklisted_params).to eq({
63
+ "token" => true,
64
+ "client_secret" => true,
65
+ "password" => true,
66
+ "passwd" => true,
67
+ "refresh_token" => true,
68
+ "pf.pass" => true,
69
+ "user.password" => true
70
+ })
71
+ expect(configuration.whitelisted_params).to eq({})
72
+ expect(configuration.whitelist_present).to eq(false)
73
+ end
74
+ end
75
+
76
+ context "with a payloads file" do
77
+ context "with empty json" do
78
+ it "should set blacklist to default params and whitelist to empty" do
79
+ payloads_file = double("payloads", read: "{}")
80
+ expect(File).to receive(:file?).with(
81
+ File.join(Dir.getwd, "config/tcell_agent.config")
82
+ ).and_return(true)
83
+ expect(File).to receive(:open).with(
84
+ File.join(Dir.getwd, "config/tcell_agent.config")
85
+ ).and_return(@config_file)
86
+ expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
87
+ expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
88
+ configuration = TCellAgent::Configuration.new
89
+
90
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
91
+ expect(configuration.blacklisted_params).to eq({
92
+ "token" => true,
93
+ "client_secret" => true,
94
+ "password" => true,
95
+ "passwd" => true,
96
+ "refresh_token" => true,
97
+ "pf.pass" => true,
98
+ "user.password" => true
99
+ })
100
+ expect(configuration.whitelisted_params).to eq({})
101
+ expect(configuration.whitelist_present).to eq(false)
102
+ end
103
+ end
104
+
105
+ context "with blacklisted present" do
106
+ it "should set blacklist but whitelist is empty" do
107
+ payloads_file = double("payloads", read:{blacklisted:["passwd"]}.to_json)
108
+ expect(File).to receive(:file?).with(
109
+ File.join(Dir.getwd, "config/tcell_agent.config")
110
+ ).and_return(true)
111
+ expect(File).to receive(:open).with(
112
+ File.join(Dir.getwd, "config/tcell_agent.config")
113
+ ).and_return(@config_file)
114
+ expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
115
+ expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
116
+ configuration = TCellAgent::Configuration.new
117
+
118
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
119
+ expect(configuration.blacklisted_params).to eq({"passwd" => true})
120
+ expect(configuration.whitelisted_params).to eq({})
121
+ expect(configuration.whitelist_present).to eq(false)
122
+ end
123
+ end
124
+
125
+ context "with whitelist present" do
126
+ it "should set whitelist and blacklist to default params" do
127
+ payloads_file = double("payloads", read: {whitelisted: ["passwd"]}.to_json)
128
+ expect(File).to receive(:file?).with(
129
+ File.join(Dir.getwd, "config/tcell_agent.config")
130
+ ).and_return(true)
131
+ expect(File).to receive(:open).with(
132
+ File.join(Dir.getwd, "config/tcell_agent.config")
133
+ ).and_return(@config_file)
134
+ expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
135
+ expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
136
+ configuration = TCellAgent::Configuration.new
137
+
138
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
139
+ expect(configuration.blacklisted_params).to eq({
140
+ "token" => true,
141
+ "client_secret" => true,
142
+ "password" => true,
143
+ "passwd" => true,
144
+ "refresh_token" => true,
145
+ "pf.pass" => true,
146
+ "user.password" => true
147
+ })
148
+ expect(configuration.whitelisted_params).to eq({"passwd" => true})
149
+ expect(configuration.whitelist_present).to eq(true)
150
+ end
151
+ end
152
+
153
+ context "with blacklist and whitelist present" do
154
+ it "should set whitelist and blacklist" do
155
+ payloads_file = double("payloads", read: {blacklisted: ["ssn"], whitelisted: ["passwd"]}.to_json)
156
+ expect(File).to receive(:file?).with(
157
+ File.join(Dir.getwd, "config/tcell_agent.config")
158
+ ).and_return(true)
159
+ expect(File).to receive(:open).with(
160
+ File.join(Dir.getwd, "config/tcell_agent.config")
161
+ ).and_return(@config_file)
162
+ expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
163
+ expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
164
+ configuration = TCellAgent::Configuration.new
165
+
166
+ expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
167
+ expect(configuration.blacklisted_params).to eq({"ssn" => true})
168
+ expect(configuration.whitelisted_params).to eq({"passwd" => true})
169
+ expect(configuration.whitelist_present).to eq(true)
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ describe "#agent_home_dir" do
178
+ context "no TCELL_AGENT_HOME defined" do
179
+ it "should set cache file, config, and log file to defaults" do
180
+ configuration = Configuration.new
181
+
182
+ expect(configuration.cache_filename).to eq(
183
+ File.join(Dir.getwd, "tcell/cache/tcell_agent.cache")
184
+ )
185
+ expect(configuration.log_filename).to eq(
186
+ File.join(Dir.getwd, "tcell/logs/tcell_agent.log")
187
+ )
188
+ expect(configuration.config_filename).to eq(
189
+ File.join(Dir.getwd, "config/tcell_agent.config")
190
+ )
191
+ end
192
+ end
193
+
194
+ context "TCELL_AGENT_HOME defined" do
195
+ it "should set config filename to default, cache file and log file are updated" do
196
+ old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
197
+
198
+ ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
199
+
200
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
201
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/logs")
202
+
203
+ configuration = Configuration.new
204
+
205
+ expect(configuration.cache_filename).to eq(
206
+ "spec_tcell_home/cache/tcell_agent.cache"
207
+ )
208
+ expect(configuration.log_filename).to eq(
209
+ "spec_tcell_home/logs/tcell_agent.log"
210
+ )
211
+ expect(configuration.config_filename).to eq(
212
+ File.join(Dir.getwd, "config/tcell_agent.config")
213
+ )
214
+
215
+ ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
216
+ end
217
+ end
218
+
219
+ context "TCELL_AGENT_HOME and TCELL_AGENT_LOG_DIR defined" do
220
+ it "should set config filename to default, cache file and log file are updated" do
221
+ old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
222
+ old_tcell_agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"]
223
+
224
+ ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
225
+ ENV["TCELL_AGENT_LOG_DIR"] = "spec_tcell_log_dir"
226
+
227
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
228
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_log_dir")
229
+
230
+ configuration = Configuration.new
231
+
232
+ expect(configuration.cache_filename).to eq(
233
+ "spec_tcell_home/cache/tcell_agent.cache"
234
+ )
235
+ expect(configuration.log_filename).to eq(
236
+ "spec_tcell_log_dir/tcell_agent.log"
237
+ )
238
+ expect(configuration.config_filename).to eq(
239
+ File.join(Dir.getwd, "config/tcell_agent.config")
240
+ )
241
+
242
+ ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
243
+ ENV["TCELL_AGENT_LOG_DIR"] = old_tcell_agent_log_dir
244
+ end
245
+ end
246
+
247
+ context "TCELL_AGENT_HOME, TCELL_AGENT_LOG_DIR, and TCELL_AGENT_CONFIG defined " do
248
+ it "should update config filename, cache file, and log file" do
249
+ old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
250
+ old_tcell_agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"]
251
+ old_config_filename = ENV["TCELL_AGENT_CONFIG"]
252
+
253
+ ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
254
+ ENV["TCELL_AGENT_LOG_DIR"] = "spec_tcell_log_dir"
255
+ ENV["TCELL_AGENT_CONFIG"] = "spec_config/tcell_agent.config"
256
+
257
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_log_dir")
258
+ expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
259
+
260
+ configuration = Configuration.new
261
+
262
+ expect(configuration.cache_filename).to eq(
263
+ "spec_tcell_home/cache/tcell_agent.cache"
264
+ )
265
+ expect(configuration.log_filename).to eq(
266
+ "spec_tcell_log_dir/tcell_agent.log"
267
+ )
268
+ expect(configuration.config_filename).to eq(
269
+ "spec_config/tcell_agent.config"
270
+ )
271
+
272
+ ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
273
+ ENV["TCELL_AGENT_LOG_DIR"] = old_tcell_agent_log_dir
274
+ ENV["TCELL_AGENT_CONFIG"] = old_config_filename
275
+ end
276
+ end
277
+ end
278
+
279
+ describe "#data_exposure" do
280
+ context "no data_exposure defined" do
281
+ it "should set max_data_ex_db_records_per_request to default" do
282
+ no_data_ex = double(
283
+ "no_data_ex",
284
+ read: {
285
+ version: 1,
286
+ applications: [
287
+ app_id: "app_id",
288
+ name: "test",
289
+ api_key: "api_key"
290
+ ]
291
+ }.to_json
292
+ )
293
+ expect(File).to receive(:file?).with(
294
+ File.join(Dir.getwd, "no_data_ex.config")
295
+ ).and_return(true)
296
+ expect(File).to receive(:open).with(
297
+ File.join(Dir.getwd, "no_data_ex.config")
298
+ ).and_return(no_data_ex)
299
+ expect(File).to receive(:file?).with(
300
+ "config/tcell_agent_payloads.config"
301
+ ).and_return(false)
302
+ configuration = Configuration.new("no_data_ex.config")
303
+
304
+ expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
305
+ end
306
+ end
307
+
308
+ context "data_exposure is empty" do
309
+ it "should set max_data_ex_db_records_per_request to default" do
310
+ no_data_ex = double(
311
+ "no_data_ex",
312
+ read: {
313
+ version: 1,
314
+ applications: [
315
+ app_id: "app_id",
316
+ name: "test",
317
+ api_key: "api_key",
318
+ data_exposure: {}
319
+ ]
320
+ }.to_json
321
+ )
322
+ expect(File).to receive(:file?).with(
323
+ File.join(Dir.getwd, "no_data_ex.config")
324
+ ).and_return(true)
325
+ expect(File).to receive(:open).with(
326
+ File.join(Dir.getwd, "no_data_ex.config")
327
+ ).and_return(no_data_ex)
328
+ expect(File).to receive(:file?).with(
329
+ "config/tcell_agent_payloads.config"
330
+ ).and_return(false)
331
+ configuration = Configuration.new("no_data_ex.config")
332
+
333
+ expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
334
+ end
335
+ end
336
+
337
+ context "data_exposure contains an override" do
338
+ it "should set max_data_ex_db_records_per_request to override" do
339
+ no_data_ex = double(
340
+ "no_data_ex",
341
+ read: {
342
+ version: 1,
343
+ applications: [
344
+ app_id: "app_id",
345
+ name: "test",
346
+ api_key: "api_key",
347
+ data_exposure: {
348
+ max_data_ex_db_records_per_request: 5000
349
+ }
350
+ ]
351
+ }.to_json
352
+ )
353
+ expect(File).to receive(:file?).with(
354
+ File.join(Dir.getwd, "no_data_ex.config")
355
+ ).and_return(true)
356
+ expect(File).to receive(:open).with(
357
+ File.join(Dir.getwd, "no_data_ex.config")
358
+ ).and_return(no_data_ex)
359
+ expect(File).to receive(:file?).with(
360
+ "config/tcell_agent_payloads.config"
361
+ ).and_return(false)
362
+ configuration = Configuration.new("no_data_ex.config")
363
+
364
+ expect(configuration.max_data_ex_db_records_per_request).to eq(5000)
365
+ end
366
+ end
367
+ end
368
+
369
+ end
370
+
371
+ end
@@ -64,24 +64,24 @@ module TCellAgent
64
64
  end
65
65
  it "alerts on get xss payload" do
66
66
  response = request.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
67
- expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
67
+ expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
68
68
  expect(TCellAgent.event_queue).to include(expected_as)
69
69
  end
70
70
  it "alerts on post xss payload" do
71
71
  response = request.post("/foo", :input => "x=<script>alert(1)</script>", 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6')
72
- expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"x", "remote_addr"=>"1.2.3.4", "m"=>"POST", "loc"=>"/foo", "tid"=>"a-b-c-d-e-f"}
72
+ expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"x", "remote_addr"=>"1.2.3.4", "m"=>"POST", "loc"=>"http://example.org/foo", "tid"=>"a-b-c-d-e-f"}
73
73
  expect(TCellAgent.event_queue).to include(expected_as)
74
74
  end #/it
75
75
  it "alerts on get xss payload with route_id" do
76
76
  response = request2.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E")
77
- expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
77
+ expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
78
78
  expect(TCellAgent.event_queue).to include(expected_as)
79
79
  end
80
80
  it "checks that payload is sent in xss with route_id" do
81
81
  old_uap = TCellAgent.configuration.allow_unencrypted_appsensor_payloads
82
82
  TCellAgent.configuration.allow_unencrypted_appsensor_payloads = true
83
83
  response = request2.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E")
84
- expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"<script>alert(1)</script>"}
84
+ expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"<script>alert(1)</script>"}
85
85
  TCellAgent.configuration.allow_unencrypted_appsensor_payloads = old_uap
86
86
  expect(TCellAgent.event_queue).to include(expected_as)
87
87
  end
@@ -104,7 +104,7 @@ module TCellAgent
104
104
  it "alerts on get sqli payload" do
105
105
  # ' OR '3'='3
106
106
  response = request.get("/foo?xyz=abds&def=%27%20OR%20%273%27%3D%273", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
107
- expected_as = {"event_type"=>"as", "dp"=>"sqli", "param"=>"def", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=&def=", "tid"=>"a-b-c-d-e-f"}
107
+ expected_as = {"event_type"=>"as", "dp"=>"sqli", "param"=>"def", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=&def=", "tid"=>"a-b-c-d-e-f"}
108
108
  expect(TCellAgent.event_queue).to include(expected_as)
109
109
  end
110
110
  end #/conext
@@ -124,14 +124,14 @@ module TCellAgent
124
124
  end
125
125
  it "alerts on most obvious payload" do
126
126
  response = request.get("/foo?xyz=/etc/passwd", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
127
- expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
127
+ expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
128
128
  expect(TCellAgent.event_queue).to include(expected_as)
129
129
  end
130
130
  it "checks that payload is sent" do
131
131
  old_uap = TCellAgent.configuration.allow_unencrypted_appsensor_payloads
132
132
  TCellAgent.configuration.allow_unencrypted_appsensor_payloads = true
133
133
  response = request.get("/foo?xyz=/etc/passwd", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
134
- expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"/etc/passwd"}
134
+ expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"/etc/passwd"}
135
135
  TCellAgent.configuration.allow_unencrypted_appsensor_payloads = old_uap
136
136
  expect(TCellAgent.event_queue).to include(expected_as)
137
137
  end
@@ -0,0 +1,289 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module SensorEvents
5
+
6
+ describe TCellAppSensorEventProcessor do
7
+
8
+ describe "#appsensor_event" do
9
+ before(:each) do
10
+ @app_sensor_event_process = TCellAppSensorEventProcessor.new
11
+ end
12
+
13
+ context "whitelist not present" do
14
+ context "a term that is blacklisted" do
15
+ it "should obfuscate the payload" do
16
+ event = double("event")
17
+ configuration = double(
18
+ "configuration",
19
+ whitelist_present: false,
20
+ raise_exceptions: true,
21
+ blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true})
22
+ )
23
+
24
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
25
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
26
+ nil,
27
+ "xss",
28
+ nil,
29
+ nil,
30
+ "PASSWD",
31
+ nil,
32
+ nil,
33
+ nil,
34
+ nil,
35
+ nil,
36
+ "BLACKLISTED"
37
+ ).and_return(event)
38
+ expect(TCellAgent).to receive(:send_event)
39
+
40
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
41
+ end
42
+ end
43
+
44
+ context "a term that is not blacklisted" do
45
+ it "should not obfuscate the payload" do
46
+ event = double("event")
47
+ configuration = double(
48
+ "configuration",
49
+ whitelist_present: false,
50
+ raise_exceptions: true,
51
+ blacklisted_params: double("bp", {"has_key?" => false})
52
+ )
53
+
54
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
55
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
56
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
57
+ nil,
58
+ "xss",
59
+ nil,
60
+ nil,
61
+ "PASSWD",
62
+ nil,
63
+ nil,
64
+ nil,
65
+ nil,
66
+ nil,
67
+ "%3Cscript%3Ealert(1)%3C%2Fscript%3E"
68
+ ).and_return(event)
69
+ expect(TCellAgent).to receive(:send_event)
70
+
71
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
72
+ end
73
+ end
74
+ end
75
+
76
+ context "whitelist present" do
77
+ context "a term is whitelisted" do
78
+ context "a term that is blacklisted" do
79
+ it "should obfuscate the payload" do
80
+ event = double("event")
81
+ configuration = double(
82
+ "configuration",
83
+ whitelist_present: true,
84
+ raise_exceptions: true,
85
+ blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true}),
86
+ whitelisted_params: double("wp", {"passwd" => true, "has_key?" => true})
87
+ )
88
+
89
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
90
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
91
+ nil,
92
+ "xss",
93
+ nil,
94
+ nil,
95
+ "PASSWD",
96
+ nil,
97
+ nil,
98
+ nil,
99
+ nil,
100
+ nil,
101
+ "BLACKLISTED"
102
+ ).and_return(event)
103
+ expect(TCellAgent).to receive(:send_event)
104
+
105
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
106
+ end
107
+ end
108
+
109
+ context "a term that is not blacklisted" do
110
+ it "should not obfuscate the payload" do
111
+ event = double("event")
112
+ configuration = double(
113
+ "configuration",
114
+ whitelist_present: true,
115
+ raise_exceptions: true,
116
+ blacklisted_params: double("bp", {"has_key?" => false}),
117
+ whitelisted_params: double("wp", {"passwd" => true, "has_key?" => true})
118
+ )
119
+
120
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
121
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
122
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
123
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
124
+ nil,
125
+ "xss",
126
+ nil,
127
+ nil,
128
+ "PASSWD",
129
+ nil,
130
+ nil,
131
+ nil,
132
+ nil,
133
+ nil,
134
+ "%3Cscript%3Ealert(1)%3C%2Fscript%3E"
135
+ ).and_return(event)
136
+ expect(TCellAgent).to receive(:send_event)
137
+
138
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
139
+ end
140
+ end
141
+ end
142
+
143
+ context "a term is not whitelisted" do
144
+ context "a term that is blacklisted" do
145
+ it "should obfuscate the payload" do
146
+ event = double("event")
147
+ configuration = double(
148
+ "configuration",
149
+ whitelist_present: true,
150
+ raise_exceptions: true,
151
+ blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true}),
152
+ whitelisted_params: double("wp", {"has_key?" => false})
153
+ )
154
+
155
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
156
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
157
+ nil,
158
+ "xss",
159
+ nil,
160
+ nil,
161
+ "PASSWD",
162
+ nil,
163
+ nil,
164
+ nil,
165
+ nil,
166
+ nil,
167
+ "BLACKLISTED"
168
+ ).and_return(event)
169
+ expect(TCellAgent).to receive(:send_event)
170
+
171
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
172
+ end
173
+ end
174
+
175
+ context "a term that is not blacklisted" do
176
+ it "should obfuscate the payload" do
177
+ event = double("event")
178
+ configuration = double(
179
+ "configuration",
180
+ whitelist_present: true,
181
+ raise_exceptions: true,
182
+ blacklisted_params: double("bp", {"has_key?" => false}),
183
+ whitelisted_params: double("wp", {"has_key?" => false})
184
+ )
185
+
186
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
187
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
188
+ expect(TCellAgent).to receive(:configuration).and_return(configuration)
189
+ expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
190
+ nil,
191
+ "xss",
192
+ nil,
193
+ nil,
194
+ "PASSWD",
195
+ nil,
196
+ nil,
197
+ nil,
198
+ nil,
199
+ nil,
200
+ "NOT_WHITELISTED"
201
+ ).and_return(event)
202
+ expect(TCellAgent).to receive(:send_event)
203
+
204
+ @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ describe "#for_params" do
212
+ context "with body_params" do
213
+ it "should iterate over body params" do
214
+ app_sensor_event_process = TCellAppSensorEventProcessor.new
215
+ app_sensor_event_process.request_content_length = 67
216
+ app_sensor_event_process.request_content_type = "application/json"
217
+ app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
218
+
219
+ expect(app_sensor_event_process.body_params).to eq({"username"=>"tester","password"=>"pass"})
220
+
221
+ iterated_over = {}
222
+
223
+ app_sensor_event_process.for_params do |method, param_name, param_value|
224
+ iterated_over[param_name] = param_value
225
+ end
226
+
227
+ expect(iterated_over).to eq({"username"=>"tester", "password"=>"pass"})
228
+ end
229
+ end
230
+ end
231
+
232
+ describe "#body_params" do
233
+ context "with text/html content type" do
234
+ it "should set the body params to empty" do
235
+ app_sensor_event_process = TCellAppSensorEventProcessor.new
236
+ app_sensor_event_process.request_content_length = 67
237
+ app_sensor_event_process.request_content_type = "text/html"
238
+ app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
239
+
240
+ expect(app_sensor_event_process.body_params).to eq({})
241
+ end
242
+ end
243
+
244
+ context "with application/json content type" do
245
+ before(:each) do
246
+ @app_sensor_event_process = TCellAppSensorEventProcessor.new
247
+ @app_sensor_event_process.request_content_length = 67
248
+ @app_sensor_event_process.request_content_type = "application/json"
249
+ end
250
+
251
+ context "with empty request body" do
252
+ it "should set the body params to empty" do
253
+ @app_sensor_event_process.request_body = nil
254
+
255
+ expect(@app_sensor_event_process.body_params).to eq({})
256
+ end
257
+ end
258
+
259
+ context "with bad json in the body" do
260
+ it "should set the body params to empty" do
261
+ @app_sensor_event_process.request_body = '{"username":"tester""password":"pass"}'
262
+
263
+ expect(@app_sensor_event_process.body_params).to eq({})
264
+ end
265
+ end
266
+
267
+ context "with valid json in the body" do
268
+ it "should set the body params" do
269
+ @app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
270
+
271
+ expect(@app_sensor_event_process.body_params).to eq({"username"=>"tester","password"=>"pass"})
272
+ end
273
+ end
274
+
275
+ context "with a json body that's too big" do
276
+ it "should set the body params to empty" do
277
+ @app_sensor_event_process.request_content_length = 2000000
278
+ @app_sensor_event_process.request_body = '{"username":"tester""password":"pass"}'
279
+
280
+ expect(@app_sensor_event_process.body_params).to eq({})
281
+ end
282
+ end
283
+ end
284
+ end
285
+
286
+ end
287
+
288
+ end
289
+ end
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.10
4
+ version: 0.2.11
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-08 00:00:00.000000000 Z
11
+ date: 2016-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -234,6 +234,7 @@ files:
234
234
  - spec/lib/tcell_agent/agent/static_agent_spec.rb
235
235
  - spec/lib/tcell_agent/api/api_spec.rb
236
236
  - spec/lib/tcell_agent/appsensor_spec.rb
237
+ - spec/lib/tcell_agent/configuration_spec.rb
237
238
  - spec/lib/tcell_agent/instrumentation_spec.rb
238
239
  - spec/lib/tcell_agent/policies/appsensor_policy_spec.rb
239
240
  - spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb
@@ -252,6 +253,7 @@ files:
252
253
  - spec/lib/tcell_agent/rails_spec.rb
253
254
  - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
254
255
  - spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb
256
+ - spec/lib/tcell_agent/sensor_events/tcell_app_sensor_event_processor_spec.rb
255
257
  - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
256
258
  - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
257
259
  - spec/lib/tcell_agent/utils/bounded_queue_spec.rb
@@ -338,6 +340,7 @@ test_files:
338
340
  - spec/lib/tcell_agent/agent/static_agent_spec.rb
339
341
  - spec/lib/tcell_agent/api/api_spec.rb
340
342
  - spec/lib/tcell_agent/appsensor_spec.rb
343
+ - spec/lib/tcell_agent/configuration_spec.rb
341
344
  - spec/lib/tcell_agent/instrumentation_spec.rb
342
345
  - spec/lib/tcell_agent/policies/appsensor_policy_spec.rb
343
346
  - spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb
@@ -356,6 +359,7 @@ test_files:
356
359
  - spec/lib/tcell_agent/rails_spec.rb
357
360
  - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
358
361
  - spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb
362
+ - spec/lib/tcell_agent/sensor_events/tcell_app_sensor_event_processor_spec.rb
359
363
  - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
360
364
  - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
361
365
  - spec/lib/tcell_agent/utils/bounded_queue_spec.rb