contrast-agent 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ext/extconf_common.rb +88 -14
  3. data/lib/contrast/agent/assess/policy/source_method.rb +13 -4
  4. data/lib/contrast/agent/assess/policy/trigger_method.rb +12 -18
  5. data/lib/contrast/agent/excluder/excluder.rb +64 -31
  6. data/lib/contrast/agent/protect/rule/base.rb +4 -6
  7. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker.rb +1 -1
  8. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +2 -2
  9. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +1 -1
  10. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
  11. data/lib/contrast/agent/protect/rule/deserialization/deserialization.rb +2 -2
  12. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +1 -1
  13. data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +1 -1
  14. data/lib/contrast/agent/protect/rule/utils/filters.rb +6 -6
  15. data/lib/contrast/agent/protect/rule/xxe/xxe.rb +1 -1
  16. data/lib/contrast/agent/reporting/client/interface.rb +132 -0
  17. data/lib/contrast/agent/reporting/client/interface_base.rb +27 -0
  18. data/lib/contrast/agent/reporting/connection_status.rb +0 -1
  19. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +6 -4
  20. data/lib/contrast/agent/reporting/reporter.rb +11 -26
  21. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
  22. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
  23. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +47 -6
  24. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +40 -31
  25. data/lib/contrast/agent/reporting/reporting_utilities/resend.rb +144 -0
  26. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +35 -13
  27. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +14 -1
  28. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +11 -11
  29. data/lib/contrast/agent/request/request.rb +27 -12
  30. data/lib/contrast/agent/telemetry/base.rb +18 -19
  31. data/lib/contrast/agent/telemetry/exception/obfuscate.rb +97 -0
  32. data/lib/contrast/agent/telemetry/exception.rb +1 -0
  33. data/lib/contrast/agent/version.rb +1 -1
  34. data/lib/contrast/components/config/sources.rb +6 -5
  35. data/lib/contrast/components/settings.rb +9 -0
  36. data/lib/contrast/config/diagnostics/source_config_value.rb +5 -1
  37. data/lib/contrast/config/diagnostics/tools.rb +4 -4
  38. data/lib/contrast/config/validate.rb +2 -2
  39. data/lib/contrast/configuration.rb +11 -19
  40. data/lib/contrast/framework/grape/support.rb +1 -2
  41. data/lib/contrast/framework/manager.rb +17 -8
  42. data/lib/contrast/framework/rack/support.rb +99 -1
  43. data/lib/contrast/framework/rails/support.rb +1 -2
  44. data/lib/contrast/framework/sinatra/support.rb +1 -2
  45. data/lib/contrast/logger/aliased_logging.rb +18 -9
  46. data/lib/contrast/utils/hash_utils.rb +21 -2
  47. data/lib/contrast/utils/request_utils.rb +14 -0
  48. data/resources/assess/policy.json +11 -0
  49. metadata +6 -3
  50. 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.deep_merge(cli_options, config_kv)
84
+ config_kv = Contrast::Utils::HashUtils.precedence_merge(cli_options, config_kv)
85
85
  @_source_file_extensions = Contrast::Utils::HashUtils.
86
- deep_merge(assign_source_to(cli_options,
87
- Contrast::Components::Config::Sources::COMMAND_LINE),
88
- @_source_file_extensions)
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::APP_CONFIGURATION_FILE.map(&:downcase)
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
- # config.merge!(file.values) { |_key, oldval, _newval| oldval = oldval }
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 { |path| @_source_file_extensions = precedence_merge!(@_source_file_extensions, path) }
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[0]
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] a Dtm describing the route
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
- # If we're mounted on Rails, use Rails.
91
- if @_frameworks.include?(Contrast::Framework::Rails::Support)
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
- # If we know the framework, use it.
96
- return @_frameworks[0].retrieve_request(env) if @_frameworks.length == 1
97
-
98
- # Fall back on a regular Rack::Request
99
- ::Rack::Request.new(env)
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
- 'rack -- don\'t let me be detected'
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] a Dtm describing the route
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] a Dtm describing the route
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
- stack_trace = wrapped_caller_locations
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
- caller_frame = stack_trace[caller_idx]
80
- stack_frame_type = caller_frame.path.delete_prefix(Dir.pwd)
81
- stack_frame_function = caller_frame.label
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, stack_trace, caller_idx)
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
- stack_frame = Contrast::Agent::Telemetry::Exception::StackFrame.build(caller.label,
145
- caller.path.delete_prefix(Dir.pwd))
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 deep_merge hsh, other_hsh
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) ? deep_merge(old_value, new_value) : old_value
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.1.0
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-04-13 00:00:00.000000000 Z
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