tcell_agent 0.2.18 → 0.2.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +11 -0
  3. data/lib/tcell_agent/configuration.rb +8 -1
  4. data/lib/tcell_agent/instrumentation.rb +14 -10
  5. data/lib/tcell_agent/logger.rb +23 -23
  6. data/lib/tcell_agent/policies/appsensor/database_sensor.rb +61 -0
  7. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +10 -2
  8. data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +66 -0
  9. data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +11 -3
  10. data/lib/tcell_agent/policies/appsensor/size_sensor.rb +6 -5
  11. data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +47 -0
  12. data/lib/tcell_agent/policies/appsensor_policy.rb +68 -5
  13. data/lib/tcell_agent/policies/patches_policy.rb +2 -2
  14. data/lib/tcell_agent/rails.rb +3 -0
  15. data/lib/tcell_agent/rails/auth/authlogic.rb +2 -2
  16. data/lib/tcell_agent/rails/auth/devise.rb +4 -4
  17. data/lib/tcell_agent/rails/better_ip.rb +36 -0
  18. data/lib/tcell_agent/rails/csrf_exception.rb +30 -0
  19. data/lib/tcell_agent/rails/dlp.rb +38 -76
  20. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +5 -5
  21. data/lib/tcell_agent/rails/middleware/context_middleware.rb +6 -4
  22. data/lib/tcell_agent/rails/middleware/global_middleware.rb +7 -7
  23. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +15 -15
  24. data/lib/tcell_agent/rails/path_parameters_setter.rb +43 -0
  25. data/lib/tcell_agent/rails/routes.rb +4 -4
  26. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +11 -6
  27. data/lib/tcell_agent/version.rb +1 -1
  28. data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +165 -0
  29. data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +432 -0
  30. data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +4 -4
  31. data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +99 -24
  32. data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +4 -4
  33. data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +156 -0
  34. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +175 -0
  35. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +79 -0
  36. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +76 -0
  37. metadata +16 -2
@@ -40,6 +40,16 @@ module TCellAgent
40
40
  expect(sensor.series_500_enabled).to eq(true)
41
41
  end
42
42
  end
43
+
44
+ context "setting excluded_route_ids on sensor" do
45
+ it "should have excluded_route_ids" do
46
+ sensor = ResponseCodesSensor.new({"exclude_routes" => ["excluded_route_id"]})
47
+ expect(sensor.enabled).to eq(false)
48
+ expect(sensor.series_400_enabled).to eq(false)
49
+ expect(sensor.series_500_enabled).to eq(false)
50
+ expect(sensor.excluded_route_ids).to eq({"excluded_route_id" => true})
51
+ end
52
+ end
43
53
  end
44
54
 
45
55
  context "#check" do
@@ -62,19 +72,50 @@ module TCellAgent
62
72
 
63
73
  context "with enabled sensor" do
64
74
  context "with 200 response code" do
75
+ before(:each) do
76
+ @sensor = ResponseCodesSensor.new({"enabled" => true})
77
+
78
+ @meta = TCellAgent::SensorEvents::AppSensorMetaEvent.new
79
+ @meta.remote_address = "remote_address"
80
+ @meta.method = "get"
81
+ @meta.location = "location"
82
+ @meta.route_id = "route_id"
83
+ @meta.session_id = "session_id"
84
+ @meta.user_id = "user_id"
85
+ @meta.transaction_id = "transaction_id"
86
+ end
87
+
65
88
  it "should not send an event" do
66
- sensor = ResponseCodesSensor.new({"enabled" => true})
67
- meta = TCellAgent::SensorEvents::AppSensorMetaEvent.new
68
- meta.remote_address = "remote_address"
69
- meta.method = "get"
70
- meta.location = "location"
71
- meta.route_id = "route_id"
72
- meta.session_id = "session_id"
73
- meta.user_id = "user_id"
74
- meta.transaction_id = "transaction_id"
89
+ expect(@sensor).to_not receive(:send_event)
90
+ @sensor.check(@meta, 200)
91
+ end
75
92
 
76
- expect(sensor).to_not receive(:send_event)
77
- sensor.check(meta, 200)
93
+ context "no excluded routes" do
94
+ it "should not send an event" do
95
+ @sensor.excluded_route_ids = {}
96
+
97
+ expect(@sensor).to_not receive(:send_event)
98
+ @sensor.check(@meta, 200)
99
+ end
100
+ end
101
+
102
+ context "has excluded routes" do
103
+ context "route id matches" do
104
+ it "should not send an event" do
105
+ @sensor.excluded_route_ids = {"route_id" => true}
106
+
107
+ expect(@sensor).to_not receive(:send_event)
108
+ @sensor.check(@meta, 200)
109
+ end
110
+ end
111
+ context "route id does not match" do
112
+ it "should not send an event" do
113
+ @sensor.excluded_route_ids = {"unmatching_route_id" => true}
114
+
115
+ expect(@sensor).to_not receive(:send_event)
116
+ @sensor.check(@meta, 200)
117
+ end
118
+ end
78
119
  end
79
120
  end
80
121
 
@@ -119,24 +160,58 @@ module TCellAgent
119
160
 
120
161
  context "with enabled series_400_enabled" do
121
162
  context "with 400 response code" do
122
- it "should send an event" do
123
- sensor = ResponseCodesSensor.new({
163
+ before(:each) do
164
+ @sensor = ResponseCodesSensor.new({
124
165
  "enabled" => true,
125
166
  "series_400_enabled" => true
126
167
  })
127
- meta = TCellAgent::SensorEvents::AppSensorMetaEvent.new
128
- meta.remote_address = "remote_address"
129
- meta.method = "get"
130
- meta.location = "location"
131
- meta.route_id = "route_id"
132
- meta.session_id = "session_id"
133
- meta.user_id = "user_id"
134
- meta.transaction_id = "transaction_id"
168
+ @meta = TCellAgent::SensorEvents::AppSensorMetaEvent.new
169
+ @meta.remote_address = "remote_address"
170
+ @meta.method = "get"
171
+ @meta.location = "location"
172
+ @meta.route_id = "route_id"
173
+ @meta.session_id = "session_id"
174
+ @meta.user_id = "user_id"
175
+ @meta.transaction_id = "transaction_id"
176
+ end
135
177
 
136
- expect(sensor).to receive(:send_event).with(
137
- meta, ResponseCodesSensor::RESPONSE_CODE_DP_DICT[4], "400", nil
178
+ it "should send an event" do
179
+ expect(@sensor).to receive(:send_event).with(
180
+ @meta, ResponseCodesSensor::RESPONSE_CODE_DP_DICT[4], "400", nil
138
181
  )
139
- sensor.check(meta, 400)
182
+ @sensor.check(@meta, 400)
183
+ end
184
+
185
+ context "no excluded routes" do
186
+ it "should send an event" do
187
+ @sensor.excluded_route_ids = {}
188
+
189
+ expect(@sensor).to receive(:send_event).with(
190
+ @meta, ResponseCodesSensor::RESPONSE_CODE_DP_DICT[4], "400", nil
191
+ )
192
+ @sensor.check(@meta, 400)
193
+ end
194
+ end
195
+
196
+ context "has excluded routes" do
197
+ context "route id matches" do
198
+ it "should not send an event" do
199
+ @sensor.excluded_route_ids = {"route_id" => true}
200
+
201
+ expect(@sensor).to_not receive(:send_event)
202
+ @sensor.check(@meta, 400)
203
+ end
204
+ end
205
+ context "route id does not match" do
206
+ it "should send an event" do
207
+ @sensor.excluded_route_ids = {"unmatching_route_id" => true}
208
+
209
+ expect(@sensor).to receive(:send_event).with(
210
+ @meta, ResponseCodesSensor::RESPONSE_CODE_DP_DICT[4], "400", nil
211
+ )
212
+ @sensor.check(@meta, 400)
213
+ end
214
+ end
140
215
  end
141
216
  end
142
217
  end
@@ -10,7 +10,7 @@ module TCellAgent
10
10
  sensor = ResponseSizeSensor.new
11
11
  expect(sensor.enabled).to eq(false)
12
12
  expect(sensor.limit).to eq(2097152)
13
- expect(sensor.exclude_routes).to eq({})
13
+ expect(sensor.excluded_route_ids).to eq({})
14
14
  expect(sensor.dp_code).to eq(ResponseSizeSensor::DP_UNUSUAL_RESPONSE_SIZE)
15
15
  end
16
16
  end
@@ -20,7 +20,7 @@ module TCellAgent
20
20
  sensor = ResponseSizeSensor.new({"enabled" => true})
21
21
  expect(sensor.enabled).to eq(true)
22
22
  expect(sensor.limit).to eq(2097152)
23
- expect(sensor.exclude_routes).to eq({})
23
+ expect(sensor.excluded_route_ids).to eq({})
24
24
  expect(sensor.dp_code).to eq(ResponseSizeSensor::DP_UNUSUAL_RESPONSE_SIZE)
25
25
  end
26
26
  end
@@ -30,7 +30,7 @@ module TCellAgent
30
30
  sensor = ResponseSizeSensor.new({"limit" => 1})
31
31
  expect(sensor.enabled).to eq(false)
32
32
  expect(sensor.limit).to eq(1)
33
- expect(sensor.exclude_routes).to eq({})
33
+ expect(sensor.excluded_route_ids).to eq({})
34
34
  expect(sensor.dp_code).to eq(ResponseSizeSensor::DP_UNUSUAL_RESPONSE_SIZE)
35
35
  end
36
36
  end
@@ -40,7 +40,7 @@ module TCellAgent
40
40
  sensor = ResponseSizeSensor.new({"exclude_routes" => ["1", "10", "20"]})
41
41
  expect(sensor.enabled).to eq(false)
42
42
  expect(sensor.limit).to eq(2097152)
43
- expect(sensor.exclude_routes).to eq({"1"=>true, "10"=>true, "20"=>true})
43
+ expect(sensor.excluded_route_ids).to eq({"1"=>true, "10"=>true, "20"=>true})
44
44
  expect(sensor.dp_code).to eq(ResponseSizeSensor::DP_UNUSUAL_RESPONSE_SIZE)
45
45
  end
46
46
  end
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Policies
5
+
6
+ describe UserAgentSensor do
7
+ context "#initialize" do
8
+ context "default sensor" do
9
+ it "should have properties set to defaults" do
10
+ sensor = UserAgentSensor.new
11
+ expect(sensor.enabled).to eq(false)
12
+ expect(sensor.empty_enabled).to eq(false)
13
+ expect(UserAgentSensor::DP_CODE).to eq("uaempty")
14
+ end
15
+ end
16
+
17
+ context "setting enabled on sensor" do
18
+ it "should have properties set to defaults" do
19
+ sensor = UserAgentSensor.new({"enabled" => true, "empty_enabled" => false})
20
+ expect(sensor.enabled).to eq(true)
21
+ expect(sensor.empty_enabled).to eq(false)
22
+ end
23
+ end
24
+
25
+ context "setting empty_enabled on sensor" do
26
+ it "should have properties set to defaults" do
27
+ sensor = UserAgentSensor.new({"enabled" => false, "empty_enabled" => true})
28
+ expect(sensor.enabled).to eq(false)
29
+ expect(sensor.empty_enabled).to eq(true)
30
+ end
31
+ end
32
+
33
+ context "setting exclude_routes on sensor" do
34
+ it "should exclude_routes set" do
35
+ sensor = UserAgentSensor.new({
36
+ "enabled" => false,
37
+ "empty_enabled" => true,
38
+ "exclude_routes" => ["route_id"]
39
+ })
40
+ expect(sensor.enabled).to eq(false)
41
+ expect(sensor.empty_enabled).to eq(true)
42
+ expect(sensor.excluded_route_ids).to eq({"route_id" => true})
43
+ end
44
+ end
45
+ end
46
+
47
+ context "#check" do
48
+ before(:each) do
49
+ @meta = TCellAgent::SensorEvents::AppSensorMetaEvent.new
50
+ @meta.remote_address = "remote_address"
51
+ @meta.method = "get"
52
+ @meta.location = "location"
53
+ @meta.route_id = "route_id"
54
+ @meta.session_id = "session_id"
55
+ @meta.user_id = "user_id"
56
+ @meta.transaction_id = "transaction_id"
57
+ end
58
+
59
+ context "with disabled sensor" do
60
+ context "with empty user agent" do
61
+ it "should not send event" do
62
+ sensor = UserAgentSensor.new({"enabled" => false, "empty_enabled" => false})
63
+ @meta.user_agent = nil
64
+
65
+ expect(sensor).to_not receive(:send_event)
66
+ sensor.check(@meta)
67
+ end
68
+ end
69
+
70
+ context "with user agent present" do
71
+ it "should not send event" do
72
+ sensor = UserAgentSensor.new({"enabled" => false, "empty_enabled" => false})
73
+ @meta.user_agent = "Mozilla"
74
+
75
+ expect(sensor).to_not receive(:send_event)
76
+ sensor.check(@meta)
77
+ end
78
+ end
79
+ end
80
+
81
+ context "with enabled sensor" do
82
+ before(:each) do
83
+ @sensor = UserAgentSensor.new({"enabled" => true, "empty_enabled" => true})
84
+ end
85
+
86
+ context "with empty user agent" do
87
+ it "should send event" do
88
+ @meta.user_agent = ""
89
+
90
+ expect(@sensor).to receive(:send_event).with(
91
+ @meta, UserAgentSensor::DP_CODE, nil, nil
92
+ )
93
+ @sensor.check(@meta)
94
+ end
95
+
96
+ context "no excluded routes" do
97
+ it "should send an event" do
98
+ @meta.user_agent = ""
99
+ @sensor.excluded_route_ids = {}
100
+
101
+ expect(@sensor).to receive(:send_event).with(
102
+ @meta, UserAgentSensor::DP_CODE, nil, nil
103
+ )
104
+ @sensor.check(@meta)
105
+ end
106
+ end
107
+
108
+ context "has excluded routes" do
109
+ context "route id matches" do
110
+ it "should not send an event" do
111
+ @meta.user_agent = ""
112
+ @sensor.excluded_route_ids = {"route_id" => true}
113
+
114
+ expect(@sensor).to_not receive(:send_event)
115
+ @sensor.check(@meta)
116
+ end
117
+ end
118
+ context "route id does not match" do
119
+ it "should send an event" do
120
+ @meta.user_agent = ""
121
+ @sensor.excluded_route_ids = {"nonmatching" => true}
122
+
123
+ expect(@sensor).to receive(:send_event).with(
124
+ @meta, UserAgentSensor::DP_CODE, nil, nil
125
+ )
126
+ @sensor.check(@meta)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ context "with blank space user agent" do
133
+ it "should not send event" do
134
+ @meta.user_agent = "\n \t \s"
135
+
136
+ expect(@sensor).to receive(:send_event).with(
137
+ @meta, UserAgentSensor::DP_CODE, nil, nil
138
+ )
139
+ @sensor.check(@meta)
140
+ end
141
+ end
142
+
143
+ context "with user agent present" do
144
+ it "should not send event" do
145
+ @meta.user_agent = "Mozilla"
146
+
147
+ expect(@sensor).to_not receive(:send_event)
148
+ @sensor.check(@meta)
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ end
156
+ end
@@ -144,6 +144,21 @@ module TCellAgent
144
144
  end
145
145
  end
146
146
 
147
+ context "setting excluded_route_ids on sensor" do
148
+ it "should have excluded_route_ids" do
149
+ sensor = XssSensor.new({"exclude_routes" => ["excluded_route_id"]})
150
+ expect(sensor.enabled).to eq(false)
151
+ expect(sensor.libinjection).to eq(false)
152
+ expect(sensor.detection_point).to eq("xss")
153
+ expect(sensor.exclude_headers).to eq(false)
154
+ expect(sensor.exclude_forms).to eq(false)
155
+ expect(sensor.exclude_cookies).to eq(false)
156
+ expect(sensor.exclusions).to eq({})
157
+ expect(sensor.active_pattern_ids).to eq({})
158
+ expect(sensor.v1_compatability_enabled).to eq(false)
159
+ expect(sensor.excluded_route_ids).to eq({"excluded_route_id" => true})
160
+ end
161
+ end
147
162
  end
148
163
 
149
164
  describe "#find_vulnerability" do
@@ -211,6 +226,7 @@ module TCellAgent
211
226
  before(:each) do
212
227
  @sensor = XssSensor.new({"enabled" => true})
213
228
  end
229
+
214
230
  context "param has NO vulnerability" do
215
231
  it "should return false" do
216
232
  sensor = XssSensor.new({"enabled" => false})
@@ -218,6 +234,34 @@ module TCellAgent
218
234
 
219
235
  expect(result).to eq(false)
220
236
  end
237
+
238
+ context "no excluded routes" do
239
+ it "should return false" do
240
+ sensor = XssSensor.new({"enabled" => false, "exclude_routes" => []})
241
+ result = sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
242
+
243
+ expect(result).to eq(false)
244
+ end
245
+ end
246
+
247
+ context "has excluded routes" do
248
+ context "route id matches" do
249
+ it "should return false" do
250
+ sensor = XssSensor.new({"enabled" => false, "exclude_routes" => ["route_id"]})
251
+ result = sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
252
+
253
+ expect(result).to eq(false)
254
+ end
255
+ end
256
+ context "route id does not match" do
257
+ it "should return false" do
258
+ sensor = XssSensor.new({"enabled" => false, "exclude_routes" => ["unmatching_route_id"]})
259
+ result = sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
260
+
261
+ expect(result).to eq(false)
262
+ end
263
+ end
264
+ end
221
265
  end
222
266
 
223
267
  context "param has a vulnerability" do
@@ -235,6 +279,55 @@ module TCellAgent
235
279
 
236
280
  expect(result).to eq(false)
237
281
  end
282
+
283
+ context "no excluded routes" do
284
+ it "should return false" do
285
+ @sensor.exclude_forms = true
286
+ @sensor.exclude_cookies = false
287
+ @sensor.excluded_route_ids = {}
288
+
289
+ expect(TCellAgent).to_not receive(:configuration)
290
+ expect(@sensor).to_not receive(:find_vulnerability)
291
+ expect(@sensor).to_not receive(:send_event)
292
+
293
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
294
+
295
+ expect(result).to eq(false)
296
+ end
297
+ end
298
+
299
+ context "has excluded routes" do
300
+ context "route id matches" do
301
+ it "should return false" do
302
+ @sensor.exclude_forms = true
303
+ @sensor.exclude_cookies = false
304
+ @sensor.excluded_route_ids = {"route_id" => true}
305
+
306
+ expect(TCellAgent).to_not receive(:configuration)
307
+ expect(@sensor).to_not receive(:find_vulnerability)
308
+ expect(@sensor).to_not receive(:send_event)
309
+
310
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
311
+
312
+ expect(result).to eq(false)
313
+ end
314
+ end
315
+ context "route id does not match" do
316
+ it "should return false" do
317
+ @sensor.exclude_forms = true
318
+ @sensor.exclude_cookies = false
319
+ @sensor.excluded_route_ids = {"unmatching_route_id" => true}
320
+
321
+ expect(TCellAgent).to_not receive(:configuration)
322
+ expect(@sensor).to_not receive(:find_vulnerability)
323
+ expect(@sensor).to_not receive(:send_event)
324
+
325
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
326
+
327
+ expect(result).to eq(false)
328
+ end
329
+ end
330
+ end
238
331
  end
239
332
 
240
333
  context "exclude cookies sensor" do
@@ -497,6 +590,88 @@ module TCellAgent
497
590
  end
498
591
  end
499
592
  end
593
+
594
+ context "no excluded routes" do
595
+ it "should return true" do
596
+ @sensor.exclude_forms = false
597
+ @sensor.exclude_cookies = true
598
+ @sensor.excluded_route_ids = {}
599
+ configuration = double(
600
+ "configuration",
601
+ allow_unencrypted_appfirewall_payloads_logging: false,
602
+ allow_unencrypted_appfirewall_payloads: true,
603
+ blacklisted_params: {},
604
+ whitelist_present: false
605
+ )
606
+
607
+ expect(@sensor).to receive(:find_vulnerability).and_return(
608
+ {"param" => "vuln_param", "value" => "vuln_value", "pattern" => "1"}
609
+ )
610
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
611
+ expect(@sensor).to receive(:send_event).with(
612
+ @meta,
613
+ "xss",
614
+ "vuln_param",
615
+ {"t" => XssSensor::GET_PARAM}.to_json,
616
+ "vuln_value",
617
+ "1"
618
+ )
619
+
620
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
621
+
622
+ expect(result).to eq(true)
623
+ end
624
+ end
625
+
626
+ context "has excluded routes" do
627
+ context "route id matches" do
628
+ it "should return false" do
629
+ @sensor.exclude_forms = false
630
+ @sensor.exclude_cookies = true
631
+ @sensor.excluded_route_ids = {"route_id" => true}
632
+
633
+ expect(TCellAgent).to_not receive(:configuration)
634
+ expect(@sensor).to_not receive(:find_vulnerability)
635
+ expect(@sensor).to_not receive(:send_event)
636
+
637
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
638
+
639
+ expect(result).to eq(false)
640
+ end
641
+ end
642
+
643
+ context "route id does not match" do
644
+ it "should return true" do
645
+ @sensor.exclude_forms = false
646
+ @sensor.exclude_cookies = true
647
+ @sensor.excluded_route_ids = {"unmatching_route_id" => true}
648
+ configuration = double(
649
+ "configuration",
650
+ allow_unencrypted_appfirewall_payloads_logging: false,
651
+ allow_unencrypted_appfirewall_payloads: true,
652
+ blacklisted_params: {},
653
+ whitelist_present: false
654
+ )
655
+
656
+ expect(@sensor).to receive(:find_vulnerability).and_return(
657
+ {"param" => "vuln_param", "value" => "vuln_value", "pattern" => "1"}
658
+ )
659
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
660
+ expect(@sensor).to receive(:send_event).with(
661
+ @meta,
662
+ "xss",
663
+ "vuln_param",
664
+ {"t" => XssSensor::GET_PARAM}.to_json,
665
+ "vuln_value",
666
+ "1"
667
+ )
668
+
669
+ result = @sensor.check(XssSensor::GET_PARAM, @meta, "param_name", "param_value")
670
+
671
+ expect(result).to eq(true)
672
+ end
673
+ end
674
+ end
500
675
  end
501
676
  end
502
677