tcell_agent 0.2.19 → 0.2.21
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 +4 -4
- data/LICENSE_libinjection +32 -0
- data/Rakefile +14 -1
- data/ext/libinjection/extconf.rb +3 -0
- data/ext/libinjection/libinjection.h +65 -0
- data/ext/libinjection/libinjection_html5.c +847 -0
- data/ext/libinjection/libinjection_html5.h +54 -0
- data/ext/libinjection/libinjection_sqli.c +2317 -0
- data/ext/libinjection/libinjection_sqli.h +295 -0
- data/ext/libinjection/libinjection_sqli_data.h +9004 -0
- data/ext/libinjection/libinjection_wrap.c +3525 -0
- data/ext/libinjection/libinjection_xss.c +531 -0
- data/ext/libinjection/libinjection_xss.h +21 -0
- data/lib/tcell_agent/configuration.rb +0 -48
- data/lib/tcell_agent/logger.rb +1 -0
- data/lib/tcell_agent/policies/appsensor/database_sensor.rb +8 -20
- data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +30 -46
- data/lib/tcell_agent/policies/appsensor/login_sensor.rb +1 -4
- data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +8 -22
- data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +143 -0
- data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +3 -1
- data/lib/tcell_agent/policies/appsensor/sensor.rb +21 -2
- data/lib/tcell_agent/policies/appsensor/size_sensor.rb +3 -1
- data/lib/tcell_agent/policies/appsensor/sqli_sensor.rb +9 -0
- data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +1 -5
- data/lib/tcell_agent/policies/appsensor/xss_sensor.rb +9 -1
- data/lib/tcell_agent/policies/appsensor_policy.rb +40 -19
- data/lib/tcell_agent/policies/http_redirect_policy.rb +12 -2
- data/lib/tcell_agent/rails/csrf_exception.rb +1 -1
- data/lib/tcell_agent/rails/dlp.rb +98 -76
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -2
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +2 -2
- data/lib/tcell_agent/rails/on_start.rb +53 -20
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +12 -19
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +7 -2
- data/lib/tcell_agent/sensor_events/sensor.rb +10 -11
- data/lib/tcell_agent/sensor_events/server_agent.rb +17 -12
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +148 -139
- data/lib/tcell_agent/utils/params.rb +24 -21
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/configuration_spec.rb +0 -179
- data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +6 -4
- data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +31 -22
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_apply_spec.rb +466 -0
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_from_json_spec.rb +890 -0
- data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_log_spec.rb +484 -0
- data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +4 -3
- data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +4 -4
- data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/appsensor/sqli_sensor_spec.rb +85 -0
- data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +36 -16
- data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +188 -312
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +61 -0
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +18 -11
- data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +14 -15
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +1 -1
- data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +6 -5
- data/spec/lib/tcell_agent/utils/params_spec.rb +28 -108
- data/tcell_agent.gemspec +21 -1
- metadata +37 -4
@@ -5,7 +5,19 @@ require 'tcell_agent/utils/params'
|
|
5
5
|
module TCellAgent
|
6
6
|
module Policies
|
7
7
|
class InjectionSensor < Sensor
|
8
|
-
|
8
|
+
GET_PARAM = TCellAgent::Utils::Params::GET_PARAM
|
9
|
+
POST_PARAM = TCellAgent::Utils::Params::POST_PARAM
|
10
|
+
JSON_PARAM = TCellAgent::Utils::Params::JSON_PARAM
|
11
|
+
COOKIE_PARAM = TCellAgent::Utils::Params::COOKIE_PARAM
|
12
|
+
URI_PARAM = TCellAgent::Utils::Params::URI_PARAM
|
13
|
+
|
14
|
+
PARAM_TYPE_TO_L = {
|
15
|
+
GET_PARAM => 'query',
|
16
|
+
POST_PARAM => 'body',
|
17
|
+
JSON_PARAM => 'body',
|
18
|
+
URI_PARAM => 'uri',
|
19
|
+
COOKIE_PARAM => 'cookie'
|
20
|
+
}
|
9
21
|
|
10
22
|
attr_accessor :enabled, :detection_point, :exclude_headers, :exclude_forms,
|
11
23
|
:exclude_cookies, :exclusions, :active_pattern_ids, :v1_compatability_enabled,
|
@@ -54,17 +66,19 @@ module TCellAgent
|
|
54
66
|
rules = get_ruleset
|
55
67
|
return nil unless rules
|
56
68
|
|
57
|
-
|
58
|
-
rules.check_violation(name, value, @active_pattern_ids, @v1_compatability_enabled)
|
59
|
-
end
|
69
|
+
rules.check_violation(param_name, param_value, @active_pattern_ids, @v1_compatability_enabled)
|
60
70
|
end
|
61
71
|
|
62
|
-
def check(type_of_param, appsensor_meta, param_name, param_value)
|
72
|
+
def check(type_of_param, appsensor_meta, param_name, param_value, payloads_policy)
|
63
73
|
return false unless @enabled
|
64
74
|
|
65
75
|
return false if @excluded_route_ids.fetch(appsensor_meta.route_id, false)
|
66
76
|
|
67
|
-
if @exclude_forms &&
|
77
|
+
if @exclude_forms &&
|
78
|
+
(GET_PARAM == type_of_param ||
|
79
|
+
POST_PARAM == type_of_param ||
|
80
|
+
JSON_PARAM == type_of_param ||
|
81
|
+
URI_PARAM == type_of_param)
|
68
82
|
return false
|
69
83
|
end
|
70
84
|
|
@@ -76,34 +90,23 @@ module TCellAgent
|
|
76
90
|
|
77
91
|
if vuln_results
|
78
92
|
vuln_param = vuln_results["param"]
|
79
|
-
payload = nil
|
80
|
-
|
81
|
-
if TCellAgent.configuration.allow_unencrypted_appfirewall_payloads
|
82
|
-
payload = vuln_results["value"]
|
83
|
-
end
|
84
93
|
|
85
94
|
if vuln_param
|
86
|
-
|
87
|
-
|
88
|
-
payload = "BLACKLISTED"
|
95
|
+
meta = {"l" => PARAM_TYPE_TO_L[type_of_param]}
|
96
|
+
pattern = vuln_results["pattern"]
|
89
97
|
|
90
|
-
|
91
|
-
!TCellAgent.configuration.whitelisted_params.has_key?(vuln_param.downcase)
|
92
|
-
payload = "NOT_WHITELISTED"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
log_appsensor_events(type_of_param, appsensor_meta, vuln_param, vuln_results["value"])
|
97
|
-
|
98
|
-
send_event(
|
99
|
-
appsensor_meta,
|
98
|
+
payload = payloads_policy.apply(
|
100
99
|
@detection_point,
|
100
|
+
appsensor_meta,
|
101
|
+
type_of_param,
|
101
102
|
vuln_param,
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
vuln_results["value"],
|
104
|
+
meta,
|
105
|
+
pattern
|
105
106
|
)
|
106
107
|
|
108
|
+
send_event(appsensor_meta, @detection_point, vuln_param, meta, payload, pattern)
|
109
|
+
|
107
110
|
return true
|
108
111
|
end
|
109
112
|
end
|
@@ -111,25 +114,6 @@ module TCellAgent
|
|
111
114
|
return false
|
112
115
|
end
|
113
116
|
|
114
|
-
def log_appsensor_events(type_of_param, appsensor_meta, vuln_param, vuln_value)
|
115
|
-
if TCellAgent.configuration.allow_unencrypted_appfirewall_payloads_logging
|
116
|
-
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
117
|
-
appsensor_meta.location,
|
118
|
-
@detection_point,
|
119
|
-
appsensor_meta.method,
|
120
|
-
appsensor_meta.remote_address,
|
121
|
-
vuln_param,
|
122
|
-
appsensor_meta.route_id,
|
123
|
-
{"t" => type_of_param}.to_json,
|
124
|
-
appsensor_meta.session_id,
|
125
|
-
appsensor_meta.user_id,
|
126
|
-
vuln_value
|
127
|
-
)
|
128
|
-
event.post_process
|
129
|
-
TCellAgent.appfirewall_payloads_logger.info(event.to_json)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
117
|
def to_s
|
134
118
|
"<#{self.class.name} enabled: #{@enabled} dp: #{@detection_point} " +
|
135
119
|
"exclude_headers: #{@exclude_headers} exclude_forms: #{exclude_forms} " +
|
@@ -23,10 +23,7 @@ module TCellAgent
|
|
23
23
|
return unless self.enabled
|
24
24
|
|
25
25
|
if username
|
26
|
-
username = TCellAgent::SensorEvents::Util.hmac(
|
27
|
-
username,
|
28
|
-
TCellAgent::SensorEvents::Util.getHmacKey()
|
29
|
-
)
|
26
|
+
username = TCellAgent::SensorEvents::Util.hmac(username)
|
30
27
|
end
|
31
28
|
|
32
29
|
send_event(appsensor_meta, LOGIN_FAILURE_DP, username, nil)
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'tcell_agent/policies/appsensor/sensor'
|
2
|
+
|
1
3
|
module TCellAgent
|
2
4
|
module Policies
|
3
5
|
|
4
|
-
class MiscSensor
|
6
|
+
class MiscSensor < Sensor
|
5
7
|
|
6
8
|
attr_accessor :enabled, :csrf_exception_enabled, :sql_exception_enabled, :excluded_route_ids
|
7
9
|
|
@@ -22,12 +24,13 @@ module TCellAgent
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
def csrf_rejected(tcell_data)
|
27
|
+
def csrf_rejected(tcell_data, exception_class)
|
26
28
|
return unless @enabled && @csrf_exception_enabled
|
27
29
|
|
28
30
|
return if tcell_data && @excluded_route_ids.fetch(tcell_data.route_id, false)
|
29
31
|
|
30
|
-
|
32
|
+
meta = nil
|
33
|
+
send_event_from_tcell_data(tcell_data, "excsrf", exception_class.name, meta)
|
31
34
|
end
|
32
35
|
|
33
36
|
def sql_exception_detected(tcell_data, exception)
|
@@ -35,25 +38,8 @@ module TCellAgent
|
|
35
38
|
|
36
39
|
return if tcell_data && @excluded_route_ids.fetch(tcell_data.route_id, false)
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def send_event(detection_point, tcell_data)
|
42
|
-
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
43
|
-
tcell_data.uri,
|
44
|
-
detection_point,
|
45
|
-
tcell_data.request_method,
|
46
|
-
tcell_data.ip_address,
|
47
|
-
nil,
|
48
|
-
tcell_data.route_id,
|
49
|
-
nil,
|
50
|
-
tcell_data.transaction_id,
|
51
|
-
tcell_data.session_id,
|
52
|
-
tcell_data.user_id,
|
53
|
-
nil
|
54
|
-
)
|
55
|
-
|
56
|
-
TCellAgent.send_event(event)
|
41
|
+
meta = nil
|
42
|
+
send_event_from_tcell_data(tcell_data, "exsql", exception.class.name, meta)
|
57
43
|
end
|
58
44
|
|
59
45
|
def to_s
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'tcell_agent/utils/params'
|
2
|
+
|
3
|
+
module TCellAgent
|
4
|
+
module Policies
|
5
|
+
|
6
|
+
class PayloadsPolicy
|
7
|
+
PARAM_TYPE_MAP = {
|
8
|
+
TCellAgent::Utils::Params::GET_PARAM => "form",
|
9
|
+
TCellAgent::Utils::Params::POST_PARAM => "form",
|
10
|
+
TCellAgent::Utils::Params::JSON_PARAM => "form",
|
11
|
+
TCellAgent::Utils::Params::COOKIE_PARAM => "cookie"
|
12
|
+
}
|
13
|
+
|
14
|
+
attr_accessor :send_payloads, :send_blacklist, :send_whitelist, :use_send_whitelist,
|
15
|
+
:log_payloads, :log_blacklist, :log_whitelist, :use_log_whitelist
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@send_payloads = false
|
19
|
+
@log_payloads = false
|
20
|
+
|
21
|
+
@send_blacklist = {}
|
22
|
+
@log_blacklist = {}
|
23
|
+
@send_whitelist = {}
|
24
|
+
@log_whitelist = {}
|
25
|
+
|
26
|
+
@use_send_whitelist = false
|
27
|
+
@use_log_whitelist = false
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply(dp, appsensor_meta, type_of_param, vuln_param, vuln_value, meta, pattern)
|
31
|
+
payload = nil
|
32
|
+
|
33
|
+
if @send_payloads && TCellAgent.configuration.allow_unencrypted_appfirewall_payloads
|
34
|
+
|
35
|
+
blacklisted_locations = @send_blacklist[vuln_param.downcase]
|
36
|
+
param_location = PARAM_TYPE_MAP[type_of_param]
|
37
|
+
|
38
|
+
if blacklisted_locations &&
|
39
|
+
( blacklisted_locations.include?(param_location) ||
|
40
|
+
blacklisted_locations.include?("*") )
|
41
|
+
payload = "BLACKLISTED"
|
42
|
+
|
43
|
+
elsif use_send_whitelist
|
44
|
+
whitelisted_locations = @send_whitelist[vuln_param.downcase]
|
45
|
+
if whitelisted_locations &&
|
46
|
+
( whitelisted_locations.include?(param_location) ||
|
47
|
+
whitelisted_locations.include?("*") )
|
48
|
+
|
49
|
+
payload = vuln_value
|
50
|
+
|
51
|
+
else
|
52
|
+
payload = "NOT_WHITELISTED"
|
53
|
+
end
|
54
|
+
|
55
|
+
else
|
56
|
+
payload = vuln_value
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
log(dp, appsensor_meta, type_of_param, vuln_param, vuln_value, meta, pattern)
|
62
|
+
|
63
|
+
payload
|
64
|
+
end
|
65
|
+
|
66
|
+
def log(dp, appsensor_meta, type_of_param, vuln_param, vuln_value, meta, pattern)
|
67
|
+
if @log_payloads && TCellAgent.configuration.allow_unencrypted_appfirewall_payloads_logging
|
68
|
+
blacklisted_locations = @log_blacklist[vuln_param.downcase]
|
69
|
+
param_location = PARAM_TYPE_MAP[type_of_param]
|
70
|
+
|
71
|
+
if !blacklisted_locations ||
|
72
|
+
( !blacklisted_locations.include?(param_location) &&
|
73
|
+
!blacklisted_locations.include?("*") )
|
74
|
+
|
75
|
+
whitelisted_locations = @log_whitelist[vuln_param.downcase]
|
76
|
+
if !use_log_whitelist ||
|
77
|
+
(whitelisted_locations && (whitelisted_locations.include?(param_location) ||
|
78
|
+
whitelisted_locations.include?("*")))
|
79
|
+
|
80
|
+
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
81
|
+
appsensor_meta.location,
|
82
|
+
dp,
|
83
|
+
appsensor_meta.method,
|
84
|
+
appsensor_meta.remote_address,
|
85
|
+
vuln_param,
|
86
|
+
appsensor_meta.route_id,
|
87
|
+
meta,
|
88
|
+
appsensor_meta.session_id,
|
89
|
+
appsensor_meta.user_id,
|
90
|
+
vuln_value,
|
91
|
+
pattern
|
92
|
+
)
|
93
|
+
event.post_process
|
94
|
+
TCellAgent.appfirewall_payloads_logger.info(event.to_json)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.from_json(policy_json)
|
101
|
+
policy = PayloadsPolicy.new
|
102
|
+
|
103
|
+
if policy_json
|
104
|
+
payloads_json = policy_json.fetch("payloads", {})
|
105
|
+
policy.send_payloads = payloads_json.fetch("send_payloads", false)
|
106
|
+
policy.log_payloads = payloads_json.fetch("log_payloads", false)
|
107
|
+
|
108
|
+
if policy.send_payloads
|
109
|
+
payloads_json.fetch("send_blacklist", {}).each do |param_name, locations|
|
110
|
+
policy.send_blacklist[param_name.downcase] = Set.new(locations)
|
111
|
+
end
|
112
|
+
|
113
|
+
send_whitelist = payloads_json["send_whitelist"]
|
114
|
+
if send_whitelist
|
115
|
+
send_whitelist.each do |param_name, locations|
|
116
|
+
policy.send_whitelist[param_name.downcase] = Set.new(locations)
|
117
|
+
end
|
118
|
+
policy.use_send_whitelist = true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
if policy.log_payloads
|
123
|
+
payloads_json.fetch("log_blacklist", {}).each do |param_name, locations|
|
124
|
+
policy.log_blacklist[param_name.downcase] = Set.new(locations)
|
125
|
+
end
|
126
|
+
|
127
|
+
log_whitelist = payloads_json["log_whitelist"]
|
128
|
+
if log_whitelist
|
129
|
+
log_whitelist.each do |param_name, locations|
|
130
|
+
policy.log_whitelist[param_name.downcase] = Set.new(locations)
|
131
|
+
end
|
132
|
+
|
133
|
+
policy.use_log_whitelist = true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
policy
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
@@ -4,7 +4,7 @@ module TCellAgent
|
|
4
4
|
module Policies
|
5
5
|
|
6
6
|
class Sensor
|
7
|
-
def send_event(appsensor_meta, detection_point, parameter,
|
7
|
+
def send_event(appsensor_meta, detection_point, parameter, meta, payload, pattern)
|
8
8
|
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
9
9
|
appsensor_meta.location,
|
10
10
|
detection_point,
|
@@ -12,7 +12,7 @@ module TCellAgent
|
|
12
12
|
appsensor_meta.remote_address,
|
13
13
|
parameter,
|
14
14
|
appsensor_meta.route_id,
|
15
|
-
|
15
|
+
meta,
|
16
16
|
appsensor_meta.session_id,
|
17
17
|
appsensor_meta.user_id,
|
18
18
|
payload,
|
@@ -21,6 +21,25 @@ module TCellAgent
|
|
21
21
|
|
22
22
|
TCellAgent.send_event(event)
|
23
23
|
end
|
24
|
+
|
25
|
+
def send_event_from_tcell_data(tcell_data, detection_point, parameter, meta)
|
26
|
+
payload = pattern = nil
|
27
|
+
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
28
|
+
tcell_data.uri,
|
29
|
+
detection_point,
|
30
|
+
tcell_data.request_method,
|
31
|
+
tcell_data.ip_address,
|
32
|
+
parameter,
|
33
|
+
tcell_data.route_id,
|
34
|
+
meta,
|
35
|
+
tcell_data.hmac_session_id,
|
36
|
+
tcell_data.user_id,
|
37
|
+
payload,
|
38
|
+
pattern
|
39
|
+
)
|
40
|
+
|
41
|
+
TCellAgent.send_event(event)
|
42
|
+
end
|
24
43
|
end
|
25
44
|
|
26
45
|
end
|
@@ -29,7 +29,9 @@ module TCellAgent
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if content_length && content_length > @limit
|
32
|
-
|
32
|
+
param = payload = pattern = nil
|
33
|
+
meta = { "sz" => content_length }
|
34
|
+
send_event(appsensor_meta, @dp_code, param, meta, payload, pattern)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'libinjection/libinjection'
|
1
2
|
require 'tcell_agent/policies/appsensor/injection_sensor'
|
2
3
|
|
3
4
|
module TCellAgent
|
@@ -19,6 +20,14 @@ module TCellAgent
|
|
19
20
|
@libinjection = policy_json.fetch("libinjection", false)
|
20
21
|
end
|
21
22
|
end
|
23
|
+
|
24
|
+
def find_vulnerability(param_name, param_value)
|
25
|
+
if @libinjection && Libinjection.is_sqli(param_value) == 1
|
26
|
+
return {"param" => param_name, "value" => param_value, "pattern" => "li"}
|
27
|
+
end
|
28
|
+
|
29
|
+
super(param_name, param_value)
|
30
|
+
end
|
22
31
|
end
|
23
32
|
|
24
33
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
+
require 'libinjection/libinjection'
|
1
2
|
require 'tcell_agent/policies/appsensor/injection_sensor'
|
2
3
|
|
3
|
-
|
4
4
|
module TCellAgent
|
5
5
|
module Policies
|
6
6
|
|
@@ -20,6 +20,14 @@ module TCellAgent
|
|
20
20
|
@libinjection = policy_json.fetch("libinjection", false)
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
def find_vulnerability(param_name, param_value)
|
25
|
+
if @libinjection && Libinjection.is_xss(param_value) == 1
|
26
|
+
return {"param" => param_name, "value" => param_value, "pattern" => "li"}
|
27
|
+
end
|
28
|
+
|
29
|
+
super(param_name, param_value)
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
end
|
@@ -5,6 +5,7 @@ require 'tcell_agent/policies/appsensor/fpt_sensor'
|
|
5
5
|
require 'tcell_agent/policies/appsensor/login_sensor'
|
6
6
|
require 'tcell_agent/policies/appsensor/misc_sensor'
|
7
7
|
require 'tcell_agent/policies/appsensor/nullbyte_sensor'
|
8
|
+
require 'tcell_agent/policies/appsensor/payloads_policy'
|
8
9
|
require 'tcell_agent/policies/appsensor/request_size_sensor'
|
9
10
|
require 'tcell_agent/policies/appsensor/response_codes_sensor'
|
10
11
|
require 'tcell_agent/policies/appsensor/response_size_sensor'
|
@@ -12,6 +13,7 @@ require 'tcell_agent/policies/appsensor/retr_sensor'
|
|
12
13
|
require 'tcell_agent/policies/appsensor/sqli_sensor'
|
13
14
|
require 'tcell_agent/policies/appsensor/user_agent_sensor'
|
14
15
|
require 'tcell_agent/policies/appsensor/xss_sensor'
|
16
|
+
require 'tcell_agent/utils/params'
|
15
17
|
|
16
18
|
|
17
19
|
module TCellAgent
|
@@ -49,17 +51,19 @@ module TCellAgent
|
|
49
51
|
"database" => DatabaseSensor
|
50
52
|
}
|
51
53
|
|
52
|
-
attr_accessor :policy_id, :options, :enabled
|
54
|
+
attr_accessor :policy_id, :options, :payloads_policy, :enabled
|
53
55
|
|
54
56
|
def initialize
|
55
57
|
@policy_id = nil
|
56
58
|
@options = Hash.new
|
57
59
|
@enabled = false
|
60
|
+
@payloads_policy = PayloadsPolicy.new
|
58
61
|
end
|
59
62
|
|
60
63
|
def process_meta_event(appsensor_meta)
|
61
64
|
return unless @enabled
|
62
65
|
|
66
|
+
check_user_agent(appsensor_meta)
|
63
67
|
check_request_size(appsensor_meta)
|
64
68
|
check_response_size(appsensor_meta)
|
65
69
|
check_response_code(appsensor_meta)
|
@@ -76,6 +80,14 @@ module TCellAgent
|
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
83
|
+
def check_user_agent(appsensor_meta)
|
84
|
+
TCellAgent::Instrumentation.safe_block("AppSensor Checking User Agent") do
|
85
|
+
if self.options.has_key?("ua")
|
86
|
+
self.options["ua"].check(appsensor_meta)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
79
91
|
def check_request_size(appsensor_meta)
|
80
92
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing Response Size") do
|
81
93
|
if self.options.has_key?("req_size")
|
@@ -101,66 +113,65 @@ module TCellAgent
|
|
101
113
|
end
|
102
114
|
|
103
115
|
def check_param_for_injections(param_type, appsensor_meta, param_name, param_value)
|
104
|
-
return if @options["xss"].check(param_type, appsensor_meta, param_name, param_value)
|
105
|
-
return if @options["sqli"].check(param_type, appsensor_meta, param_name, param_value)
|
116
|
+
return if @options["xss"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
117
|
+
return if @options["sqli"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
106
118
|
if InjectionSensor::COOKIE_PARAM != param_type
|
107
|
-
return if @options["cmdi"].check(param_type, appsensor_meta, param_name, param_value)
|
119
|
+
return if @options["cmdi"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
108
120
|
end
|
109
121
|
if InjectionSensor::COOKIE_PARAM != param_type
|
110
|
-
return if @options["fpt"].check(param_type, appsensor_meta, param_name, param_value)
|
122
|
+
return if @options["fpt"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
111
123
|
end
|
112
124
|
if InjectionSensor::COOKIE_PARAM != param_type
|
113
|
-
return if @options["nullbyte"].check(param_type, appsensor_meta, param_name, param_value)
|
125
|
+
return if @options["nullbyte"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
114
126
|
end
|
115
127
|
if InjectionSensor::POST_PARAM != param_type && InjectionSensor::JSON_PARAM != param_type
|
116
|
-
return if @options["retr"].check(param_type, appsensor_meta, param_name, param_value)
|
128
|
+
return if @options["retr"].check(param_type, appsensor_meta, param_name, param_value, @payloads_policy)
|
117
129
|
end
|
118
130
|
end
|
119
131
|
|
120
132
|
def check_params_for_injections(appsensor_meta)
|
121
|
-
path_param_type =
|
122
|
-
if (appsensor_meta.method || "get").to_s.downcase == "get"
|
123
|
-
InjectionSensor::GET_PARAM
|
124
|
-
else
|
125
|
-
InjectionSensor::POST_PARAM
|
126
|
-
end
|
127
133
|
|
128
|
-
(appsensor_meta.path_parameters || {}).each do |param_name, param_value|
|
134
|
+
TCellAgent::Utils::Params.flatten(appsensor_meta.path_parameters || {}).each do |param_name, param_value|
|
129
135
|
TCellAgent::Instrumentation.safe_block("AppSensor Check Path Params injections") do
|
136
|
+
param_name = param_name[-1]
|
130
137
|
next if param_name == :controller || param_name == :action
|
131
|
-
check_param_for_injections(
|
138
|
+
check_param_for_injections(InjectionSensor::URI_PARAM, appsensor_meta, param_name.to_s, param_value)
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
135
|
-
(appsensor_meta.get_dict || {}).each do |param_name, param_value|
|
142
|
+
TCellAgent::Utils::Params.flatten(appsensor_meta.get_dict || {}).each do |param_name, param_value|
|
136
143
|
TCellAgent::Instrumentation.safe_block("AppSensor Check GET var injections") do
|
144
|
+
param_name = param_name[-1]
|
137
145
|
check_param_for_injections(InjectionSensor::GET_PARAM, appsensor_meta, param_name, param_value)
|
138
146
|
end
|
139
147
|
end
|
140
148
|
|
141
149
|
(appsensor_meta.post_dict || {}).each do |param_name, param_value|
|
142
150
|
TCellAgent::Instrumentation.safe_block("AppSensor Check POST var injections") do
|
151
|
+
param_name = param_name[-1]
|
143
152
|
check_param_for_injections(InjectionSensor::POST_PARAM, appsensor_meta, param_name, param_value)
|
144
153
|
end
|
145
154
|
end
|
146
155
|
|
147
156
|
(appsensor_meta.body_dict || {}).each do |param_name, param_value|
|
148
157
|
TCellAgent::Instrumentation.safe_block("AppSensor Check JSON var injections") do
|
158
|
+
param_name = param_name[-1]
|
149
159
|
check_param_for_injections(InjectionSensor::JSON_PARAM, appsensor_meta, param_name, param_value)
|
150
160
|
end
|
151
161
|
end
|
152
162
|
|
153
|
-
(appsensor_meta.cookie_dict || {}).each do |param_name, param_value|
|
163
|
+
TCellAgent::Utils::Params.flatten(appsensor_meta.cookie_dict || {}).each do |param_name, param_value|
|
154
164
|
TCellAgent::Instrumentation.safe_block("AppSensor Check COOKIE var injections") do
|
165
|
+
param_name = param_name[-1]
|
155
166
|
check_param_for_injections(InjectionSensor::COOKIE_PARAM, appsensor_meta, param_name, param_value)
|
156
167
|
end
|
157
168
|
end
|
158
169
|
end
|
159
170
|
|
160
|
-
def csrf_rejected(tcell_data)
|
171
|
+
def csrf_rejected(tcell_data, exception_class)
|
161
172
|
TCellAgent::Instrumentation.safe_block("AppSensor CSRF Exception processing") do
|
162
173
|
if self.options.has_key?("errors")
|
163
|
-
self.options["errors"].csrf_rejected(tcell_data)
|
174
|
+
self.options["errors"].csrf_rejected(tcell_data, exception_class)
|
164
175
|
end
|
165
176
|
end
|
166
177
|
end
|
@@ -198,6 +209,9 @@ module TCellAgent
|
|
198
209
|
|
199
210
|
else
|
200
211
|
sensor_policy.enabled = true
|
212
|
+
sensor_policy.payloads_policy = PayloadsPolicy.from_json(
|
213
|
+
data_json.fetch("options", {})
|
214
|
+
)
|
201
215
|
|
202
216
|
DETECTION_POINTS_V2.each do |sensor_name, sensor_class|
|
203
217
|
settings = sensors_json.fetch(sensor_name, {})
|
@@ -217,6 +231,13 @@ module TCellAgent
|
|
217
231
|
|
218
232
|
else
|
219
233
|
sensor_policy.enabled = true
|
234
|
+
sensor_policy.payloads_policy = PayloadsPolicy.from_json({
|
235
|
+
"payloads" => {
|
236
|
+
"send_payloads" => true,
|
237
|
+
"log_payloads" => true
|
238
|
+
}
|
239
|
+
})
|
240
|
+
|
220
241
|
DETECTION_POINTS_V1.each do |sensor_name|
|
221
242
|
if "req_res_size" == sensor_name
|
222
243
|
enabled = options_json.fetch(sensor_name, false)
|
@@ -41,7 +41,7 @@ module TCellAgent
|
|
41
41
|
end
|
42
42
|
return true
|
43
43
|
end
|
44
|
-
def enforce(target_url, current_host, current_path, method, route_id, status_code, remote_addr,
|
44
|
+
def enforce(target_url, current_host, current_path, method, route_id, status_code, remote_addr, hmac_session_id=nil)
|
45
45
|
if @enabled == false
|
46
46
|
return nil
|
47
47
|
end
|
@@ -51,7 +51,17 @@ module TCellAgent
|
|
51
51
|
return nil
|
52
52
|
end
|
53
53
|
begin
|
54
|
-
event = TCellAgent::SensorEvents::TCellRedirectSensorEvent.new(
|
54
|
+
event = TCellAgent::SensorEvents::TCellRedirectSensorEvent.new(
|
55
|
+
host,
|
56
|
+
current_host,
|
57
|
+
current_path,
|
58
|
+
method,
|
59
|
+
route_id,
|
60
|
+
status_code,
|
61
|
+
remote_addr,
|
62
|
+
hmac_session_id,
|
63
|
+
nil)
|
64
|
+
|
55
65
|
TCellAgent.send_event(event)
|
56
66
|
rescue Exception => ie
|
57
67
|
TCellAgent.logger.error("uncaught exception while creating redirect event: #{ie.message}")
|
@@ -14,7 +14,7 @@ module TCellAgent
|
|
14
14
|
if appsensor_policy
|
15
15
|
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
16
16
|
if tcell_data
|
17
|
-
appsensor_policy.csrf_rejected(tcell_data)
|
17
|
+
appsensor_policy.csrf_rejected(tcell_data, ActionController::InvalidAuthenticityToken)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|