Module: Contrast::Agent::Protect::Rule::Filters

Included in:
Base
Defined in:
lib/contrast/agent/protect/rule/utils/filters.rb

Overview

Module to hold required generic filters (prefilter, infilter, postfilter)

Constant Summary collapse

POSTFILTER_MODES =
Set.new(%i[BLOCK MONITOR]).cs__freeze

Instance Method Summary collapse

Instance Method Details

#infilter(context, match_string, _kwargs) ⇒ Object

This should only ever be called directly from patched code and will have a different implementation based on the rule. As such, there is not parent implementation.

Parameters:

  • context (Contrast::Agent::RequestContext)

    the context for the current request

  • match_string (String)

    the input that violated the rule and matched the attack detection logic

  • _kwargs (Hash)

    key-value pairs used by the rule to build a report.

Raises:



62
63
64
65
66
67
68
69
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 62

def infilter context, match_string, _kwargs
  return unless infilter?(context)
  return unless (result = build_violation(context, match_string))

  append_to_activity(context, result)
  record_triggered(context)
  raise(Contrast::SecurityException.new(self, block_message)) if blocked?
end

#infilter?(context) ⇒ Boolean

Infilter check always called before infilter to check if the rule is infilter capable, not disabled or in other way excluded by url or input exclusions.

Parameters:

Returns:

  • (Boolean)


76
77
78
79
80
81
82
83
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 76

def infilter? context
  return false unless enabled?
  return false unless (results = gather_ia_results(context)) && results.any?
  return false if protect_excluded_by_url?(rule_name)
  return false if protect_excluded_by_input?(results)

  true
end

#postfilter(context) ⇒ Object

Actions required for the rules that have to happen after the application has completed its processing of the request.

Any implementation here needs to account for the fact that responses may be streaming and, as such, transformations of the response itself may not be permissible.

Override for rules that need the response Currently postfilter can be applied to streamed responses, if any logic within postfilter changes to modify the response streamed responses will break



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 110

def postfilter context
  return unless postfilter?(context)

  result = find_postfilter_attacker(context, nil)
  return unless result&.samples&.any?

  append_to_activity(context, result)
  record_triggered(context)
  return unless blocked_violation?(result)

  raise(Contrast::SecurityException.new(self, "#{ rule_name } triggered in postfilter. Response blocked."))
end

#postfilter?(context) ⇒ Boolean

Check befor commiting infilter

Parameters:

Returns:

  • (Boolean)


88
89
90
91
92
93
94
95
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 88

def postfilter? context
  return false unless enabled? && POSTFILTER_MODES.include?(mode)
  return false if protect_excluded_by_url?(rule_name)
  return false if protect_excluded_by_input?(gather_ia_results(context))
  return false if mode == :NO_ACTION || mode == :PERMIT

  true
end

#prefilter(context) ⇒ Object

Actions required for the rules that have to happen before the application has completed its processing of the request.

For most rules, these actions are performed within the analysis engine and communicated as an input analysis result. Those that require specific action need to provide that action.

Parameters:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 21

def prefilter context
  return unless prefilter?(context)

  ia_results = gather_ia_results(context)

  ia_results.each do |ia_result|
    result = build_attack_result(context)
    result = build_attack_without_match(context, ia_result, result)
    next unless result

    append_to_activity(context, result)
    record_triggered(context)
    raise(Contrast::SecurityException.new(self, block_message)) if blocked_violation?(result)
  end
end

#prefilter?(context) ⇒ Boolean

Prefilter check always called before infilter to check if the rule is infilter capable, not disabled or in other way excluded by url or input exclusions.

Parameters:

Returns:

  • (Boolean)


42
43
44
45
46
47
48
49
50
# File 'lib/contrast/agent/protect/rule/utils/filters.rb', line 42

def prefilter? context
  return false unless enabled?
  return false if protect_excluded_by_url?(rule_name)
  return false unless context
  return false unless (results = gather_ia_results(context)) && results.any?
  return false if protect_excluded_by_input?(results)

  true
end