contrast-agent 7.1.0 → 7.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/ext/extconf_common.rb +88 -14
- data/lib/contrast/agent/assess/policy/source_method.rb +13 -4
- data/lib/contrast/agent/assess/policy/trigger_method.rb +12 -18
- data/lib/contrast/agent/excluder/excluder.rb +64 -31
- data/lib/contrast/agent/protect/rule/base.rb +4 -6
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker.rb +1 -1
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +2 -2
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization/deserialization.rb +2 -2
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +1 -1
- data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +1 -1
- data/lib/contrast/agent/protect/rule/utils/filters.rb +6 -6
- data/lib/contrast/agent/protect/rule/xxe/xxe.rb +1 -1
- data/lib/contrast/agent/reporting/client/interface.rb +132 -0
- data/lib/contrast/agent/reporting/client/interface_base.rb +27 -0
- data/lib/contrast/agent/reporting/connection_status.rb +0 -1
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +6 -4
- data/lib/contrast/agent/reporting/reporter.rb +11 -26
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +47 -6
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +40 -31
- data/lib/contrast/agent/reporting/reporting_utilities/resend.rb +144 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +35 -13
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +14 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +11 -11
- data/lib/contrast/agent/request/request.rb +27 -12
- data/lib/contrast/agent/telemetry/base.rb +18 -19
- data/lib/contrast/agent/telemetry/exception/obfuscate.rb +97 -0
- data/lib/contrast/agent/telemetry/exception.rb +1 -0
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/components/config/sources.rb +6 -5
- data/lib/contrast/components/settings.rb +9 -0
- data/lib/contrast/config/diagnostics/source_config_value.rb +5 -1
- data/lib/contrast/config/diagnostics/tools.rb +4 -4
- data/lib/contrast/config/validate.rb +2 -2
- data/lib/contrast/configuration.rb +11 -19
- data/lib/contrast/framework/grape/support.rb +1 -2
- data/lib/contrast/framework/manager.rb +17 -8
- data/lib/contrast/framework/rack/support.rb +99 -1
- data/lib/contrast/framework/rails/support.rb +1 -2
- data/lib/contrast/framework/sinatra/support.rb +1 -2
- data/lib/contrast/logger/aliased_logging.rb +18 -9
- data/lib/contrast/utils/hash_utils.rb +21 -2
- data/lib/contrast/utils/request_utils.rb +14 -0
- data/resources/assess/policy.json +11 -0
- metadata +6 -3
- data/lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb +0 -27
@@ -81,11 +81,11 @@ module Contrast
|
|
81
81
|
# Overlay CLI options - they take precedence over config file
|
82
82
|
cli_options = Contrast::Utils::HashUtils.deep_symbolize_all_keys(cli_options)
|
83
83
|
if cli_options
|
84
|
-
config_kv = Contrast::Utils::HashUtils.
|
84
|
+
config_kv = Contrast::Utils::HashUtils.precedence_merge(cli_options, config_kv)
|
85
85
|
@_source_file_extensions = Contrast::Utils::HashUtils.
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
precedence_merge(assign_source_to(cli_options,
|
87
|
+
Contrast::Components::Config::Sources::COMMAND_LINE),
|
88
|
+
@_source_file_extensions)
|
89
89
|
end
|
90
90
|
|
91
91
|
# Some in-flight rewrites to maintain backwards compatibility
|
@@ -157,7 +157,7 @@ module Contrast
|
|
157
157
|
@_configuration_paths ||= begin
|
158
158
|
basename = default_name.split('.').first
|
159
159
|
# Order of extensions comes from here:
|
160
|
-
extensions = Contrast::Components::Config::Sources::
|
160
|
+
extensions = Contrast::Components::Config::Sources::APP_CONFIGURATION_EXTENSIONS
|
161
161
|
|
162
162
|
paths = []
|
163
163
|
# Environment paths takes precedence here. Look first through them.
|
@@ -216,7 +216,6 @@ module Contrast
|
|
216
216
|
end
|
217
217
|
origin.add_source_file(path, (yaml_to_hash(path) || {}))
|
218
218
|
end
|
219
|
-
|
220
219
|
# Legacy usage: Assign main configuration file for reference.
|
221
220
|
@config_file = origin.main_file
|
222
221
|
# merge all settings keeping the top yaml files values as priority.
|
@@ -225,13 +224,15 @@ module Contrast
|
|
225
224
|
# precedence of paths: see Contrast::Configuration::CONFIG_BASE_PATHS
|
226
225
|
extensions_maps = []
|
227
226
|
origin.source_files.each do |file|
|
228
|
-
|
229
|
-
precedence_merge!(config, file.values)
|
227
|
+
config = Contrast::Utils::HashUtils.precedence_merge(config, file.values)
|
230
228
|
# assign source values extentions:
|
231
229
|
extensions_maps << assign_source_to(Contrast::Utils::HashUtils.deep_symbolize_all_keys(file.values), file.path)
|
232
230
|
end
|
231
|
+
|
233
232
|
# merge all origin paths to be used as extension classification to preserve the precedence of config files:
|
234
|
-
extensions_maps.each
|
233
|
+
extensions_maps.each do |path|
|
234
|
+
@_source_file_extensions = Contrast::Utils::HashUtils.precedence_merge!(@_source_file_extensions, path)
|
235
|
+
end
|
235
236
|
|
236
237
|
config
|
237
238
|
end
|
@@ -357,7 +358,7 @@ module Contrast
|
|
357
358
|
KEYS_TO_REDACT.include?(key.to_sym)
|
358
359
|
end
|
359
360
|
|
360
|
-
def assign_source_to hash, source = Contrast::Components::Config::Sources::APP_CONFIGURATION_FILE
|
361
|
+
def assign_source_to hash, source = Contrast::Components::Config::Sources::APP_CONFIGURATION_FILE
|
361
362
|
hash.transform_values do |value|
|
362
363
|
if value.is_a?(Hash)
|
363
364
|
assign_source_to(value, source)
|
@@ -366,14 +367,5 @@ module Contrast
|
|
366
367
|
end
|
367
368
|
end
|
368
369
|
end
|
369
|
-
|
370
|
-
# Merges two hashes, first hash will preserve it's values and will only add unique values.
|
371
|
-
#
|
372
|
-
# @param hsh [Hash]
|
373
|
-
# @param other_hsh [Hash]
|
374
|
-
# @return [Hash]
|
375
|
-
def precedence_merge! hsh, other_hsh
|
376
|
-
hsh.merge!(other_hsh) { |_key, old_val, _new_val| old_val }
|
377
|
-
end
|
378
370
|
end
|
379
371
|
end
|
@@ -72,8 +72,7 @@ module Contrast
|
|
72
72
|
|
73
73
|
# @param request [Contrast::Agent::Request] a contrast tracked request.
|
74
74
|
# @param controller [::Grape::API] optionally use this controller instead of global ::Grape::API.
|
75
|
-
# @return [Contrast::Agent::Reporting::RouteCoverage, nil]
|
76
|
-
# matched to the request if a match was found.
|
75
|
+
# @return [Contrast::Agent::Reporting::RouteCoverage, nil] the route coverage object or nil if no route
|
77
76
|
def current_route_coverage request, controller = ::Grape::API, full_route = nil
|
78
77
|
return unless grape_controller?(controller)
|
79
78
|
|
@@ -37,6 +37,9 @@ module Contrast
|
|
37
37
|
logger.info('Framework detected. Enabling support.', framework: framework_klass.detection_class)
|
38
38
|
framework_klass
|
39
39
|
end
|
40
|
+
|
41
|
+
# Delete Rack if we have more than one framework detected
|
42
|
+
@_frameworks.delete(Contrast::Framework::Rack::Support) if @_frameworks.length > 1
|
40
43
|
@_frameworks.compact!
|
41
44
|
end
|
42
45
|
|
@@ -87,16 +90,22 @@ module Contrast
|
|
87
90
|
# this particular Request
|
88
91
|
# @return [::Rack::Request] either a rack request or subclass thereof.
|
89
92
|
def retrieve_request env
|
90
|
-
|
91
|
-
|
92
|
-
return Contrast::Framework::Rails::Support.retrieve_request(env)
|
93
|
+
if Contrast::Utils::DuckUtils.empty_duck?(@_frameworks)
|
94
|
+
return Contrast::Framework::Rack::Support.retrieve_request(env)
|
93
95
|
end
|
94
96
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
framework = @_frameworks[0]
|
98
|
+
|
99
|
+
case framework.cs__name
|
100
|
+
when 'Contrast::Framework::Rails::Support'
|
101
|
+
Contrast::Framework::Rails::Support.retrieve_request(env)
|
102
|
+
when 'Contrast::Framework::Grape::Support'
|
103
|
+
Contrast::Framework::Grape::Support.retrieve_request(env)
|
104
|
+
when 'Contrast::Framework::Sinatra::Support'
|
105
|
+
Contrast::Framework::Sinatra::Support.retrieve_request(env)
|
106
|
+
else
|
107
|
+
Contrast::Framework::Rack::Support.retrieve_request(env)
|
108
|
+
end
|
100
109
|
rescue StandardError => e
|
101
110
|
logger.warn('Unable to retrieve_request', e)
|
102
111
|
end
|
@@ -14,7 +14,105 @@ module Contrast
|
|
14
14
|
extend Contrast::Framework::Rack::Patch::Support
|
15
15
|
class << self
|
16
16
|
def detection_class
|
17
|
-
'
|
17
|
+
'Rack'
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] the Rack version
|
21
|
+
def version
|
22
|
+
::Rack.version
|
23
|
+
rescue StandardError
|
24
|
+
''
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String] the Rack application name
|
28
|
+
def application_name
|
29
|
+
'Rack Application'
|
30
|
+
end
|
31
|
+
|
32
|
+
def application_root
|
33
|
+
Dir.pwd
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String] the server type
|
37
|
+
def server_type
|
38
|
+
'Rack'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find all the predefined routes for this application
|
42
|
+
#
|
43
|
+
# Extracting the Rack application routes is not trivial. Routes are evaluated dynamically
|
44
|
+
# when a request comes in, so they are not loaded before and stored in a data structure
|
45
|
+
# available somewhere. This mean that route discovery is only available through the rack map,
|
46
|
+
# but this is limited as not showing the actual method (GET, POST, etc...). For now The Agent
|
47
|
+
# will use only the current_route_coverage for Rack applications.
|
48
|
+
#
|
49
|
+
# @return [Array<Contrast::Agent::Reporting::DiscoveredRoute>]
|
50
|
+
# @raise [NoMethodError] raises error if subclass does not implement this method
|
51
|
+
def collect_routes
|
52
|
+
# return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless defined?(Rack)
|
53
|
+
# Rack::URLMap is used for mapping different rack apps to different paths.
|
54
|
+
# The Rack app could be separated into smaller rack applications.
|
55
|
+
# Rack::Builder is another option.
|
56
|
+
# return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless rack_map
|
57
|
+
|
58
|
+
# This method is disabled for now, as it is not returning the actual routes. Code is left for as
|
59
|
+
# comment for future reference.
|
60
|
+
#
|
61
|
+
# routes = []
|
62
|
+
# rack_map.any? do |path, meta|
|
63
|
+
# routes << Contrast::Agent::Reporting::DiscoveredRoute.from_rack_route(meta[1], meta[0], path)
|
64
|
+
# end
|
65
|
+
# routes
|
66
|
+
Contrast::Utils::ObjectShare::EMPTY_ARRAY
|
67
|
+
end
|
68
|
+
|
69
|
+
# Given the current request - return a RouteCoverage object
|
70
|
+
|
71
|
+
# @param request [Contrast::Agent::Request] a contrast tracked request.
|
72
|
+
# @param _controller [::Sinatra::Base] optionally use this controller instead of global ::Sinatra::Base.
|
73
|
+
# @return [Contrast::Agent::Reporting::RouteCoverage, nil] the route coverage object or nil if no route
|
74
|
+
def current_route_coverage request, _controller = nil, full_route = nil
|
75
|
+
method = request.env[::Rack::REQUEST_METHOD] # GET, PUT, POST, etc...
|
76
|
+
|
77
|
+
full_route ||= request.env[::Rack::PATH_INFO]
|
78
|
+
return unless full_route && method
|
79
|
+
|
80
|
+
route_coverage = Contrast::Agent::Reporting::RouteCoverage.new
|
81
|
+
# We might not have controller, or even if there is defined one, it could not bare the name of the
|
82
|
+
# route to match as an object, it could be one router class with base controller with several methods
|
83
|
+
# describing each class, search for final controller might be resource heavy, and not efficient.
|
84
|
+
# For now to identify the controller the Agent will use the route name, this may lead to recording
|
85
|
+
# of false routes, but it is better than nothing. If route do no match a pattern it is a good practice
|
86
|
+
# to notify the user by displaying a not found page, in a sense this is a exercise of the application, but
|
87
|
+
# not correctly recorded controller name. Try to see if there is a define Rack::URLMap, and use it first.
|
88
|
+
mapped_controller = rack_map[full_route]&.last
|
89
|
+
final_controller = mapped_controller || full_route
|
90
|
+
route_coverage.attach_rack_based_data(final_controller, method, nil, full_route)
|
91
|
+
route_coverage
|
92
|
+
end
|
93
|
+
|
94
|
+
# Try and get map of Rack application { "path" => ["pattern", "controller"] }.
|
95
|
+
#
|
96
|
+
# @return [Hash<String, Array<String>>] the rack map
|
97
|
+
def rack_map
|
98
|
+
rack_map = {}
|
99
|
+
maps = ObjectSpace.each_object(::Rack::URLMap).to_a
|
100
|
+
maps.any? do |map|
|
101
|
+
mapping = map.instance_variable_get(:@mapping)
|
102
|
+
mapping.any? do |arr|
|
103
|
+
path = arr[1]
|
104
|
+
pattern = arr[2]
|
105
|
+
controller = arr[3]&.cs__class&.cs__name
|
106
|
+
rack_map[path] = [pattern, controller] if path&.cs__is_a?(String) && controller
|
107
|
+
end
|
108
|
+
end
|
109
|
+
rack_map
|
110
|
+
rescue StandardError
|
111
|
+
{}
|
112
|
+
end
|
113
|
+
|
114
|
+
def retrieve_request env
|
115
|
+
::Rack::Request.new(env)
|
18
116
|
end
|
19
117
|
end
|
20
118
|
end
|
@@ -51,8 +51,7 @@ module Contrast
|
|
51
51
|
# Find the current route, based on the provided Request wrapper
|
52
52
|
#
|
53
53
|
# @param request[Contrast::Agent::Request]
|
54
|
-
# @return [Contrast::Agent::Reporting::RouteCoverage, nil]
|
55
|
-
# matched to the request if a match was found.
|
54
|
+
# @return [Contrast::Agent::Reporting::RouteCoverage, nil] the route coverage object or nil if no route
|
56
55
|
def current_route_coverage request
|
57
56
|
return unless ::Rails.cs__respond_to?(:application)
|
58
57
|
|
@@ -68,8 +68,7 @@ module Contrast
|
|
68
68
|
|
69
69
|
# @param request [Contrast::Agent::Request] a contrast tracked request.
|
70
70
|
# @param _controller [::Sinatra::Base] optionally use this controller instead of global ::Sinatra::Base.
|
71
|
-
# @return [Contrast::Agent::Reporting::RouteCoverage, nil]
|
72
|
-
# matched to the request if a match was found.
|
71
|
+
# @return [Contrast::Agent::Reporting::RouteCoverage, nil] the route coverage object or nil if no route
|
73
72
|
def current_route_coverage request, _controller = ::Sinatra::Base, full_route = nil
|
74
73
|
method = request.env[::Rack::REQUEST_METHOD] # GET, PUT, POST, etc...
|
75
74
|
route = _cleaned_route(request)
|
@@ -72,13 +72,11 @@ module Contrast
|
|
72
72
|
def build_exception type, message = nil, exception = nil, data = nil
|
73
73
|
return unless buildable?
|
74
74
|
|
75
|
-
|
76
|
-
caller_idx = stack_trace&.find_index { |stack| stack.to_s.include?(type) } || 0
|
77
|
-
# The caller_stack is the method in which the error occurred, so has to be above this method
|
75
|
+
caller_idx = wrapped_caller_locations&.find_index { |stack| stack.to_s.include?(type) } || 0
|
78
76
|
caller_idx += 1
|
79
|
-
|
80
|
-
stack_frame_type =
|
81
|
-
stack_frame_function =
|
77
|
+
caller = wrapped_caller_locations[caller_idx]
|
78
|
+
stack_frame_type = obfuscate_type(caller)
|
79
|
+
stack_frame_function = caller.label
|
82
80
|
key = "#{ stack_frame_type }|#{ stack_frame_function }|#{ message }"
|
83
81
|
if Contrast::TELEMETRY_EXCEPTIONS[key]
|
84
82
|
Contrast::TELEMETRY_EXCEPTIONS.increment(key)
|
@@ -92,7 +90,7 @@ module Contrast
|
|
92
90
|
stack_frame_type, message_exception_type,
|
93
91
|
data, exception,
|
94
92
|
message)
|
95
|
-
build_stack(event_message,
|
93
|
+
build_stack(event_message, wrapped_caller_locations, caller_idx)
|
96
94
|
TELEMETRY_EXCEPTIONS[key] = event_message
|
97
95
|
rescue StandardError => e
|
98
96
|
debug('[Telemetry] Unable to report exception', e)
|
@@ -141,8 +139,11 @@ module Contrast
|
|
141
139
|
caller_stack.each_with_index do |caller, idx|
|
142
140
|
next unless idx > caller_idx
|
143
141
|
|
144
|
-
|
145
|
-
|
142
|
+
obfuscated_label = Contrast::Agent::Telemetry::Exception::Obfuscate.obfuscate_path(caller.label)
|
143
|
+
obfuscated_path = Contrast::Agent::Telemetry::Exception::Obfuscate.
|
144
|
+
obfuscate_path(caller.path.delete_prefix(Dir.pwd))
|
145
|
+
|
146
|
+
stack_frame = Contrast::Agent::Telemetry::Exception::StackFrame.build(obfuscated_label, obfuscated_path)
|
146
147
|
event_exception_message.push(stack_frame)
|
147
148
|
end
|
148
149
|
end
|
@@ -153,6 +154,14 @@ module Contrast
|
|
153
154
|
def wrapped_caller_locations
|
154
155
|
caller_locations
|
155
156
|
end
|
157
|
+
|
158
|
+
# @param caller [Thread::Backtrace::Location, nil]
|
159
|
+
# @return [String]
|
160
|
+
def obfuscate_type caller
|
161
|
+
return '' unless caller.cs__respond_to?(:path)
|
162
|
+
|
163
|
+
Contrast::Agent::Telemetry::Exception::Obfuscate.obfuscate_path(caller.path.delete_prefix(Dir.pwd).to_s)
|
164
|
+
end
|
156
165
|
end
|
157
166
|
end
|
158
167
|
end
|
@@ -10,9 +10,28 @@ module Contrast
|
|
10
10
|
#
|
11
11
|
# @param hsh [Hash]
|
12
12
|
# @param other_hsh [Hash]
|
13
|
-
def
|
13
|
+
def precedence_merge hsh, other_hsh
|
14
14
|
hsh.merge(other_hsh) do |_key, old_value, new_value|
|
15
|
-
old_value.is_a?(Hash) || new_value.is_a?(Hash)
|
15
|
+
if old_value.is_a?(Hash) || new_value.is_a?(Hash)
|
16
|
+
Contrast::Utils::HashUtils.precedence_merge(old_value, new_value)
|
17
|
+
else
|
18
|
+
old_value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Merges two hashes, first hash will preserve it's values and will only add unique values.
|
24
|
+
#
|
25
|
+
# @param hsh [Hash]
|
26
|
+
# @param other_hsh [Hash]
|
27
|
+
# @return [Hash]
|
28
|
+
def precedence_merge! hsh, other_hsh
|
29
|
+
hsh.merge!(other_hsh) do |_key, old_val, new_val|
|
30
|
+
if old_val.is_a?(Hash) || new_val.is_a?(Hash)
|
31
|
+
Contrast::Utils::HashUtils.precedence_merge!(old_val, new_val)
|
32
|
+
else
|
33
|
+
old_val
|
34
|
+
end
|
16
35
|
end
|
17
36
|
end
|
18
37
|
|
@@ -5,6 +5,20 @@ module Contrast
|
|
5
5
|
module Utils
|
6
6
|
# used in Contrast::Agent::Request
|
7
7
|
module RequestUtils
|
8
|
+
# TOKENS:
|
9
|
+
NUM_ = '/{n}/'
|
10
|
+
ID_ = '{ID}'
|
11
|
+
# PATTERNS:
|
12
|
+
NUM_PATTERN = %r{/\d+/}.cs__freeze
|
13
|
+
END_PATTERN = %r{/\d+$}.cs__freeze
|
14
|
+
STATIC_SUFFIXES = /\.(?:js|css|jpeg|jpg|gif|png|ico|woff|svg|pdf|eot|ttf|jar)$/i.cs__freeze
|
15
|
+
UUID_PATTERN = Regexp.new('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}').cs__freeze # rubocop:disable Metrics/LineLength
|
16
|
+
# Regular expression to match any type of hash pattern that is 16 bytes like uuid with no
|
17
|
+
# slashes, md5, sha1, sha256, etc
|
18
|
+
HASH_PATTERN = Regexp.new('([a-fA-F0-9]{2}){16,}').cs__freeze
|
19
|
+
WIN_PATTERN = Regexp.new('S-1-5-((32-\d+)|(21-\d+-\d+-\d+-\d+))').cs__freeze
|
20
|
+
MEDIA_TYPE_MARKERS = %w[image/ text/css text/javascript].cs__freeze
|
21
|
+
|
8
22
|
# Return a flattened hash of params with realized paths for keys, in
|
9
23
|
# addition to a separate, valueless, entry for each nest key.
|
10
24
|
# See RUBY-621 for more details.
|
@@ -1258,6 +1258,17 @@
|
|
1258
1258
|
"tags":["HTML_ENCODED"],
|
1259
1259
|
"untags":["HTML_DECODED"]
|
1260
1260
|
},
|
1261
|
+
{
|
1262
|
+
"class_name": "Rails::HTML::Concern::ComposedSanitize",
|
1263
|
+
"method_name": "sanitize",
|
1264
|
+
"method_visibility": "public",
|
1265
|
+
"instance_method": true,
|
1266
|
+
"source": "P0",
|
1267
|
+
"target": "R",
|
1268
|
+
"action": "REMOVE",
|
1269
|
+
"tags":["HTML_ENCODED"],
|
1270
|
+
"untags":["HTML_DECODED"]
|
1271
|
+
},
|
1261
1272
|
{
|
1262
1273
|
"class_name": "Rails::Html::SafeListSanitizer",
|
1263
1274
|
"method_name": "sanitize",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contrast-agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- galen.palmer@contrastsecurity.com
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: exe
|
15
15
|
cert_chain: []
|
16
|
-
date: 2023-
|
16
|
+
date: 2023-05-31 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: bundler
|
@@ -1051,6 +1051,8 @@ files:
|
|
1051
1051
|
- lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb
|
1052
1052
|
- lib/contrast/agent/reporting/attack_result/response_type.rb
|
1053
1053
|
- lib/contrast/agent/reporting/attack_result/user_input.rb
|
1054
|
+
- lib/contrast/agent/reporting/client/interface.rb
|
1055
|
+
- lib/contrast/agent/reporting/client/interface_base.rb
|
1054
1056
|
- lib/contrast/agent/reporting/connection_status.rb
|
1055
1057
|
- lib/contrast/agent/reporting/details/bot_blocker_details.rb
|
1056
1058
|
- lib/contrast/agent/reporting/details/cmd_injection_details.rb
|
@@ -1069,7 +1071,6 @@ files:
|
|
1069
1071
|
- lib/contrast/agent/reporting/details/xxe_details.rb
|
1070
1072
|
- lib/contrast/agent/reporting/details/xxe_match.rb
|
1071
1073
|
- lib/contrast/agent/reporting/details/xxe_wrapper.rb
|
1072
|
-
- lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb
|
1073
1074
|
- lib/contrast/agent/reporting/input_analysis/details/protect_rule_details.rb
|
1074
1075
|
- lib/contrast/agent/reporting/input_analysis/input_analysis.rb
|
1075
1076
|
- lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb
|
@@ -1130,6 +1131,7 @@ files:
|
|
1130
1131
|
- lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb
|
1131
1132
|
- lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb
|
1132
1133
|
- lib/contrast/agent/reporting/reporting_utilities/reporting_storage.rb
|
1134
|
+
- lib/contrast/agent/reporting/reporting_utilities/resend.rb
|
1133
1135
|
- lib/contrast/agent/reporting/reporting_utilities/response.rb
|
1134
1136
|
- lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb
|
1135
1137
|
- lib/contrast/agent/reporting/reporting_utilities/response_handler.rb
|
@@ -1181,6 +1183,7 @@ files:
|
|
1181
1183
|
- lib/contrast/agent/telemetry/exception/event.rb
|
1182
1184
|
- lib/contrast/agent/telemetry/exception/message.rb
|
1183
1185
|
- lib/contrast/agent/telemetry/exception/message_exception.rb
|
1186
|
+
- lib/contrast/agent/telemetry/exception/obfuscate.rb
|
1184
1187
|
- lib/contrast/agent/telemetry/exception/stack_frame.rb
|
1185
1188
|
- lib/contrast/agent/telemetry/hash.rb
|
1186
1189
|
- lib/contrast/agent/telemetry/identifier.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 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/input_analysis/details/protect_rule_details'
|
5
|
-
|
6
|
-
module Contrast
|
7
|
-
module Agent
|
8
|
-
module Reporting
|
9
|
-
# Bot blocker IA result details info.
|
10
|
-
class BotBlockerDetails < ProtectRuleDetails
|
11
|
-
# @return [String]
|
12
|
-
attr_accessor :bot
|
13
|
-
# User agent header value
|
14
|
-
#
|
15
|
-
# @return [String]
|
16
|
-
attr_accessor :user_agent
|
17
|
-
|
18
|
-
def to_controlled_hash
|
19
|
-
{
|
20
|
-
bot: bot,
|
21
|
-
userAgent: user_agent
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|