Class: Contrast::Agent::Protect::Rule::Base Abstract

Inherits:
Object
  • Object
show all
Includes:
Builders, Filters, Components::Logger::InstanceMethods, Components::Scope::InstanceMethods
Defined in:
lib/contrast/agent/protect/rule/base.rb

Overview

This class is abstract.

Subclass and override Filters#prefilter, Filters#infilter, #find_attacker, Filters#postfilter to implement

This is a basic rule for Protect. It’s the abstract class which all other protect rules extend in order to function.

Constant Summary collapse

RULE_NAME =
'base-rule'
BLOCKING_MODES =
Set.new(%i[BLOCK BLOCK_AT_PERIMETER]).cs__freeze
STACK_COLLECTION_RESULTS =
Set.new([
  Contrast::Agent::Reporting::ResponseType::BLOCKED,
  Contrast::Agent::Reporting::ResponseType::MONITORED
]).cs__freeze
SUSPICIOUS_REPORTING_RULES =
%w[
  unsafe-file-upload
  reflected-xss
  cmd-injection-semantic-dangerous-paths
  cmd-injection-semantic-chained-commands
  path-traversal-semantic-file-security-bypass
  sql-injection-semantic-dangerous-functions
].cs__freeze

Constants included from Filters

Filters::POSTFILTER_MODES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Filters

#infilter, #infilter?, #postfilter, #postfilter?, #prefilter, #prefilter?

Methods included from Builders

#build_attack_result, #build_attack_with_match, #build_attack_without_match, #build_base_sample, #build_sample, #build_violation

Methods included from Components::Scope::InstanceMethods

#contrast_enter_method_scopes!, #contrast_exit_method_scopes!, #with_app_scope, #with_contrast_scope, #with_deserialization_scope, #with_split_scope

Methods included from Components::Logger::InstanceMethods

#cef_logger, #logger

Constructor Details

#initializeBase

Initializes new rule and sets it mode from settings



47
48
49
# File 'lib/contrast/agent/protect/rule/base.rb', line 47

def initialize
  @mode = mode_from_settings
end

Instance Attribute Details

#modeSymbol (readonly)

Returns:

  • (Symbol)


42
43
44
# File 'lib/contrast/agent/protect/rule/base.rb', line 42

def mode
  @mode
end

Instance Method Details

#append_to_activity(context, result) ⇒ Object

Attach the given result to the current request’s context to report it to TeamServer

Parameters:



139
140
141
# File 'lib/contrast/agent/protect/rule/base.rb', line 139

def append_to_activity context, result
  context.activity.attach_defend(result) if result
end

#block_messageString

Message to display when the rule is triggered.

Returns:



54
55
56
# File 'lib/contrast/agent/protect/rule/base.rb', line 54

def block_message
  "Contrast Security Protect #{ rule_name } Triggered. Response blocked."
end

#cef_logging(result, attack = :ineffective_attack, value: nil, input_type: nil, context: nil) ⇒ Object

With this we log to CEF

Parameters:



149
150
151
152
153
154
155
# File 'lib/contrast/agent/protect/rule/base.rb', line 149

def cef_logging result, attack = :ineffective_attack, value: nil, input_type: nil, context: nil
  sample = result.samples[0]
  outcome = result.response.to_s
  input_type = sample&.user_input&.input_type&.to_s || input_type
  input_value = sample&.user_input&.value || value
  cef_logger.send(attack, result.rule_id, outcome, input_type, input_value, context)
end

#classificationModule

The classification module used for each specific rule to classify input data and score it. Extend for each rule.

Returns:



86
# File 'lib/contrast/agent/protect/rule/base.rb', line 86

def classification; end

#classify(input_type, value, input_analysis) ⇒ Object

Generic method forwarder, shorthand for classification: Input Classification stage is done to determine if an user input is DEFINITEATTACK or to be ignored.

Parameters:



97
98
99
# File 'lib/contrast/agent/protect/rule/base.rb', line 97

def classify input_type, value, input_analysis
  classification.classify(rule_name, input_type, value, input_analysis)
end

#enabled?Boolean

Check if rule is enabled.

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
114
# File 'lib/contrast/agent/protect/rule/base.rb', line 104

def enabled?
  # 1. it is not enabled because protect is not enabled
  return false unless ::Contrast::AGENT.enabled?
  return false unless ::Contrast::PROTECT.enabled?

  # 2. it is not enabled because it is in the list of disabled protect rules
  return false if ::Contrast::PROTECT.rule_config&.disabled_rules&.include?(rule_name)

  # 3. it is enabled so long as its mode is not NO_ACTION
  @mode != :NO_ACTION
end

#excluded?(exclusions) ⇒ Boolean

Check if the rule is excluded by checking inside array of exclusions

Parameters:

Returns:

  • (Boolean)


119
120
121
122
123
# File 'lib/contrast/agent/protect/rule/base.rb', line 119

def excluded? exclusions
  Array(exclusions).any? do |ex|
    ex.protection_rule?(rule_name)
  end
end

#rule_nameString

Should return the name as it is known to Teamserver; defaults to class

Returns:



61
62
63
# File 'lib/contrast/agent/protect/rule/base.rb', line 61

def rule_name
  RULE_NAME
end

#stream_safe?Boolean

Return false for rules that modify or inspect the response body during postfilter

Returns:

  • (Boolean)

    if the rule can safely be evaluated in streaming requests



129
130
131
# File 'lib/contrast/agent/protect/rule/base.rb', line 129

def stream_safe?
  true
end

#sub_rulesArray

Should return list of all sub_rules. Extend for each main rule any sub-rules.

Returns:

  • (Array)


78
79
80
# File 'lib/contrast/agent/protect/rule/base.rb', line 78

def sub_rules
  Contrast::Utils::ObjectShare::EMPTY_ARRAY
end

#updateObject

Update state form Settings or Configuration.



66
67
68
# File 'lib/contrast/agent/protect/rule/base.rb', line 66

def update
  @mode = mode_from_settings
end