contrast-agent 6.6.4 → 6.6.5
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/lib/contrast/agent/assess/policy/trigger_method.rb +21 -6
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +2 -0
- data/lib/contrast/agent/at_exit_hook.rb +1 -7
- data/lib/contrast/agent/inventory/database_config.rb +12 -13
- data/lib/contrast/agent/middleware.rb +0 -1
- data/lib/contrast/agent/protect/rule/base.rb +16 -20
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +5 -4
- data/lib/contrast/agent/protect/rule/deserialization.rb +5 -4
- data/lib/contrast/agent/protect/rule/path_traversal.rb +9 -7
- data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +16 -14
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/protect/rule/xxe.rb +9 -6
- data/lib/contrast/agent/reporting/attack_result/attack_result.rb +8 -0
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +85 -36
- data/lib/contrast/agent/reporting/attack_result/user_input.rb +11 -0
- data/lib/contrast/agent/reporting/details/bot_blocker_details.rb +29 -0
- data/lib/contrast/agent/reporting/details/cmd_injection_details.rb +30 -0
- data/lib/contrast/agent/reporting/details/details.rb +18 -0
- data/lib/contrast/agent/reporting/details/http_method_tempering_details.rb +27 -0
- data/lib/contrast/agent/reporting/details/ip_denylist_details.rb +27 -0
- data/lib/contrast/agent/reporting/details/no_sqli_details.rb +36 -0
- data/lib/contrast/agent/reporting/details/path_traversal_details.rb +24 -0
- data/lib/contrast/agent/reporting/details/path_traversal_semantic_analysis_details.rb +32 -0
- data/lib/contrast/agent/reporting/details/protect_rule_details.rb +17 -0
- data/lib/contrast/agent/reporting/details/sqli_details.rb +36 -0
- data/lib/contrast/agent/reporting/details/untrusted_deserialization_details.rb +27 -0
- data/lib/contrast/agent/reporting/details/virtual_patch_details.rb +24 -0
- data/lib/contrast/agent/reporting/details/xss_details.rb +33 -0
- data/lib/contrast/agent/reporting/details/xss_match.rb +30 -0
- data/lib/contrast/agent/reporting/details/xxe_details.rb +36 -0
- data/lib/contrast/agent/reporting/details/xxe_match.rb +25 -0
- data/lib/contrast/agent/reporting/details/xxe_wrapper.rb +25 -0
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +1 -1
- data/lib/contrast/agent/reporting/masker/masker.rb +78 -65
- data/lib/contrast/agent/reporting/masker/masker_utils.rb +1 -30
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +84 -15
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +13 -25
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_activity.rb +17 -22
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +46 -125
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +5 -16
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +10 -18
- data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -14
- data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +29 -20
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +45 -10
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -7
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +2 -1
- data/lib/contrast/agent/request.rb +2 -0
- data/lib/contrast/agent/request_context.rb +13 -4
- data/lib/contrast/agent/request_context_extend.rb +59 -40
- data/lib/contrast/agent/request_handler.rb +7 -9
- data/lib/contrast/agent/service_heartbeat.rb +1 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/components/app_context.rb +6 -6
- data/lib/contrast/config/assess_configuration.rb +1 -1
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -6
- data/lib/contrast/utils/assess/event_limit_utils.rb +26 -7
- data/lib/contrast/utils/log_utils.rb +15 -9
- metadata +19 -2
@@ -30,21 +30,18 @@ module Contrast
|
|
30
30
|
|
31
31
|
# Mask sensitive data according to the contrast sensitive data rules.
|
32
32
|
#
|
33
|
-
# @param [Contrast::
|
33
|
+
# @param [Contrast::Agent::Reporting::ApplicationActivity]
|
34
34
|
def mask activity
|
35
|
-
return unless Contrast::Agent::Reporter.enabled?
|
36
35
|
return unless activity
|
37
36
|
|
38
|
-
logger.debug('
|
39
|
-
activity: activity.__id__,
|
40
|
-
request: activity.http_request&.uuid)
|
37
|
+
logger.debug('Masker: masking sensitive data', activity: activity.__id__, request: activity.request&.__id__)
|
41
38
|
mask_body(activity)
|
42
39
|
mask_query_string(activity)
|
43
40
|
mask_request_params(activity)
|
44
41
|
mask_request_cookies(activity)
|
45
42
|
mask_request_headers(activity)
|
46
43
|
rescue StandardError => _e
|
47
|
-
logger.debug('Could not mask activity!', activity: activity.__id__, request: activity.
|
44
|
+
logger.debug('Could not mask activity!', activity: activity.__id__, request: activity.request&.__id__)
|
48
45
|
end
|
49
46
|
|
50
47
|
private
|
@@ -64,68 +61,67 @@ module Contrast
|
|
64
61
|
|
65
62
|
# Mask request body:
|
66
63
|
#
|
67
|
-
# @param activity [Contrast::
|
64
|
+
# @param activity [Contrast::Agent::Reporting::ApplicationActivity]
|
68
65
|
# @return masked_body [String, nil]
|
69
66
|
def mask_body activity
|
70
67
|
return unless mask_body?
|
71
68
|
|
72
|
-
body = activity.
|
69
|
+
body = activity.request.body
|
73
70
|
return if body.nil? || body.empty?
|
74
71
|
|
75
|
-
activity.
|
76
|
-
activity.
|
72
|
+
activity.request.body = BODY_MASK
|
73
|
+
activity.request.body_binary = BODY_BINARY_MASK
|
77
74
|
end
|
78
75
|
|
79
76
|
# Mask request params.
|
80
77
|
#
|
81
|
-
# @param activity [Contrast::
|
78
|
+
# @param activity [Contrast::Agent::Reporting::ApplicationActivity]
|
82
79
|
# @return masked_body [String, nil]
|
83
80
|
def mask_request_params activity
|
84
|
-
params = activity.
|
81
|
+
params = activity.request.parameters
|
85
82
|
return unless params
|
86
83
|
|
87
|
-
mask_with_dictionary(activity.
|
84
|
+
mask_with_dictionary(activity.attack_results, params)
|
88
85
|
end
|
89
86
|
|
90
87
|
def mask_request_headers activity
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
88
|
+
headers = activity.request.headers
|
89
|
+
return if headers&.empty?
|
90
|
+
|
91
|
+
# Used normalized request_headers
|
92
|
+
mask = mask_with_dictionary(activity.attack_results, headers)
|
93
|
+
activity.request.headers = mask if mask
|
98
94
|
end
|
99
95
|
|
100
96
|
# Mask Cookies.
|
101
97
|
#
|
102
|
-
# @param activity [Contrast::
|
98
|
+
# @param activity [Contrast::Agent::Reporting::ApplicationActivity] Activity to mask
|
103
99
|
# @return masked_values [Hash, nil]
|
104
100
|
def mask_request_cookies activity
|
105
|
-
cookies = activity.
|
106
|
-
return
|
101
|
+
cookies = activity.request.cookies
|
102
|
+
return if cookies&.empty?
|
107
103
|
|
108
|
-
mask_with_dictionary(activity.
|
104
|
+
mask_with_dictionary(activity.attack_results, cookies)
|
109
105
|
end
|
110
106
|
|
111
107
|
# Mask request query string:
|
112
108
|
# exp: password => sensitive to password => contrast-redacted-password
|
113
109
|
#
|
114
|
-
# @param activity [Contrast::
|
110
|
+
# @param activity [Contrast::Agent::Reporting::ApplicationActivity]
|
115
111
|
# @return masked_query [String]
|
116
112
|
def mask_query_string activity
|
117
|
-
qs = activity.
|
113
|
+
qs = activity.request.query_string
|
118
114
|
return if qs.nil? || qs.empty?
|
119
115
|
|
120
|
-
|
121
|
-
|
116
|
+
mask = mask_raw_query(qs, activity.attack_results)
|
117
|
+
activity.request.query_string = mask if mask
|
122
118
|
end
|
123
119
|
|
124
120
|
# Mask if the value in the passed hash are matched against dictionary
|
125
121
|
# keyword. If the mask_attack_vector flag is set, this will also mask
|
126
122
|
# any attack.
|
127
123
|
#
|
128
|
-
# @param results [Array<Contrast::
|
124
|
+
# @param results [Array<Contrast::Agent::Reporting::ApplicationDefendAttackActivity>]
|
129
125
|
# results to match against.
|
130
126
|
# @param hash [Hash] Normalized hash representing the key/val pair from
|
131
127
|
# the activity's http request parameters.
|
@@ -134,81 +130,98 @@ module Contrast
|
|
134
130
|
return if hash.nil? || hash.empty?
|
135
131
|
|
136
132
|
hash.each do |key, val|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
# key => Contrast::Api::Dtm::Pair (key, val<Values>).
|
142
|
-
# try one level down
|
143
|
-
if val.cs__respond_to?(:values)
|
144
|
-
mask_values(key, val, results)
|
133
|
+
next unless dictionary_match(key)
|
134
|
+
|
135
|
+
if val.cs__is_a?(Array)
|
136
|
+
mask_values(key, val, hash, results)
|
145
137
|
else
|
146
138
|
# Just assign keys.
|
147
139
|
mask_hash(key, val, hash, results)
|
148
140
|
end
|
149
141
|
end
|
150
|
-
hash
|
151
142
|
end
|
152
143
|
|
153
|
-
# Mask the values of
|
154
|
-
#
|
144
|
+
# Mask the values of key value pair with array of string as input.
|
145
|
+
# If the mask_attack_vector? flag is set then the attack vector won't be
|
146
|
+
# masked.
|
155
147
|
#
|
156
|
-
# @param key [String]
|
157
|
-
#
|
158
|
-
# @param results [Array<Contrast::
|
148
|
+
# @param key [String]
|
149
|
+
# @param hash [Hash] Normalized hash representing the key/val pair.
|
150
|
+
# @param results [Array<Contrast::Agent::Reporting::ApplicationDefendAttackActivity>]
|
159
151
|
# results to match against.
|
160
|
-
# @param val [
|
161
|
-
def mask_values key, val, results
|
162
|
-
val.
|
152
|
+
# @param val [String, Array<String>]
|
153
|
+
def mask_values key, val, hash, results
|
154
|
+
val.each.with_index do |v, idx|
|
163
155
|
# Mask the attack vector only if the flag is set.
|
164
|
-
|
156
|
+
hash[key][idx] = MASK + key.downcase if attack_vector?(results, v) && mask_attack_vector?
|
165
157
|
# It is not attack vector and we mask it as normal.
|
166
|
-
|
158
|
+
hash[key][idx] = MASK + key.downcase unless attack_vector?(results, v)
|
167
159
|
end
|
168
|
-
|
160
|
+
hash
|
169
161
|
end
|
170
162
|
|
171
|
-
# Handles the masking of
|
172
|
-
# this case is used when called from #mask_field_hash
|
173
|
-
# and #mask_raw_query helper methods. Since they dont
|
174
|
-
# return values containing sub-values (key, val<Values>).
|
163
|
+
# Handles the masking of hash
|
175
164
|
#
|
176
165
|
# @param key [String] current iterable key from Protobuf::Field::FieldHash
|
177
166
|
# @param val [String] normalized value to be matched against the results
|
178
167
|
# and masked.
|
179
168
|
# @param hash [Hash] Normalized hash representing the key/val pair.
|
180
|
-
# @param results [Array<Contrast::
|
169
|
+
# @param results [Array<Contrast::Agent::Reporting::ApplicationDefendAttackActivity>]
|
181
170
|
# results to match against.
|
171
|
+
# @return [Hash]
|
182
172
|
def mask_hash key, val, hash, results
|
173
|
+
# Mask the attack vector only if the flag is set.
|
183
174
|
hash[key] = MASK + key.downcase if attack_vector?(results, val) && mask_attack_vector?
|
175
|
+
# It is not attack vector we mask it.
|
184
176
|
hash[key] = MASK + key.downcase unless attack_vector?(results, val)
|
177
|
+
hash
|
185
178
|
end
|
186
179
|
|
187
180
|
# Match to see if values matches input from AttackResults array.
|
188
181
|
# If match is found and the attack result's response is any of
|
189
182
|
# [BAP(Block At Perimeter), BLOCKED, PROBED] the return is true.
|
190
183
|
#
|
191
|
-
# @param results [Array<Contrast::
|
184
|
+
# @param results [Array<Contrast::Agent::Reporting::ApplicationDefendAttackActivity>]
|
192
185
|
# results to match against.
|
193
186
|
# @param value [String] Input to match.
|
194
|
-
# @return
|
187
|
+
# @return [Boolean]
|
195
188
|
def attack_vector? results, value
|
196
189
|
return false unless value && results
|
197
190
|
|
198
|
-
results.each do |
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
191
|
+
results.each do |attacker|
|
192
|
+
attacker.each do |activity|
|
193
|
+
blocked = iterate_attack_samples(activity.blocked, value)
|
194
|
+
return blocked if blocked
|
195
|
+
|
196
|
+
exploited = iterate_attack_samples(activity.exploited, value)
|
197
|
+
return exploited if exploited
|
205
198
|
|
206
|
-
|
199
|
+
ineffective = iterate_attack_samples(activity.ineffective, value)
|
200
|
+
return ineffective if ineffective
|
201
|
+
|
202
|
+
suspicious = iterate_attack_samples(activity.suspicious, value)
|
203
|
+
return suspicious if suspicious
|
207
204
|
end
|
208
205
|
end
|
209
206
|
false
|
210
207
|
end
|
211
208
|
|
209
|
+
# Go through activity samples and search for a matching input.
|
210
|
+
#
|
211
|
+
# @param activity [Contrast::Agent::Reporting::ApplicationDefendAttackActivity]
|
212
|
+
# @param value [String] Input to match.
|
213
|
+
# @return [Boolean]
|
214
|
+
def iterate_attack_samples activity, value
|
215
|
+
return false unless activity
|
216
|
+
|
217
|
+
activity.samples.any? do |sample|
|
218
|
+
match = sample.user_input.value == value.to_s
|
219
|
+
|
220
|
+
return true if match
|
221
|
+
end
|
222
|
+
false
|
223
|
+
end
|
224
|
+
|
212
225
|
# Consult with our current settings state.
|
213
226
|
#
|
214
227
|
# @return true | false
|
@@ -227,7 +240,7 @@ module Contrast
|
|
227
240
|
#
|
228
241
|
# @param value [String] Value to check.
|
229
242
|
# @return match [String, nil] from the Dictionary, or nil.
|
230
|
-
def
|
243
|
+
def dictionary_match value
|
231
244
|
return unless @_dictionary
|
232
245
|
|
233
246
|
@_dictionary.each do |rule|
|
@@ -9,35 +9,6 @@ module Contrast
|
|
9
9
|
# helper methods used for masking
|
10
10
|
module MaskerUtils
|
11
11
|
include Contrast::Utils::ObjectShare
|
12
|
-
# Helper to deal with Protobuf FieldHash.
|
13
|
-
#
|
14
|
-
# @param field_hash [Protobuf::Field::FieldHash] hash to be masked
|
15
|
-
# @param results [Array<Contrast::Api::Dtm::AttackResults>]
|
16
|
-
# results to match against.
|
17
|
-
# @return [Hash]
|
18
|
-
def mask_field_hash field_hash, results
|
19
|
-
return {} unless field_hash&.any?
|
20
|
-
|
21
|
-
hash = {}
|
22
|
-
# Because this is the start of a built string, we have to be sure that it is not frozen.
|
23
|
-
masked = +''
|
24
|
-
field_hash.each do |entry|
|
25
|
-
# Protobuf::Field::FieldHash produces array, with the key as first param and value as second.
|
26
|
-
new_value = entry[1].delete(SEMICOLON).split(SPACE)
|
27
|
-
new_value.each do |value|
|
28
|
-
arr = value.split(EQUALS)
|
29
|
-
# Add to new hash.
|
30
|
-
hash[arr[0]] = arr[1]
|
31
|
-
end
|
32
|
-
# Mask the newly created hash.
|
33
|
-
mask_with_dictionary(results, hash)
|
34
|
-
|
35
|
-
# Restore to original form.
|
36
|
-
hash.each { |k, v| masked += "#{ k }=#{ v }; " }
|
37
|
-
masked.rstrip!
|
38
|
-
field_hash[entry[0]] = masked
|
39
|
-
end
|
40
|
-
end
|
41
12
|
|
42
13
|
# Mask raw query as it comes from the env.
|
43
14
|
# exp:
|
@@ -45,7 +16,7 @@ module Contrast
|
|
45
16
|
# 'ssn=contrast-redacted-ssn&id=contrast-redacted-id'
|
46
17
|
#
|
47
18
|
# @param query [String]
|
48
|
-
# @param results [Array<Contrast::
|
19
|
+
# @param results [Array<Contrast::Agent::Reporting::ApplicationDefendAttackActivitys>]
|
49
20
|
# results to match against.
|
50
21
|
def mask_raw_query query, results
|
51
22
|
masked = EMPTY_STRING
|
@@ -5,6 +5,7 @@ require 'contrast/components/logger'
|
|
5
5
|
require 'contrast/agent/reporting/reporting_events/application_reporting_event'
|
6
6
|
require 'contrast/agent/reporting/reporting_events/application_defend_activity'
|
7
7
|
require 'contrast/agent/reporting/reporting_events/application_inventory_activity'
|
8
|
+
require 'contrast/agent/reporting/attack_result/response_type'
|
8
9
|
|
9
10
|
module Contrast
|
10
11
|
module Agent
|
@@ -12,38 +13,106 @@ module Contrast
|
|
12
13
|
# This is the new ApplicationActivity class which will include all the needed information for the new reporting
|
13
14
|
# system to report
|
14
15
|
class ApplicationActivity < Contrast::Agent::Reporting::ApplicationReportingEvent
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
include Contrast::Agent::Reporting::ResponseType
|
17
|
+
|
18
|
+
# @return [Integer]
|
19
|
+
attr_accessor :query_count
|
20
|
+
# @return [Array]
|
21
|
+
attr_accessor :routes
|
22
|
+
# @return [Array]
|
23
|
+
attr_accessor :dynamic_sources
|
24
|
+
# @return [Contrast::Agent::Response]
|
25
|
+
attr_accessor :response
|
24
26
|
|
25
27
|
def initialize
|
28
|
+
@routes = []
|
29
|
+
@dynamic_sources = {}
|
30
|
+
@query_count = 0
|
26
31
|
@event_method = :PUT
|
27
32
|
@event_type = :application_activity
|
28
33
|
@event_endpoint = Contrast::Agent::Reporting::Endpoints.application_activity
|
29
34
|
super
|
30
35
|
end
|
31
36
|
|
37
|
+
# @return [Contrast::Agent::Reporting::FindingRequest] Current context's request
|
38
|
+
def request
|
39
|
+
@_request ||= FindingRequest.convert(Contrast::Agent::REQUEST_TRACKER.current&.request)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Contrast::Agent::Reporting::ApplicationDefendActivity] main
|
43
|
+
# activity for all protect rules.
|
44
|
+
def defend
|
45
|
+
@_defend ||= Contrast::Agent::Reporting::ApplicationDefendActivity.new
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Contrast::Agent::Reporting::ApplicationInventoryActivity] main
|
49
|
+
# activity for all inventory activity reporting.
|
50
|
+
def inventory
|
51
|
+
@_inventory ||= Contrast::Agent::Reporting::ApplicationInventoryActivity.new
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return file_name [String] used for audit
|
32
55
|
def file_name
|
33
56
|
'activity-application'
|
34
57
|
end
|
35
58
|
|
36
59
|
def to_controlled_hash
|
37
60
|
hsh = { lastUpdate: since_last_update }
|
38
|
-
hsh[:defend] = @
|
39
|
-
hsh[:inventory] = @
|
61
|
+
hsh[:defend] = @_defend&.to_controlled_hash if @_defend
|
62
|
+
hsh[:inventory] = @_inventory&.to_controlled_hash if @_inventory
|
40
63
|
hsh
|
41
64
|
end
|
42
65
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
66
|
+
# Look for attack results and access to samples by
|
67
|
+
# searching with rule_id and response_type
|
68
|
+
#
|
69
|
+
# @param rule_id [String] name of the protect rule
|
70
|
+
# @param response_type[Symbol<Contrast::Agent::Reporting::ResponseType]
|
71
|
+
# filter by response type
|
72
|
+
# @return [Array<Contrast::Agent::Reporting::ApplicationDefendAttackSampleActivity>, nil]
|
73
|
+
# return any matches.
|
74
|
+
def attack_results_for rule_id, response_type = nil
|
75
|
+
results = []
|
76
|
+
defend.attackers.each do |attacker|
|
77
|
+
results << case response_type
|
78
|
+
when BLOCKED, BLOCK_AT_PERIMETER
|
79
|
+
attacker.protection_rules[rule_id].blocked
|
80
|
+
when EXPLOITED
|
81
|
+
attacker.protection_rules[rule_id].exploited
|
82
|
+
when PROBED
|
83
|
+
attacker.protection_rules[rule_id].ineffective
|
84
|
+
when SUSPICIOUS
|
85
|
+
attacker.protection_rules[rule_id].suspicious
|
86
|
+
else
|
87
|
+
attacker.protection_rules[rule_id]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
results
|
91
|
+
end
|
92
|
+
|
93
|
+
# By reference. List of all results only by values, no rule_ids.
|
94
|
+
#
|
95
|
+
# @return [Array<[Contrast::Agent::Reporting::ApplicationDefendAttackerActivity]>]
|
96
|
+
def attack_results
|
97
|
+
results = []
|
98
|
+
defend.attackers.each { |a| results << a.protection_rules.values }
|
99
|
+
results
|
100
|
+
end
|
101
|
+
|
102
|
+
# This is primary used for attaching new data and merging existing
|
103
|
+
# samples per rule entry in attackers, and to make sure the attack
|
104
|
+
# time_map is updated correctly.
|
105
|
+
#
|
106
|
+
# @param attack_result [Contrast::Agent::Reporting::AttackResult]
|
107
|
+
def attach_defend attack_result
|
108
|
+
defend.attach_data(attack_result)
|
109
|
+
end
|
110
|
+
|
111
|
+
# This is primary used for attaching new inventory reporting
|
112
|
+
#
|
113
|
+
# @param architecture [Contrast::Agent::Reporting::AttackResult]
|
114
|
+
def attach_inventory architecture
|
115
|
+
inventory.attach_data(architecture)
|
47
116
|
end
|
48
117
|
end
|
49
118
|
end
|
@@ -13,20 +13,9 @@ module Contrast
|
|
13
13
|
# @return [Array<Contrast::Agent::Reporting::ApplicationDefendAttackerActivity>]
|
14
14
|
attr_reader :attackers
|
15
15
|
|
16
|
-
class << self
|
17
|
-
# @param activity_dtm [Contrast::Api::Dtm::ApplicationActivity]
|
18
|
-
# @return [Contrast::Agent::Reporting::ApplicationDefendActivity]
|
19
|
-
def convert activity_dtm
|
20
|
-
activity = new
|
21
|
-
activity.attach_data(activity_dtm.results)
|
22
|
-
activity
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
16
|
def initialize
|
27
17
|
@attackers = []
|
28
18
|
@event_type = :application_defend_activity
|
29
|
-
super
|
30
19
|
end
|
31
20
|
|
32
21
|
def to_controlled_hash
|
@@ -35,20 +24,19 @@ module Contrast
|
|
35
24
|
}
|
36
25
|
end
|
37
26
|
|
38
|
-
# @param
|
39
|
-
def attach_data
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
27
|
+
# @param attack_result [Contrast::Agent::Reporting::AttackResult]
|
28
|
+
def attach_data attack_result
|
29
|
+
attacker_activity = Contrast::Agent::Reporting::ApplicationDefendAttackerActivity.new
|
30
|
+
attacker_activity.attach_data(attack_result)
|
31
|
+
existing_attacker_activity = attackers.find do |existing|
|
32
|
+
existing.source_forwarded_for == attacker_activity.source_forwarded_for &&
|
33
|
+
existing.source_ip == attacker_activity.source_ip
|
34
|
+
end
|
35
|
+
rule = attack_result.rule_id
|
36
|
+
if existing_attacker_activity
|
37
|
+
attach_existing(existing_attacker_activity, attacker_activity, rule)
|
38
|
+
else
|
39
|
+
attackers << attacker_activity
|
52
40
|
end
|
53
41
|
end
|
54
42
|
|
@@ -19,44 +19,39 @@ module Contrast
|
|
19
19
|
attr_accessor :ineffective
|
20
20
|
# @return [Contrast::Agent::Reporting::ApplicationDefendAttackSampleActivity]
|
21
21
|
attr_accessor :suspicious
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
activity = new
|
27
|
-
activity.attach_data(attack_result)
|
28
|
-
activity
|
29
|
-
end
|
30
|
-
end
|
22
|
+
# Helper method to determine before hand the response type and iv needed for access
|
23
|
+
#
|
24
|
+
# @return [Contrast::Agent::Reporting::ResponseType]
|
25
|
+
attr_reader :response_type
|
31
26
|
|
32
27
|
def initialize
|
33
28
|
@start_time = start_time
|
34
|
-
super
|
35
29
|
end
|
36
30
|
|
37
31
|
def to_controlled_hash
|
38
32
|
{
|
39
33
|
startTime: @start_time,
|
40
|
-
blocked: blocked&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
41
|
-
exploited: exploited&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
42
|
-
ineffective: ineffective&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
43
|
-
suspicious: suspicious&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH
|
34
|
+
blocked: @blocked&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
35
|
+
exploited: @exploited&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
36
|
+
ineffective: @ineffective&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH,
|
37
|
+
suspicious: @suspicious&.to_controlled_hash || Contrast::Utils::ObjectShare::EMPTY_HASH
|
44
38
|
}
|
45
39
|
end
|
46
40
|
|
47
|
-
# @param attack_result [Contrast::
|
41
|
+
# @param attack_result [Contrast::Agent::Reporting::AttackResult]
|
48
42
|
# @return [Contrast::Agent::Reporting::Defend::AttackSampleActivity]
|
49
43
|
def attach_data attack_result
|
50
|
-
attack_sample_activity =
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
attack_sample_activity = Contrast::Agent::Reporting::ApplicationDefendAttackSampleActivity.new
|
45
|
+
attack_sample_activity.attach_data(attack_result)
|
46
|
+
@response_type = attack_result.response
|
47
|
+
case response_type
|
48
|
+
when ::Contrast::Agent::Reporting::ResponseType::BLOCKED
|
54
49
|
@blocked = attack_sample_activity
|
55
|
-
when ::Contrast::
|
50
|
+
when ::Contrast::Agent::Reporting::ResponseType::MONITORED
|
56
51
|
@exploited = attack_sample_activity
|
57
|
-
when ::Contrast::
|
52
|
+
when ::Contrast::Agent::Reporting::ResponseType::PROBED
|
58
53
|
@ineffective = attack_sample_activity
|
59
|
-
when ::Contrast::
|
54
|
+
when ::Contrast::Agent::Reporting::ResponseType::SUSPICIOUS
|
60
55
|
@suspicious = attack_sample_activity
|
61
56
|
end
|
62
57
|
end
|