contrast-agent 6.1.2 → 6.2.0
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/at_exit_hook.rb +2 -1
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +9 -5
- data/lib/contrast/agent/protect/rule/xss.rb +4 -0
- data/lib/contrast/agent/reporting/reporter.rb +2 -11
- data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +3 -18
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +75 -15
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +2 -2
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +5 -19
- data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +6 -22
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +2 -3
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +1 -3
- data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +9 -0
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -2
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -10
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response.rb +60 -2
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +32 -10
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +58 -26
- data/lib/contrast/agent/reporting/settings/application_settings.rb +8 -23
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +27 -33
- data/lib/contrast/agent/reporting/settings/bot_blocker.rb +68 -0
- data/lib/contrast/agent/reporting/settings/code_exclusion.rb +27 -0
- data/lib/contrast/agent/reporting/settings/exclusion_base.rb +33 -0
- data/lib/contrast/agent/reporting/settings/exclusions.rb +39 -57
- data/lib/contrast/agent/reporting/settings/helpers.rb +56 -0
- data/lib/contrast/agent/reporting/settings/input_exclusion.rb +37 -0
- data/lib/contrast/agent/reporting/settings/ip_filter.rb +35 -0
- data/lib/contrast/agent/reporting/settings/keyword.rb +74 -0
- data/lib/contrast/agent/reporting/settings/log_enhancer.rb +65 -0
- data/lib/contrast/agent/reporting/settings/protect.rb +4 -2
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +62 -115
- data/lib/contrast/agent/reporting/settings/reaction.rb +11 -2
- data/lib/contrast/agent/reporting/settings/rule_definition.rb +63 -0
- data/lib/contrast/agent/reporting/settings/sampling.rb +10 -0
- data/lib/contrast/agent/reporting/settings/sanitizer.rb +38 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +9 -1
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +7 -0
- data/lib/contrast/agent/reporting/settings/server_features.rb +8 -0
- data/lib/contrast/agent/reporting/settings/syslog.rb +176 -0
- data/lib/contrast/agent/reporting/settings/url_exclusion.rb +42 -0
- data/lib/contrast/agent/reporting/settings/validator.rb +17 -0
- data/lib/contrast/agent/request_context.rb +4 -0
- data/lib/contrast/agent/request_handler.rb +8 -4
- data/lib/contrast/agent/static_analysis.rb +4 -8
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +1 -1
- data/lib/contrast/agent/thread_watcher.rb +4 -5
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +1 -3
- data/lib/contrast/api/decorators/application_update.rb +0 -8
- data/lib/contrast/api/decorators.rb +0 -1
- data/lib/contrast/framework/base_support.rb +5 -4
- data/lib/contrast/framework/grape/support.rb +6 -6
- data/lib/contrast/framework/manager.rb +2 -4
- data/lib/contrast/framework/manager_extend.rb +1 -0
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +2 -1
- data/lib/contrast/framework/rails/support.rb +9 -2
- data/lib/contrast/framework/sinatra/support.rb +3 -2
- data/lib/contrast/logger/aliased_logging.rb +31 -26
- data/lib/contrast/utils/response_utils.rb +14 -1
- data/lib/contrast/utils/telemetry.rb +9 -0
- data/lib/contrast/utils/telemetry_hash.rb +36 -12
- data/lib/contrast/utils/telemetry_identifier.rb +8 -0
- data/lib/contrast/utils/thread_tracker.rb +26 -9
- data/lib/contrast/utils/timer.rb +6 -1
- data/lib/contrast.rb +1 -3
- metadata +26 -14
- data/lib/contrast/api/decorators/library_usage_update.rb +0 -31
@@ -152,9 +152,9 @@ module Contrast
|
|
152
152
|
#
|
153
153
|
# @param response [Contrast::Agent::Reporting::Response]
|
154
154
|
def update_reaction response
|
155
|
-
return unless response
|
155
|
+
return unless response&.reactions&.any?
|
156
156
|
|
157
|
-
response.
|
157
|
+
response.reactions.each do |reaction|
|
158
158
|
# The enums are all uppercase, we need to downcase them before attempting to log.
|
159
159
|
level = reaction.level.nil? ? :error : reaction.level.downcase
|
160
160
|
logger.with_level(level, reaction.message) if reaction.message
|
@@ -198,50 +198,82 @@ module Contrast
|
|
198
198
|
response_body = response&.body
|
199
199
|
return unless response_body
|
200
200
|
|
201
|
-
response_data = JSON.parse(response_body)
|
201
|
+
response_data = JSON.parse(response_body, symbolize_names: true)
|
202
202
|
return unless response_data.cs__is_a?(Hash)
|
203
203
|
|
204
|
-
response_data
|
204
|
+
populate_response(response_data)
|
205
|
+
rescue StandardError => e
|
206
|
+
logger.error('Unable to convert response', e)
|
207
|
+
nil
|
208
|
+
end
|
209
|
+
|
210
|
+
# Extracts the data from the response and coverts it to
|
211
|
+
# Contrast::Agent::Reporting::Response.
|
212
|
+
#
|
213
|
+
# @param response_data[Hash]
|
214
|
+
# @return response [Contrast::Agent::Reporting::Response]
|
215
|
+
def populate_response response_data
|
216
|
+
return unless (success, messages = extract_success(response_data))
|
217
|
+
|
205
218
|
# check if response contains application settings or Feature settings
|
206
219
|
if response_data[:settings]
|
207
220
|
# the response contains ApplicationSettings
|
208
|
-
|
221
|
+
response = Contrast::Agent::Reporting::Response.build_application_response
|
222
|
+
response.success = success
|
223
|
+
response.messages = messages
|
224
|
+
app_settings = build_application_settings(response_data, response)
|
209
225
|
logger.trace('Agent: Received updated application settings', raw: response_data, processed: app_settings)
|
210
226
|
app_settings
|
211
227
|
else
|
212
228
|
# the response contains FeatureSettings
|
213
|
-
|
229
|
+
response = Contrast::Agent::Reporting::Response.build_server_response
|
230
|
+
response.success = success
|
231
|
+
response.messages = messages
|
232
|
+
server_features = build_feature_settings(response_data, response)
|
214
233
|
logger.trace('Agent: Received updated application settings', raw: response_data, processed: server_features)
|
215
234
|
server_features
|
216
235
|
end
|
217
|
-
|
218
|
-
logger.error('Unable to convert response', e)
|
219
|
-
nil
|
236
|
+
response
|
220
237
|
end
|
221
238
|
|
222
239
|
# @param response_data [Hash]
|
223
240
|
# @return res [Contrast::Agent::Reporting::Response]
|
224
|
-
def build_application_settings response_data
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
res
|
241
|
+
def build_application_settings response_data, response
|
242
|
+
extract_assess(response_data, response)
|
243
|
+
extract_protect(response_data, response)
|
244
|
+
extract_exclusions(response_data, response)
|
245
|
+
extract_reactions(response_data, response)
|
246
|
+
extract_sensitive_data_policy(response_data, response)
|
247
|
+
response
|
232
248
|
end
|
233
249
|
|
234
250
|
# @param response_data [Hash]
|
235
251
|
# @return res [Contrast::Agent::Reporting::Response]
|
236
|
-
def build_feature_settings response_data
|
237
|
-
|
238
|
-
extract_assess_server_features(response_data,
|
239
|
-
extract_protect_server_features(response_data,
|
240
|
-
extract_protect_lists(response_data,
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
252
|
+
def build_feature_settings response_data, response
|
253
|
+
extract_reactions(response_data, response)
|
254
|
+
extract_assess_server_features(response_data, response)
|
255
|
+
extract_protect_server_features(response_data, response)
|
256
|
+
extract_protect_lists(response_data, response)
|
257
|
+
extract_log_settings(response_data, response)
|
258
|
+
response.server_features.telemetry = response_data[:telemetry]
|
259
|
+
response
|
260
|
+
end
|
261
|
+
|
262
|
+
# This method with check the success and messages field of the response.
|
263
|
+
# If the success is false, then it will return nil and log the error.
|
264
|
+
#
|
265
|
+
# @param response_data [Hash]
|
266
|
+
# @return [Array, nil] Returns the success status or nil if request
|
267
|
+
# was not processed by TS.
|
268
|
+
def extract_success response_data
|
269
|
+
success = response_data[:success]
|
270
|
+
messages = response_data[:messages]
|
271
|
+
return [success, messages] if success
|
272
|
+
|
273
|
+
logger.error('Unable to connect to Contrast UI') if messages.nil?
|
274
|
+
logger.error('Failure on Contrast UI processing request', reasons: messages.join(', ')) if messages
|
275
|
+
|
276
|
+
nil
|
245
277
|
end
|
246
278
|
end
|
247
279
|
end
|
@@ -37,13 +37,6 @@ module Contrast
|
|
37
37
|
@_exclusions ||= Contrast::Agent::Reporting::Settings::Exclusions.new
|
38
38
|
end
|
39
39
|
|
40
|
-
# Reaction the agent should take based on a state in TS.
|
41
|
-
#
|
42
|
-
# @return [Array<Contrast::Agent::Reporting::Settings::Reaction>, nil]
|
43
|
-
def reactions
|
44
|
-
@_reactions
|
45
|
-
end
|
46
|
-
|
47
40
|
# This object will hold the masking rules send from TS.
|
48
41
|
#
|
49
42
|
# @return sensitive_data_masking [Contrast::Agent::Reporting::Settings::SensitiveDataMasking] this object
|
@@ -52,22 +45,14 @@ module Contrast
|
|
52
45
|
@_sensitive_data_masking ||= Contrast::Agent::Reporting::Settings::SensitiveDataMasking.new
|
53
46
|
end
|
54
47
|
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
def reactions= reactions
|
64
|
-
return unless reactions.is_a?(Array)
|
65
|
-
|
66
|
-
@_reactions = []
|
67
|
-
reactions.each do |r|
|
68
|
-
reaction = Contrast::Agent::Reporting::Settings::Reaction.new(r[:level], r[:operation], r[:message])
|
69
|
-
@_reactions << reaction
|
70
|
-
end
|
48
|
+
# Currently protect and assess are not covered with to_controlled_hash methods
|
49
|
+
def to_controlled_hash
|
50
|
+
{
|
51
|
+
defend: {},
|
52
|
+
exceptions: exclusions.to_controlled_hash,
|
53
|
+
assessment: {},
|
54
|
+
sensitive_data_masking_policy: sensitive_data_masking.to_controlled_hash
|
55
|
+
}
|
71
56
|
end
|
72
57
|
end
|
73
58
|
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
|
4
4
|
require 'contrast/utils/object_share'
|
5
5
|
require 'contrast/agent/reporting/settings/sampling'
|
6
|
+
require 'contrast/agent/reporting/settings/sanitizer'
|
7
|
+
require 'contrast/agent/reporting/settings/validator'
|
8
|
+
require 'contrast/agent/reporting/settings/helpers'
|
6
9
|
|
7
10
|
module Contrast
|
8
11
|
module Agent
|
@@ -52,54 +55,45 @@ module Contrast
|
|
52
55
|
|
53
56
|
# The sanitizers defined by the user for use by the agent on this server for this organization.
|
54
57
|
#
|
55
|
-
# @return sanitizers [Array<
|
56
|
-
# Api [String], Rules [Array[RulesID]]
|
57
|
-
# tags [Array[String]]
|
58
|
-
# uuid [String]
|
58
|
+
# @return sanitizers [Array<Contrast::Agent::Reporting::Settings::Sanitizer>]
|
59
59
|
def sanitizers
|
60
60
|
@_sanitizers ||= []
|
61
61
|
end
|
62
62
|
|
63
63
|
# set sanitizer
|
64
64
|
#
|
65
|
-
# @param
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# Api [String], Rules [Array[RulesID]]
|
72
|
-
# tags [Array[String]]
|
73
|
-
# uuid [String]
|
74
|
-
def sanitizers= sanitizers
|
75
|
-
@_sanitizers = sanitizers if sanitizers.is_a?(Array)
|
65
|
+
# @param sanitizers_array [Array<Contrast::Agent::Reporting::Settings::Sanitizer>]
|
66
|
+
# @return sanitizers [Array<Contrast::Agent::Reporting::Settings::Sanitizer>]
|
67
|
+
def sanitizers= sanitizers_array
|
68
|
+
Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(Contrast::Agent::Reporting::Settings::Sanitizer,
|
69
|
+
sanitizers,
|
70
|
+
sanitizers_array)
|
76
71
|
end
|
77
72
|
|
78
73
|
# The validators defined by the user for use by the agent on this server for this organization.
|
79
74
|
#
|
80
|
-
# @return
|
81
|
-
# Api [String], Rules [Array[RulesID]]
|
82
|
-
# tags [Array[String]]
|
83
|
-
# uuid [String]
|
84
|
-
# }
|
75
|
+
# @return sanitizers [Array<Contrast::Agent::Reporting::Settings::Validator>]
|
85
76
|
def validators
|
86
77
|
@_validators ||= []
|
87
78
|
end
|
88
79
|
|
89
|
-
#
|
80
|
+
# set validators
|
90
81
|
#
|
91
|
-
# @param
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
82
|
+
# @param validators_array [Array<Contrast::Agent::Reporting::Settings::Validator>]
|
83
|
+
# @return sanitizers [Array<Contrast::Agent::Reporting::Settings::Validator>]
|
84
|
+
def validators= validators_array
|
85
|
+
Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(Contrast::Agent::Reporting::Settings::Validator,
|
86
|
+
validators,
|
87
|
+
validators_array)
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_controlled_hash
|
91
|
+
{
|
92
|
+
enabled: enabled?,
|
93
|
+
sampling: sampling.to_controlled_hash,
|
94
|
+
sanitizers: sanitizers.map(&:to_controlled_hash),
|
95
|
+
validators: validators.map(&:to_controlled_hash)
|
96
|
+
}
|
103
97
|
end
|
104
98
|
end
|
105
99
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/reporting/settings/helpers'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Reporting
|
9
|
+
module Settings
|
10
|
+
# Indicate if the bot protection feature set is enabled for this server or not.
|
11
|
+
class BotBlocker
|
12
|
+
# @return [Boolean]
|
13
|
+
attr_accessor :enable
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@enable = true
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return bots [Hash<Contrast::Agent::Reporting::Settings::Bot>, []]
|
20
|
+
def bots
|
21
|
+
@_bots ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def bots= bots_array
|
25
|
+
Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(Contrast::Agent::Reporting::Settings::Bot,
|
26
|
+
bots,
|
27
|
+
bots_array)
|
28
|
+
end
|
29
|
+
|
30
|
+
# We should be receiving:
|
31
|
+
# bot_blockers { enable, bots[{bot, case_sensitive, start_anchor}]}
|
32
|
+
# Instead in the response there is bot_blockers[], and the enable
|
33
|
+
# which can be retrieved from bot-blocker.
|
34
|
+
def to_controlled_hash
|
35
|
+
@enable
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# This class is used to represent a Bot entity inside the bots array.
|
40
|
+
class Bot
|
41
|
+
ATTRIBUTES = %i[bot case_sensitive start_anchor].cs__freeze
|
42
|
+
|
43
|
+
# @return bot [String]
|
44
|
+
attr_accessor :bot
|
45
|
+
# @return case_sensitive [Boolean] Whether the name is case-sensitive
|
46
|
+
# or not.
|
47
|
+
attr_accessor :case_sensitive
|
48
|
+
# @return start_anchor [Boolean]
|
49
|
+
attr_accessor :start_anchor
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
# default values of properties:
|
53
|
+
@start_anchor = false
|
54
|
+
@case_sensitive = false
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_controlled_hash
|
58
|
+
{
|
59
|
+
bot: bot,
|
60
|
+
caseSensitive: case_sensitive,
|
61
|
+
startAnchor: start_anchor
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/reporting/settings/exclusion_base'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Reporting
|
9
|
+
module Settings
|
10
|
+
# CodeExclusions class
|
11
|
+
class CodeExclusion < ExclusionBase
|
12
|
+
ATTRIBUTES = BASE_ATTRIBUTES.dup << :denylist
|
13
|
+
ATTRIBUTES.cs__freeze
|
14
|
+
|
15
|
+
# @return denylist [Array<String>] #rubocop:disable [Naming/InclusiveLanguage]
|
16
|
+
attr_accessor :denylist
|
17
|
+
|
18
|
+
def to_controlled_hash
|
19
|
+
hash = super
|
20
|
+
hash[:denylist] = denylist
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Reporting
|
7
|
+
module Settings
|
8
|
+
# Base class to represent common exclusions fields.
|
9
|
+
class ExclusionBase
|
10
|
+
BASE_ATTRIBUTES = %i[name modes assess_rules protect_rules].cs__freeze
|
11
|
+
|
12
|
+
# @return name [String]
|
13
|
+
attr_accessor :name
|
14
|
+
# @return modes [Array<String>]
|
15
|
+
attr_accessor :modes
|
16
|
+
# @return assess_rules [Array<String>]
|
17
|
+
attr_accessor :assess_rules
|
18
|
+
# @return protect_rules [Array<String>]
|
19
|
+
attr_accessor :protect_rules
|
20
|
+
|
21
|
+
def to_controlled_hash
|
22
|
+
{
|
23
|
+
name: name, # rubocop:disable Security/Module/Name
|
24
|
+
modes: modes,
|
25
|
+
assessRules: assess_rules,
|
26
|
+
protectRules: protect_rules
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'contrast/agent/reporting/settings/code_exclusion'
|
5
|
+
require 'contrast/agent/reporting/settings/input_exclusion'
|
6
|
+
require 'contrast/agent/reporting/settings/url_exclusion'
|
7
|
+
require 'contrast/agent/reporting/settings/helpers'
|
8
|
+
|
4
9
|
module Contrast
|
5
10
|
module Agent
|
6
11
|
module Reporting
|
@@ -11,52 +16,38 @@ module Contrast
|
|
11
16
|
class Exclusions
|
12
17
|
# Cases where rules should be excluded if violated in a method call
|
13
18
|
#
|
14
|
-
# @return code_exclusions [Array<CodeExclusion>] Array of CodeExclusion
|
15
|
-
# name [String] The name of the exclusion as defined by the user in TS.
|
16
|
-
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
17
|
-
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
18
|
-
# denylist [String] The call, if in the stack, should result in the agent not taking action.
|
19
|
-
# }
|
19
|
+
# @return code_exclusions [Array<Contrast::Agent::Reporting::Settings::CodeExclusion>] Array of CodeExclusion
|
20
20
|
def code_exclusions
|
21
21
|
@_code_exclusions ||= []
|
22
22
|
end
|
23
23
|
|
24
24
|
# set the CodeExclusions array
|
25
25
|
#
|
26
|
-
# @param
|
26
|
+
# @param new_code_exclusions [Array<CodeExclusion>] Array of CodeExclusion: {
|
27
27
|
# name [String] The name of the exclusion as defined by the user in TS.
|
28
28
|
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
29
29
|
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
30
30
|
# denylist [String] The call, if in the stack, should result in the agent not taking action.
|
31
31
|
# }
|
32
|
-
# @return code_exclusions [Array<CodeExclusion>] Array of CodeExclusion
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def code_exclusions= code_exclusions
|
39
|
-
@_code_exclusions = code_exclusions if code_exclusions.is_a?(Array)
|
32
|
+
# @return code_exclusions [Array<Contrast::Agent::Reporting::Settings::CodeExclusion>] Array of CodeExclusion
|
33
|
+
def code_exclusions= new_code_exclusions
|
34
|
+
@_code_exclusions = Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(
|
35
|
+
Contrast::Agent::Reporting::Settings::CodeExclusion,
|
36
|
+
code_exclusions,
|
37
|
+
new_code_exclusions)
|
40
38
|
end
|
41
39
|
|
42
40
|
# Cases where rules should be excluded if violated from a given input.
|
43
41
|
#
|
44
|
-
# @return input_exclusions [Array<InputExclusions>]
|
45
|
-
#
|
46
|
-
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
47
|
-
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
48
|
-
# protect_rules [Array] Array of ProtectRuleID [String] The protect rules to which this exclusion applies.
|
49
|
-
# urls [Array] Array of URLs to which the exclusions apply. URL [String]
|
50
|
-
# match_strategy [String] If this exclusion applies to all URLs or only those specified. [ALL, ONLY]
|
51
|
-
# type [String] The type of the input [COOKIE, PARAMETER, HEADER, BODY, QUERYSTRING]
|
52
|
-
# }
|
42
|
+
# @return input_exclusions [Array<Contrast::Agent::Reporting::Settings::InputExclusions>]
|
43
|
+
# Array of InputExclusions
|
53
44
|
def input_exclusions
|
54
45
|
@_input_exclusions ||= []
|
55
46
|
end
|
56
47
|
|
57
48
|
# set the InputExclusions array
|
58
49
|
#
|
59
|
-
# @param
|
50
|
+
# @param new_input_exclusions [Array<InputExclusions>] Array of InputExclusions: {
|
60
51
|
# name [String] The name of the input.
|
61
52
|
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
62
53
|
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
@@ -65,37 +56,25 @@ module Contrast
|
|
65
56
|
# match_strategy [String] If this exclusion applies to all URLs or only those specified. [ALL, ONLY]
|
66
57
|
# type [String] The type of the input [COOKIE, PARAMETER, HEADER, BODY, QUERYSTRING]
|
67
58
|
# }
|
68
|
-
# @return input_exclusions [Array<InputExclusions>]
|
69
|
-
#
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
# type [String] The type of the input [COOKIE, PARAMETER, HEADER, BODY, QUERYSTRING]
|
76
|
-
# }
|
77
|
-
def input_exclusions= input_exclusions
|
78
|
-
@_input_exclusions = input_exclusions if input_exclusions.is_a?(Array)
|
59
|
+
# @return input_exclusions [Array<Contrast::Agent::Reporting::Settings::InputExclusions>]
|
60
|
+
# Array of InputExclusions
|
61
|
+
def input_exclusions= new_input_exclusions
|
62
|
+
@_input_exclusions = Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(
|
63
|
+
Contrast::Agent::Reporting::Settings::InputExclusion,
|
64
|
+
input_exclusions,
|
65
|
+
new_input_exclusions)
|
79
66
|
end
|
80
67
|
|
81
68
|
# A case where rules should be excluded if violated during a call to a given URL.
|
82
69
|
#
|
83
|
-
# @return url_exclusions [Array<
|
84
|
-
# name [String] The name of the input.
|
85
|
-
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
86
|
-
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
87
|
-
# protect_rules [Array] Array of ProtectRuleID [String] The protect rules to which this exclusion applies.
|
88
|
-
# urls [Array] Array of URLs to which the exclusions apply. URL [String]
|
89
|
-
# match_strategy [String] If this exclusion applies to all URLs or only those specified. [ALL, ONLY]
|
90
|
-
# type [String] The type of the input [COOKIE, PARAMETER, HEADER, BODY, QUERYSTRING]
|
91
|
-
# }
|
70
|
+
# @return url_exclusions [Array<Contrast::Agent::Reporting::Settings::UrlExclusion>] Array of UrlExclusions
|
92
71
|
def url_exclusions
|
93
72
|
@_url_exclusions ||= []
|
94
73
|
end
|
95
74
|
|
96
75
|
# set the UrlExclusions array
|
97
76
|
#
|
98
|
-
# @param
|
77
|
+
# @param new_url_exclusions [Array] Array of UrlExclusions: {
|
99
78
|
# name [String] The name of the input.
|
100
79
|
# modes [String] If this exclusion applies to assess or protect. [assess, defend]
|
101
80
|
# assess_rules [Array] Array of assess rules to which this exclusion applies. AssessRuleID [String]
|
@@ -104,17 +83,20 @@ module Contrast
|
|
104
83
|
# match_strategy [String] If this exclusion applies to all URLs or only those specified. [ALL, ONLY]
|
105
84
|
# type [String] The type of the input [COOKIE, PARAMETER, HEADER, BODY, QUERYSTRING]
|
106
85
|
# }
|
107
|
-
# @return url_exclusions [Array<
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
86
|
+
# @return url_exclusions [Array<Contrast::Agent::Reporting::Settings::UrlExclusion>] Array of UrlExclusions
|
87
|
+
def url_exclusions= new_url_exclusions
|
88
|
+
@_url_exclusions = Contrast::Agent::Reporting::Settings::Helpers.array_to_iv(
|
89
|
+
Contrast::Agent::Reporting::Settings::UrlExclusion,
|
90
|
+
url_exclusions,
|
91
|
+
new_url_exclusions)
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_controlled_hash
|
95
|
+
{
|
96
|
+
codeExceptions: code_exclusions.map(&:to_controlled_hash),
|
97
|
+
inputExceptions: input_exclusions.map(&:to_controlled_hash),
|
98
|
+
urlExceptions: url_exclusions.map(&:to_controlled_hash)
|
99
|
+
}
|
118
100
|
end
|
119
101
|
end
|
120
102
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Reporting
|
7
|
+
module Settings
|
8
|
+
# Helper methods used across the settings.
|
9
|
+
module Helpers
|
10
|
+
class << self
|
11
|
+
# Fills instance variable [Array] with new settings as new instance type
|
12
|
+
# for each entry.
|
13
|
+
#
|
14
|
+
# @param instance_type [Class] a class to create new instance from to
|
15
|
+
# @param instance_variable [Array] instance variable accessor method
|
16
|
+
# return an array to fill.
|
17
|
+
# @param array [Array] array to be used to fill the iv.
|
18
|
+
# fill the iv with the new type containing data from the provided array
|
19
|
+
# param.
|
20
|
+
# @return instance_variable [Class]
|
21
|
+
def array_to_iv instance_type, instance_variable, array
|
22
|
+
return unless array.is_a?(Array)
|
23
|
+
|
24
|
+
array.each_with_index do |entry, index|
|
25
|
+
new_instance = instance_type.new
|
26
|
+
instance_type::ATTRIBUTES.each do |attr|
|
27
|
+
new_instance.send("#{ attr }=".to_sym, entry[no_more_underscore(attr)])
|
28
|
+
end
|
29
|
+
instance_variable[index] = new_instance
|
30
|
+
end
|
31
|
+
|
32
|
+
instance_variable
|
33
|
+
end
|
34
|
+
|
35
|
+
# :attr_name => :attrName
|
36
|
+
# return original if no '_'
|
37
|
+
#
|
38
|
+
# @param attr_name [Symbol]
|
39
|
+
# @return normalized_name [Symbol]
|
40
|
+
def no_more_underscore attr_name
|
41
|
+
name = attr_name.to_s
|
42
|
+
idx = name.index('_')
|
43
|
+
return attr_name if idx.nil? || (idx.zero? && idx >= name.length)
|
44
|
+
|
45
|
+
result = name
|
46
|
+
result.slice!(idx)
|
47
|
+
result.insert(idx, name[idx]&.upcase)
|
48
|
+
result.slice!(idx + 1)
|
49
|
+
result.index('_') ? no_more_underscore(result).to_sym : result.to_sym
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/reporting/settings/exclusion_base'
|
5
|
+
require 'contrast/utils/object_share'
|
6
|
+
|
7
|
+
module Contrast
|
8
|
+
module Agent
|
9
|
+
module Reporting
|
10
|
+
module Settings
|
11
|
+
# InputExclusions class
|
12
|
+
class InputExclusion < ExclusionBase
|
13
|
+
ATTRIBUTES = BASE_ATTRIBUTES.dup << :type
|
14
|
+
ATTRIBUTES.cs__freeze
|
15
|
+
VALID_INPUT_TYPES = %w[COOKIE PARAMETER HEADER BODY QUERYSTRING].cs__freeze
|
16
|
+
|
17
|
+
# @return type [String] The type of the input
|
18
|
+
def type
|
19
|
+
@_type ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param new_type [String] Set new input type.
|
23
|
+
# @return type [String] The type of the input.
|
24
|
+
def type= new_type
|
25
|
+
@_type = new_type if VALID_INPUT_TYPES.include?(new_type)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_controlled_hash
|
29
|
+
hash = super
|
30
|
+
hash[:type] = type
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|