Class: Contrast::Agent::Patching::Policy::TriggerNode

Inherits:
PolicyNode show all
Defined in:
lib/contrast/agent/patching/policy/trigger_node.rb

Overview

This class functions to translate our policy.json into an actionable Ruby object, allowing for dynamic patching over hardcoded patching, specifically for those methods which result in the trigger of an attack (indicate points in the application where uncontrolled user input attempted to or did do damage).

Constant Summary collapse

JSON_NAME =
'name'
JSON_APPLICATOR =
'applicator'
JSON_APPLICATOR_METHOD =
'applicator_method'
JSON_REQUIRED_PROPS =
'required_properties'
JSON_OPTIONAL_PROPS =
'optional_properties'
JSON_ON_EXCEPTION =
'on_exception'
NODE =
'Trigger'

Instance Attribute Summary collapse

Attributes inherited from PolicyNode

#class_name, #instance_method, #method_name, #method_scope, #method_visibility, #properties

Instance Method Summary collapse

Methods inherited from PolicyNode

#feature, #id, #instance_method?

Methods included from Components::Interface

included

Constructor Details

#initialize(trigger_hash = {}, rule_hash = {}) ⇒ TriggerNode

Returns a new instance of TriggerNode.



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 26

def initialize trigger_hash = {}, rule_hash = {}
  super(trigger_hash)
  @rule_id = rule_hash[JSON_NAME]
  @on_exception = rule_hash[JSON_ON_EXCEPTION] # returns nil in most cases
  @required_properties = rule_hash[JSON_REQUIRED_PROPS]
  @optional_properties = rule_hash[JSON_OPTIONAL_PROPS]
  @applicator = class_from_string(rule_hash[JSON_APPLICATOR])
  # if a unique applicator method is defined for this method (rare case), preference getting that one.
  # otherwise, fall back to the normal applicator method for this rule
  @applicator_method = (trigger_hash[JSON_APPLICATOR_METHOD] || rule_hash[JSON_APPLICATOR_METHOD]).to_sym
end

Instance Attribute Details

#applicatorObject (readonly)

Returns the value of attribute applicator.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def applicator
  @applicator
end

#applicator_methodObject (readonly)

Returns the value of attribute applicator_method.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def applicator_method
  @applicator_method
end

#on_exceptionObject (readonly)

Returns the value of attribute on_exception.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def on_exception
  @on_exception
end

#optional_propertiesObject (readonly)

Returns the value of attribute optional_properties.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def optional_properties
  @optional_properties
end

#required_propertiesObject (readonly)

Returns the value of attribute required_properties.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def required_properties
  @required_properties
end

#rule_idObject (readonly)

Returns the value of attribute rule_id.



24
25
26
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 24

def rule_id
  @rule_id
end

Instance Method Details

#node_classObject



39
40
41
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 39

def node_class
  NODE
end

#validateObject

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 43

def validate
  super
  unless applicator.public_methods(false).any? { |method| method == applicator_method }
    raise(ArgumentError,
          "#{ id } did not have a proper applicator method: #{ applicator } does not respond to #{ applicator_method }. Unable to create.")
  end
  if (required_properties & optional_properties).any?
    raise(ArgumentError, "#{ rule_id } had overlapping elements between required and optional properties. Unable to create.")
  end
  if (properties.keys - (required_properties | optional_properties)).any?
    raise(ArgumentError, "#{ id } had an unexpected property. Unable to create.")
  end
  raise(ArgumentError, "#{ id } did not have a required property. Unable to create.") if (required_properties - properties.keys).any?

  validate_rule
end

#validate_ruleObject

Raises:

  • (ArgumentError)


60
61
62
63
64
65
66
# File 'lib/contrast/agent/patching/policy/trigger_node.rb', line 60

def validate_rule
  raise(ArgumentError, 'Unknown rule did not have a proper name. Unable to create.') unless rule_id
  raise(ArgumentError, "#{ id } did not have a proper applicator. Unable to create.") unless applicator
  raise(ArgumentError, "#{ id } did not have a proper applicator method. Unable to create.") unless applicator_method
  raise(ArgumentError, "#{ id } did not have a proper set of required properties. Unable to create.") unless required_properties
  raise(ArgumentError, "#{ id } did not have a proper set of optional properties. Unable to create.") unless optional_properties
end