contrast-agent 6.14.0 → 6.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__scope/cs__scope.c +2 -1
  3. data/lib/contrast/agent/{assess.rb → assess/assess.rb} +1 -1
  4. data/lib/contrast/agent/{module_data.rb → assess/module_data.rb} +0 -0
  5. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +3 -0
  6. data/lib/contrast/agent/assess/policy/policy_node.rb +3 -2
  7. data/lib/contrast/agent/assess/policy/propagation_method.rb +2 -2
  8. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +0 -1
  9. data/lib/contrast/agent/assess/policy/source_method.rb +1 -1
  10. data/lib/contrast/agent/assess/policy/trigger_method.rb +36 -1
  11. data/lib/contrast/agent/{excluder.rb → excluder/excluder.rb} +0 -0
  12. data/lib/contrast/agent/{exclusion_matcher.rb → excluder/exclusion_matcher.rb} +0 -0
  13. data/lib/contrast/agent/{at_exit_hook.rb → hooks/at_exit_hook.rb} +0 -0
  14. data/lib/contrast/agent/{tracepoint_hook.rb → hooks/tracepoint_hook.rb} +0 -0
  15. data/lib/contrast/agent/inventory/database_config.rb +1 -0
  16. data/lib/contrast/agent/{inventory.rb → inventory/inventory.rb} +0 -0
  17. data/lib/contrast/agent/{middleware.rb → middleware/middleware.rb} +3 -3
  18. data/lib/contrast/agent/{static_analysis.rb → middleware/static_analysis.rb} +0 -0
  19. data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +5 -5
  20. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +1 -1
  21. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
  22. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
  23. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
  24. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -1
  25. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
  26. data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +1 -1
  27. data/lib/contrast/agent/protect/rule/base.rb +121 -134
  28. data/lib/contrast/agent/protect/rule/{bot_blocker.rb → bot_blocker/bot_blocker.rb} +2 -2
  29. data/lib/contrast/agent/protect/rule/{cmd_injection.rb → cmdi/cmd_injection.rb} +1 -1
  30. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +3 -3
  31. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
  32. data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +2 -2
  33. data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +2 -2
  34. data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +1 -1
  35. data/lib/contrast/agent/protect/rule/{deserialization.rb → deserialization/deserialization.rb} +2 -2
  36. data/lib/contrast/agent/protect/rule/{no_sqli.rb → no_sqli/no_sqli.rb} +3 -3
  37. data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +1 -1
  38. data/lib/contrast/agent/protect/rule/{path_traversal.rb → path_traversal/path_traversal.rb} +2 -2
  39. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +3 -3
  40. data/lib/contrast/agent/protect/rule/{sql_sample_builder.rb → sqli/sql_sample_builder.rb} +0 -1
  41. data/lib/contrast/agent/protect/rule/{sqli.rb → sqli/sqli.rb} +2 -2
  42. data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +1 -1
  43. data/lib/contrast/agent/protect/rule/{unsafe_file_upload.rb → unsafe_file_upload/unsafe_file_upload.rb} +2 -2
  44. data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +1 -1
  45. data/lib/contrast/agent/protect/rule/utils/builders.rb +111 -0
  46. data/lib/contrast/agent/protect/rule/utils/filters.rb +110 -0
  47. data/lib/contrast/agent/protect/rule/{xss.rb → xss/xss.rb} +2 -2
  48. data/lib/contrast/agent/protect/rule/{xxe.rb → xxe/xxe.rb} +2 -2
  49. data/lib/contrast/agent/protect/rule.rb +8 -9
  50. data/lib/contrast/agent/{disable_reaction.rb → reactions/disable_reaction.rb} +0 -0
  51. data/lib/contrast/agent/reporting/reporter.rb +1 -1
  52. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +3 -3
  53. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +1 -1
  54. data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +1 -1
  55. data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +1 -1
  56. data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +1 -1
  57. data/lib/contrast/agent/{request.rb → request/request.rb} +0 -0
  58. data/lib/contrast/agent/{request_context.rb → request/request_context.rb} +3 -3
  59. data/lib/contrast/agent/{request_context_extend.rb → request/request_context_extend.rb} +0 -0
  60. data/lib/contrast/agent/{request_handler.rb → request/request_handler.rb} +0 -0
  61. data/lib/contrast/agent/{response.rb → response/response.rb} +0 -0
  62. data/lib/contrast/agent/{scope.rb → scope/scope.rb} +0 -0
  63. data/lib/contrast/agent/telemetry/base.rb +2 -2
  64. data/lib/contrast/agent/{telemetry.rb → telemetry/telemetry.rb} +0 -0
  65. data/lib/contrast/agent/{thread.rb → thread/thread.rb} +0 -0
  66. data/lib/contrast/agent/{thread_watcher.rb → thread/thread_watcher.rb} +0 -0
  67. data/lib/contrast/agent/{worker_thread.rb → thread/worker_thread.rb} +0 -0
  68. data/lib/contrast/agent/version.rb +1 -1
  69. data/lib/contrast/agent.rb +11 -11
  70. data/lib/contrast/components/agent.rb +1 -1
  71. data/lib/contrast/components/assess.rb +1 -0
  72. data/lib/contrast/{agent → components}/rule_set.rb +0 -0
  73. data/lib/contrast/components/scope.rb +1 -1
  74. data/lib/contrast/components/settings.rb +1 -1
  75. data/lib/contrast/extension/assess/exec_trigger.rb +1 -1
  76. data/lib/contrast/extension/assess/string.rb +4 -3
  77. data/lib/contrast.rb +1 -1
  78. data/ruby-agent.gemspec +4 -2
  79. metadata +53 -58
  80. data/lib/contrast/agent/protect/rule/base_service.rb +0 -175
@@ -6,6 +6,8 @@ require 'contrast/components/scope'
6
6
  require 'contrast/utils/object_share'
7
7
  require 'contrast/agent/reporting/attack_result/response_type'
8
8
  require 'contrast/agent/reporting/attack_result/attack_result'
9
+ require 'contrast/agent/protect/rule/utils/builders'
10
+ require 'contrast/agent/protect/rule/utils/filters'
9
11
 
10
12
  module Contrast
11
13
  module Agent
@@ -18,9 +20,11 @@ module Contrast
18
20
  class Base
19
21
  include Contrast::Components::Logger::InstanceMethods
20
22
  include Contrast::Components::Scope::InstanceMethods
23
+ include Contrast::Agent::Protect::Rule::Builders
24
+ include Contrast::Agent::Protect::Rule::Filters
21
25
 
26
+ RULE_NAME = 'base-rule'
22
27
  BLOCKING_MODES = Set.new(%i[BLOCK BLOCK_AT_PERIMETER]).cs__freeze
23
- POSTFILTER_MODES = Set.new(%i[BLOCK MONITOR]).cs__freeze
24
28
  STACK_COLLECTION_RESULTS = Set.new([
25
29
  Contrast::Agent::Reporting::ResponseType::BLOCKED,
26
30
  Contrast::Agent::Reporting::ResponseType::MONITORED
@@ -34,30 +38,47 @@ module Contrast
34
38
  sql-injection-semantic-dangerous-functions
35
39
  ].cs__freeze
36
40
 
41
+ # @return [Symbol]
37
42
  attr_reader :mode
38
43
 
44
+ # Initializes new rule and sets it mode from settings
45
+ #
46
+ # @return mode [Symbol]
39
47
  def initialize
40
48
  ::Contrast::PROTECT.defend_rules[rule_name] = self
41
49
  @mode = mode_from_settings
42
50
  end
43
51
 
52
+ # Message to display when the rule is triggered.
53
+ #
54
+ # @return [String]
55
+ def block_message
56
+ "Contrast Security Protect #{ rule_name } Triggered. Response blocked."
57
+ end
58
+
44
59
  # Should return the name as it is known to Teamserver; defaults to class
60
+ #
61
+ # @return [String]
45
62
  def rule_name
46
- cs__class.cs__name
63
+ RULE_NAME
47
64
  end
48
65
 
49
66
  # Should return list of all sub_rules.
50
67
  # Extend for each main rule any sub-rules.
68
+ #
69
+ # @return [Array]
51
70
  def sub_rules
52
71
  Contrast::Utils::ObjectShare::EMPTY_ARRAY
53
72
  end
54
73
 
55
74
  # The classification module used for each specific rule to
56
75
  # classify input data and score it. Extend for each rule.
76
+ #
77
+ # @return [Module]
57
78
  def classification; end
58
79
 
59
- # Input Classification stage is done to determine if an user input is
60
- # DEFINITEATTACK or to be ignored.
80
+ # Generic method forwarder, shorthand for classification:
81
+ # Input Classification stage is done to determine if an user input is DEFINITEATTACK or to be ignored.
61
82
  #
62
83
  # @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
63
84
  # @param value [Hash<String>] the value of the input.
@@ -69,6 +90,9 @@ module Contrast
69
90
  classification.classify(rule_name, input_type, value, input_analysis)
70
91
  end
71
92
 
93
+ # Check if rule is enabled.
94
+ #
95
+ # @return [Boolean]
72
96
  def enabled?
73
97
  # 1. it is not enabled because protect is not enabled
74
98
  return false unless ::Contrast::AGENT.enabled?
@@ -81,111 +105,23 @@ module Contrast
81
105
  @mode != :NO_ACTION
82
106
  end
83
107
 
108
+ # Check if the rule is excluded by checking inside array of exclusions
109
+ #
110
+ # @param exclusions [Array<Contrast::Agent::Reporting::Settings::ExclusionBase>]
84
111
  def excluded? exclusions
85
112
  Array(exclusions).any? do |ex|
86
113
  ex.protection_rule?(rule_name)
87
114
  end
88
115
  end
89
116
 
90
- def infilter? _context
91
- false
92
- end
93
-
94
- # return false for rules that modify or inspect the response body
117
+ # Return false for rules that modify or inspect the response body
95
118
  # during postfilter
96
119
  #
97
- # @return [Boolean] if the rule can safely be evaluated in streaming
98
- # requests
120
+ # @return [Boolean] if the rule can safely be evaluated in streaming requests
99
121
  def stream_safe?
100
122
  true
101
123
  end
102
124
 
103
- # Actions required for the rules that have to happen before the
104
- # application has completed its processing of the request.
105
- #
106
- # For most rules, these actions are performed within the analysis
107
- # engine and communicated as an input analysis result. Those that
108
- # require specific action need to provide that action.
109
- #
110
- # @param _context [Contrast::Agent::RequestContext] the context for
111
- # the current request
112
- def prefilter _context; end
113
-
114
- # This should only ever be called directly from patched code and will
115
- # have a different implementation based on the rule. As such, there
116
- # is not parent implementation.
117
- #
118
- # @param _context [Contrast::Agent::RequestContext] the context for
119
- # the current request
120
- # @param _match_string [String] the input that violated the rule and
121
- # matched the attack detection logic
122
- # @param _kwargs [Hash] key-value pairs used by the rule to build a
123
- # report.
124
- def infilter _context, _match_string, **_kwargs; end
125
-
126
- # Actions required for the rules that have to happen after the
127
- # application has completed its processing of the request.
128
- #
129
- # Any implementation here needs to account for the fact that
130
- # responses may be streaming and, as such, transformations of the
131
- # response itself may not be permissible.
132
- #
133
- # @param _context [Contrast::Agent::RequestContext] the context for
134
- # the current request
135
- def postfilter _context; end
136
-
137
- # A given input, candidate_string, was determined to violate a
138
- # protect rule and did exploit the application, or at least made it
139
- # to exploitable code in the case where we blocked the attack. As
140
- # such, we need to build a result to report this violation to
141
- # TeamServer.
142
- #
143
- # @param context [Contrast::Agent::RequestContext] the context of the
144
- # request in which this input is evaluated.
145
- # @param ia_result [Contrast::Agent::Reporting::InputAnalysis] the
146
- # analysis of the input that was determined to be an attack
147
- # @param result [Contrast::Agent::Reporting::AttackResult, nil] previous
148
- # attack result for this rule, if one exists, in the case of
149
- # multiple inputs being found to violate the protection criteria
150
- # @param candidate_string [String] the value of the input which may
151
- # be an attack
152
- # @param kwargs [Hash] key - value pairs of context individual rules
153
- # need to build out details to send to the TeamServer to tell the
154
- # story of the attack
155
- # @return [Contrast::Agent::Reporting::AttackResult] the attack result from
156
- # this input
157
- def build_attack_with_match context, ia_result, result, candidate_string, **kwargs
158
- result ||= build_attack_result(context)
159
- update_successful_attack_response(context, ia_result, result, candidate_string)
160
- append_sample(context, ia_result, result, candidate_string, **kwargs)
161
-
162
- result
163
- end
164
-
165
- # A given input, candidate_string, was determined to violate a
166
- # protect rule but did not exploit the application. As such, we need
167
- # to build a result to report this violation to TeamServer.
168
- #
169
- # @param context [Contrast::Agent::RequestContext, nil] the context of the
170
- # request in which this input is evaluated.
171
- # @param ia_result [Contrast::Agent::Reporting::InputAnalysis] the
172
- # analysis of the input that was determined to be an attack
173
- # @param result [Contrast::Agent::Reporting::AttackResult, nil] previous
174
- # attack result for this rule, if one exists, in the case of
175
- # multiple inputs being found to violate the protection criteria
176
- # @param kwargs [Hash, nil] key - value pairs of context individual rules
177
- # need to build out details to send to TeamServer to tell the
178
- # story of the attack
179
- # @return [Contrast::Agent::Reporting::AttackResult] the attack result from
180
- # this input
181
- def build_attack_without_match context, ia_result, result, **kwargs
182
- result ||= build_attack_result(context)
183
- update_perimeter_attack_response(context, ia_result, result)
184
- append_sample(context, ia_result, result, nil, **kwargs)
185
-
186
- result
187
- end
188
-
189
125
  # Attach the given result to the current request's context to report
190
126
  # it to TeamServer
191
127
  #
@@ -211,44 +147,88 @@ module Contrast
211
147
 
212
148
  protected
213
149
 
150
+ # Assign the mode from active settings.
151
+ #
152
+ # @return mode [Symbol]
214
153
  def mode_from_settings
215
154
  ::Contrast::PROTECT.rule_mode(rule_name).tap do |mode|
216
155
  logger.trace('Retrieving rule mode', rule: rule_name, mode: mode)
217
156
  end
218
157
  end
219
158
 
159
+ # Rule blocked check
160
+ #
161
+ # @return [Boolean]
220
162
  def blocked?
221
163
  enabled? && BLOCKING_MODES.include?(mode)
222
164
  end
223
165
 
166
+ # Check if the protect rules is excluded by url from the exclusion rules for this application.
167
+ #
224
168
  # @param rule_id [String]
225
169
  # @param request_path [String] Current request path
226
170
  def protect_excluded_by_url? rule_id, request_path
227
171
  Contrast::SETTINGS.excluder.protect_excluded_by_url?(rule_id, request_path)
228
172
  end
229
173
 
174
+ # Check if the protect rules is excluded by input from the exclusion rules for this application.
175
+ #
230
176
  # @param results [Array<Contrast::Agent::Reporting::InputAnalysis>]
231
177
  # @param request_path [String] Current request path
232
178
  def protect_excluded_by_input? results, request_path
233
179
  Contrast::SETTINGS.excluder.protect_excluded_by_input?(results, request_path)
234
180
  end
235
181
 
182
+ # Allows for the InputAnalysis from Agent Library to be extracted early
183
+ #
184
+ # @param context [Contrast::Agent::RequestContext]
185
+ # @param potential_attack_string [String, nil]
186
+ # @param ia_results [Array<Contrast::Agent::Reporting::InputAnalysis>]
187
+ # @param **kwargs
188
+ # @return [Contrast::Agent::Reporting, nil]
189
+ def find_attacker_with_results context, potential_attack_string, ia_results, **kwargs
190
+ logger.trace('Checking vectors for attacks', rule: rule_name, input: potential_attack_string)
191
+
192
+ result = nil
193
+ ia_results.each do |ia_result|
194
+ if potential_attack_string
195
+ idx = potential_attack_string.index(ia_result.value)
196
+ next unless idx
197
+
198
+ result = build_attack_with_match(context, ia_result, result, potential_attack_string, **kwargs)
199
+ else
200
+ result = build_attack_without_match(context, ia_result, result, **kwargs)
201
+ end
202
+ end
203
+ result
204
+ end
205
+
236
206
  # By default, rules do not have to find attackers as they do not have
237
207
  # Input Analysis. Any attack for the standard rule will be evaluated
238
208
  # at execution time. As such, those rules are expected to implement
239
209
  # this custom behavior
240
210
  #
241
- # @param _context [Contrast::Agent::RequestContext] the context for
211
+ # @param context [Contrast::Agent::RequestContext] the context for
242
212
  # the current request
243
- # @param _potential_attack_string [String] the input that may violate
213
+ # @param potential_attack_string [String] the input that may violate
244
214
  # the rule and matched the attack detection logic
245
- # @param _kwargs [Hash] key-value pairs used by the rule to build a
215
+ # @param **kwargs [Hash] key-value pairs used by the rule to build a
246
216
  # report.
247
- # @raise[NoMethodError] raises if subclass did not implement this method on extend
248
- def find_attacker _context, _potential_attack_string, **_kwargs
249
- raise(NoMethodError, "Rule #{ rule_name } did not implement find_attack")
217
+ def find_attacker context, potential_attack_string, **kwargs
218
+ ia_results = gather_ia_results(context)
219
+ find_attacker_with_results(context, potential_attack_string, ia_results, **kwargs)
250
220
  end
251
221
 
222
+ # Update the message's response type to be send to TS, depending on
223
+ # the attack results, and rule policy. The match with rules is also
224
+ # logged, and if an attack counter of the ia_result is increased.
225
+ #
226
+ # @param context [Contrast::Agent::RequestContext] the context for
227
+ # the current request
228
+ # @param ia_result [Contrast::Agent::Reporting::InputAnalysis]
229
+ # @param result [Contrast::Agent::Reporting::AttackResult]
230
+ # @param attack_string [String] Potential attack vector
231
+ # @return [Contrast::Agent::Reporting::AttackResult]
252
232
  def update_successful_attack_response context, ia_result, result, attack_string = nil
253
233
  case mode
254
234
  when :MONITOR
@@ -268,6 +248,8 @@ module Contrast
268
248
  result
269
249
  end
270
250
 
251
+ # Update the response type for perimeter rules ( BAP ).
252
+ #
271
253
  # @param context [Contrast::Agent::RequestContext] the context of the
272
254
  # request in which this input is evaluated.
273
255
  # @param ia_result [Contrast::Agent::Reporting::InputAnalysis] the
@@ -275,6 +257,7 @@ module Contrast
275
257
  # @param result [Contrast::Agent::Reporting::AttackResult] previous
276
258
  # attack result for this rule, if one exists, in the case of
277
259
  # multiple inputs being found to violate the protection criteria
260
+ # @return [Contrast::Agent::Reporting::AttackResult]
278
261
  def update_perimeter_attack_response context, ia_result, result
279
262
  if mode == :BLOCK_AT_PERIMETER
280
263
  result.response = if blocked_rule?(ia_result)
@@ -291,16 +274,12 @@ module Contrast
291
274
  result
292
275
  end
293
276
 
294
- # Set up an attack result for the current rule
277
+ # Builds a caller's stack and appends it to a passed Rasp rule sample.
295
278
  #
296
- # @param _context [Contrast::Agent::RequestContext] the context of
297
- # the current request
298
- # @return [Contrast::Agent::Reporting::AttackResult]
299
- def build_attack_result _context; end
300
-
301
279
  # @param sample [Contrast::Agent::Reporting::RaspRuleSample]
302
280
  # @param result [Contrast::Agent::Reporting::AttackResult, nil] previous attack result for this rule, if one
303
281
  # exists, in the case of multiple inputs being found to violate the protection criteria
282
+ # @return [Contrast::Agent::Reporting::RaspRuleSample]
304
283
  def append_stack sample, result
305
284
  return unless sample
306
285
  return unless STACK_COLLECTION_RESULTS.include?(result&.response)
@@ -311,6 +290,8 @@ module Contrast
311
290
  sample.stack.concat(stack)
312
291
  end
313
292
 
293
+ # Appends an attack sample to existing attack results.
294
+ #
314
295
  # @param context [Contrast::Agent::RequestContext] the context of the request in which this input is
315
296
  # evaluated.
316
297
  # @param ia_result [Contrast::Agent::Reporting::Settings::InputAnalysisResult] the analysis of the input that
@@ -332,27 +313,8 @@ module Contrast
332
313
  result.samples << sample
333
314
  end
334
315
 
335
- # Override if rule can make use of the candidate string or kwargs to
336
- # build rasp rule sample.
316
+ # Logs if a rule have matched an attack vector and it's being triggered.
337
317
  #
338
- # @param context [Contrast::Agent::RequestContext]
339
- # @param ia_result [Contrast::Agent::Reporting::Settings::InputAnalysisResult] the analysis of the input that
340
- # was determined to be an attack
341
- # @param _candidate_string [String] potential attack value/ input containing attack value
342
- # @param _kwargs [Hash]
343
- # @return [Contrast::Agent::Reporting::RaspRuleSample]
344
- def build_sample context, ia_result, _candidate_string, **_kwargs
345
- build_base_sample(context, ia_result)
346
- end
347
-
348
- # @param context [Contrast::Agent::RequestContext]
349
- # @param ia_result [Contrast::Agent::Reporting::Settings::InputAnalysisResult] the analysis of the input that
350
- # was determined to be an attack
351
- # @return [Contrast::Agent::Reporting::RaspRuleSample]
352
- def build_base_sample context, ia_result
353
- Contrast::Agent::Reporting::RaspRuleSample.build(context, ia_result)
354
- end
355
-
356
318
  def log_rule_matched _context, ia_result, response, _matched_string = nil
357
319
  logger.debug('A successful attack was detected',
358
320
  rule: rule_name,
@@ -362,12 +324,26 @@ module Contrast
362
324
  result: response)
363
325
  end
364
326
 
365
- # This method returns the symbol for the enum
327
+ # This method will check against the current context IA and find any results that match
328
+ # the rule id.
366
329
  #
367
- # @param enum [Enumerable]
368
- # @return [Symbol]
369
- def extract_input_type enum
370
- Contrast::Api::Dtm::UserInput::InputType.get_name_by_tag(enum)
330
+ # @param context [Contrast::Agent::RequestContext]
331
+ # @return [Array<Contrast::Agent::Reporting::InputAnalysis>]
332
+ def gather_ia_results context
333
+ return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless context&.agent_input_analysis&.results
334
+
335
+ context.agent_input_analysis.results.select do |ia_result|
336
+ ia_result.rule_id == rule_name && ia_result.score_level != Contrast::Agent::Reporting::ScoreLevel::IGNORE
337
+ end
338
+ end
339
+
340
+ # Check to if result is blocked. Used for raise check.
341
+ #
342
+ # @param result [Contrast::Agent::Reporting::AttackResult]
343
+ def blocked_violation? result
344
+ return false unless result
345
+
346
+ result.response == Contrast::Agent::Reporting::ResponseType::BLOCKED
371
347
  end
372
348
 
373
349
  private
@@ -407,6 +383,17 @@ module Contrast
407
383
  Contrast::Agent::Reporting::ResponseType::PROBED
408
384
  end
409
385
  end
386
+
387
+ # @param context [Contrast::Agent::RequestContext]
388
+ # @param potential_attack_string [String, nil]
389
+ # @return [Contrast::Agent::Reporting, nil]
390
+ def find_postfilter_attacker context, potential_attack_string, **kwargs
391
+ ia_results = gather_ia_results(context)
392
+ ia_results.select! do |ia_result|
393
+ ia_result.score_level == Contrast::Agent::Reporting::ScoreLevel::DEFINITEATTACK
394
+ end
395
+ find_attacker_with_results(context, potential_attack_string, ia_results, **kwargs)
396
+ end
410
397
  end
411
398
  end
412
399
  end
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/components/logger'
6
6
  require 'contrast/agent/reporting/input_analysis/input_type'
7
7
  require 'contrast/agent/reporting/input_analysis/score_level'
@@ -13,7 +13,7 @@ module Contrast
13
13
  module Protect
14
14
  module Rule
15
15
  # The Ruby implementation of the Protect BotBlocker rule.
16
- class BotBlocker < Contrast::Agent::Protect::Rule::BaseService
16
+ class BotBlocker < Contrast::Agent::Protect::Rule::Base
17
17
  include Contrast::Components::Logger::InstanceMethods
18
18
  include Contrast::Agent::Reporting::InputType
19
19
 
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/utils/stack_trace_utils'
6
6
  require 'contrast/utils/object_share'
7
7
  require 'contrast/components/logger'
@@ -1,11 +1,11 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
5
- require 'contrast/agent/request_context'
4
+ require 'contrast/agent/protect/rule/base'
5
+ require 'contrast/agent/request/request_context'
6
6
  require 'contrast/utils/object_share'
7
7
  require 'contrast/agent/protect/rule/cmdi/cmdi_base_rule'
8
- require 'contrast/agent/protect/rule/cmd_injection'
8
+ require 'contrast/agent/protect/rule/cmdi/cmd_injection'
9
9
 
10
10
  module Contrast
11
11
  module Agent
@@ -12,7 +12,7 @@ module Contrast
12
12
  module Rule
13
13
  # The Ruby implementation of the Protect Command Injection Semantic
14
14
  # Dangerous Path sub-rule. This rule should report
15
- class CmdiBaseRule < Contrast::Agent::Protect::Rule::BaseService
15
+ class CmdiBaseRule < Contrast::Agent::Protect::Rule::Base
16
16
  include Contrast::Components::Logger::InstanceMethods
17
17
  include Contrast::Agent::Reporting::InputType
18
18
 
@@ -1,8 +1,8 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
5
- require 'contrast/agent/request_context'
4
+ require 'contrast/agent/protect/rule/base'
5
+ require 'contrast/agent/request/request_context'
6
6
  require 'contrast/utils/object_share'
7
7
  require 'contrast/agent/protect/rule/cmdi/cmdi_base_rule'
8
8
 
@@ -1,8 +1,8 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
5
- require 'contrast/agent/request_context'
4
+ require 'contrast/agent/protect/rule/base'
5
+ require 'contrast/agent/request/request_context'
6
6
  require 'contrast/utils/object_share'
7
7
  require 'contrast/agent/protect/rule/cmdi/cmdi_base_rule'
8
8
 
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/cmd_injection'
4
+ require 'contrast/agent/protect/rule/cmdi/cmd_injection'
5
5
  require 'contrast/agent/reporting/input_analysis/score_level'
6
6
  require 'contrast/agent/protect/input_analyzer/input_analyzer'
7
7
  require 'contrast/utils/input_classification_base'
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/agent/reporting/details/untrusted_deserialization_details'
6
6
  require 'contrast/components/logger'
7
7
 
@@ -11,7 +11,7 @@ module Contrast
11
11
  module Rule
12
12
  # This class handles our implementation of the Untrusted
13
13
  # Deserialization Protect rule.
14
- class Deserialization < Contrast::Agent::Protect::Rule::BaseService
14
+ class Deserialization < Contrast::Agent::Protect::Rule::Base
15
15
  # The TeamServer recognized name of this rule
16
16
  include Contrast::Components::Logger::InstanceMethods
17
17
  # Used to name this input since input analysis isn't done for this
@@ -1,8 +1,8 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
5
- require 'contrast/agent/protect/rule/sql_sample_builder'
4
+ require 'contrast/agent/protect/rule/base'
5
+ require 'contrast/agent/protect/rule/sqli/sql_sample_builder'
6
6
  require 'contrast/agent/reporting/input_analysis/input_type'
7
7
  require 'contrast/agent/protect/rule/no_sqli/no_sqli_input_classification'
8
8
 
@@ -11,7 +11,7 @@ module Contrast
11
11
  module Protect
12
12
  module Rule
13
13
  # The Ruby implementation of the Protect NoSQL Injection rule.
14
- class NoSqli < Contrast::Agent::Protect::Rule::BaseService
14
+ class NoSqli < Contrast::Agent::Protect::Rule::Base
15
15
  # Generate a sample for the No-SQL injection detection rule, allowing for reporting to and rendering
16
16
  # by TeamServer
17
17
  include SqlSampleBuilder::NoSqliSample
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/utils/object_share'
5
- require 'contrast/agent/protect/rule/no_sqli'
5
+ require 'contrast/agent/protect/rule/no_sqli/no_sqli'
6
6
  require 'contrast/agent/protect/input_analyzer/input_analyzer'
7
7
  require 'contrast/utils/input_classification_base'
8
8
 
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass'
6
6
  require 'contrast/agent/reporting/input_analysis/input_type'
7
7
  require 'contrast/agent/reporting/input_analysis/score_level'
@@ -17,7 +17,7 @@ module Contrast
17
17
  module Rule
18
18
  # This class handles our implementation of the Path Traversal
19
19
  # Protect rule.
20
- class PathTraversal < Contrast::Agent::Protect::Rule::BaseService
20
+ class PathTraversal < Contrast::Agent::Protect::Rule::Base
21
21
  include Contrast::Agent::Reporting::InputType
22
22
 
23
23
  NAME = 'path-traversal'
@@ -1,9 +1,9 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/agent/reporting/details/path_traversal_semantic_analysis_details'
6
- require 'contrast/agent/request_context'
6
+ require 'contrast/agent/request/request_context'
7
7
  require 'contrast/utils/string_utils'
8
8
  require 'contrast/agent_lib/api/path_semantic_file_security_bypass'
9
9
  require 'contrast/agent_lib/interface'
@@ -14,7 +14,7 @@ module Contrast
14
14
  module Rule
15
15
  # The Ruby implementation of the Protect Path Traversal Semantic
16
16
  # Bypass sub-rule. This rule should report the attack result
17
- class PathTraversalSemanticBypass < Contrast::Agent::Protect::Rule::BaseService
17
+ class PathTraversalSemanticBypass < Contrast::Agent::Protect::Rule::Base
18
18
  NAME = 'path-traversal-semantic-file-security-bypass'
19
19
  SYSTEM_PATHS = %w[
20
20
  /proc/self
@@ -2,7 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/protect/rule/base'
5
- require 'contrast/agent/protect/rule/base_service'
6
5
  require 'contrast/agent/reporting/details/sqli_details'
7
6
  require 'contrast/agent/reporting/details/no_sqli_details'
8
7
 
@@ -1,9 +1,9 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/agent/protect/policy/applies_sqli_rule'
6
- require 'contrast/agent/protect/rule/sql_sample_builder'
6
+ require 'contrast/agent/protect/rule/sqli/sql_sample_builder'
7
7
  require 'contrast/agent/reporting/input_analysis/input_type'
8
8
  require 'contrast/agent/protect/rule/sqli/sqli_base_rule'
9
9
  require 'contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions'
@@ -6,7 +6,7 @@ module Contrast
6
6
  module Protect
7
7
  module Rule
8
8
  # This is the Base Rule
9
- class SqliBaseRule < Contrast::Agent::Protect::Rule::BaseService
9
+ class SqliBaseRule < Contrast::Agent::Protect::Rule::Base
10
10
  include Contrast::Components::Logger::InstanceMethods
11
11
  include Contrast::Agent::Reporting::InputType
12
12
 
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/protect/rule/base_service'
4
+ require 'contrast/agent/protect/rule/base'
5
5
  require 'contrast/agent/reporting/input_analysis/input_type'
6
6
  require 'contrast/agent/reporting/input_analysis/score_level'
7
7
  require 'contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification'
@@ -13,7 +13,7 @@ module Contrast
13
13
  # The Ruby implementation of the Protect Unsafe File Upload rule.
14
14
  # The unsafe-file-upload rule can trigger the following results:
15
15
  # BLOCKED in Blocking mode and SUSPICIOUS in Monitor mode.
16
- class UnsafeFileUpload < Contrast::Agent::Protect::Rule::BaseService
16
+ class UnsafeFileUpload < Contrast::Agent::Protect::Rule::Base
17
17
  include Contrast::Agent::Reporting::InputType
18
18
 
19
19
  NAME = 'unsafe-file-upload'
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/utils/object_share'
5
- require 'contrast/agent/protect/rule/unsafe_file_upload'
5
+ require 'contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload'
6
6
  require 'contrast/agent/protect/input_analyzer/input_analyzer'
7
7
  require 'contrast/utils/input_classification_base'
8
8