Class: Contrast::Agent::Assess::Policy::PropagationNode
- Inherits:
-
PolicyNode
- Object
- Patching::Policy::PolicyNode
- PolicyNode
- Contrast::Agent::Assess::Policy::PropagationNode
- Includes:
- Components::Logger::InstanceMethods
- Defined in:
- lib/contrast/agent/assess/policy/propagation_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 transformation of untrusted data (indicate points in the application where user controlled input is modified).
Constant Summary collapse
- JSON_ACTION =
'action'
- JSON_UNTAGS =
'untags'
- JSON_PATCH_CLASS =
'patch_class'
- JSON_PATCH_METHOD =
'patch_method'
- TAGGER =
'Tagger'
- PROPAGATOR =
'Propagator'
Constants inherited from PolicyNode
Contrast::Agent::Assess::Policy::PolicyNode::ALL_TYPE, Contrast::Agent::Assess::Policy::PolicyNode::JSON_DATAFLOW, Contrast::Agent::Assess::Policy::PolicyNode::JSON_SOURCE, Contrast::Agent::Assess::Policy::PolicyNode::JSON_TAGS, Contrast::Agent::Assess::Policy::PolicyNode::JSON_TARGET, Contrast::Agent::Assess::Policy::PolicyNode::ORIGINAL_OBJECT_METHODS, Contrast::Agent::Assess::Policy::PolicyNode::RESPONSE_SOURCES, Contrast::Agent::Assess::Policy::PolicyNode::TO_MARKER, Contrast::Agent::Assess::Policy::PolicyNode::TO_S
Constants inherited from Patching::Policy::PolicyNode
Patching::Policy::PolicyNode::JSON_CLASS_NAME, Patching::Policy::PolicyNode::JSON_INSTANCE_METHOD, Patching::Policy::PolicyNode::JSON_METHOD_NAME, Patching::Policy::PolicyNode::JSON_METHOD_SCOPE, Patching::Policy::PolicyNode::JSON_METHOD_VISIBILITY, Patching::Policy::PolicyNode::JSON_PROPERTIES
Instance Attribute Summary collapse
-
#action ⇒ Object
readonly
-
‘CUSTOM’ - the propagation node is a custom propagation node - ‘DB_WRITE’ - the propagation node is a database write propagation node - ‘APPEND’ - the propagation node is an append propagation node - ‘CENTER’ - the propagation node is a center propagation node - ‘INSERT’ - the propagation node is an insert propagation node - ‘KEEP’ - the propagation node is a keep propagation node - ‘NEXT’ - the propagation node is a next propagation node - ‘BUFFER’ - the propagation node is a buffer propagation node - ‘NOOP’ - the propagation node is a noop propagation node - ‘PREPEND’ - the propagation node is a prepend propagation node - ‘REPLACE’ - the propagation node is a replace propagation node - ‘REMOVE’ - the propagation node is a remove propagation node - ‘REVERSE’ - the propagation node is a reverse propagation node - ‘RESPONSE’ - the propagation node is a response propagation node - ‘SPLAT’ - the propagation node is a splat propagation node - ‘SPLIT’ - the propagation node is a split propagation node.
-
-
#patch_class ⇒ Object
for this propagation node.
-
#patch_method ⇒ Object
readonly
contains the method to be called for this propagation node.
-
#untags ⇒ Object
readonly
target of this propagation node.
Attributes inherited from PolicyNode
#source_string, #sources, #tags, #target_string, #targets, #type
Attributes inherited from Patching::Policy::PolicyNode
#class_name, #instance_method, #method_name, #method_scope, #method_visibility, #properties
Instance Method Summary collapse
-
#initialize(propagation_hash = {}) ⇒ PropagationNode
constructor
Most things here carry over from PolicyNode.
- #needs_args? ⇒ Boolean
-
#needs_object? ⇒ Boolean
Propagation node.
-
#node_class ⇒ String
Class name.
-
#node_type ⇒ Symbol
Unlike the other agents, we don’t have separate tag & propagation events.
-
#tagger? ⇒ Boolean
This is a tagger if it has a tag or an untag.
-
#validate ⇒ Object
Standard validation + TS trace version two rules: Must have source, target, and action.
-
#validate_untags ⇒ Object
@raise raises if any of the tags is invalid.
Methods included from Components::Logger::InstanceMethods
Methods inherited from PolicyNode
#add_property, #assign_on_bang_check, #build_action, #feature, #get_property, #response_source_node?, #use_original_object?, #use_original_on_bang_method?, #use_response_as_source?, #validate_tags
Methods inherited from Patching::Policy::PolicyNode
#feature, #id, #instance_method?
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
Constructor Details
#initialize(propagation_hash = {}) ⇒ PropagationNode
Most things here carry over from PolicyNode. A couple things are new / have new rules
Source - from where the tainted data flows, cannot be nil Target - to where the tainted data flows, cannot be nil Action - how the tainted data flows from source to target, should not be nil Tags - array of tags to apply to the target, can be nil if no tags are added Untags - array of tags to remove from the target, can be nil if not tags are removed id, class_name, instance_method, method_name, source, target, action, tags = nil, untags = nil
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 69 def initialize propagation_hash = {} super(propagation_hash) @action = propagation_hash[JSON_ACTION] @untags = Set.new(propagation_hash[JSON_UNTAGS]) @patch_class = propagation_hash[JSON_PATCH_CLASS] @patch_method = propagation_hash[JSON_PATCH_METHOD] @patch_method = @patch_method.to_sym if @patch_method validate rescue ArgumentError => e logger.error('Propagation Node Initialization failed with: ', e) nil end |
Instance Attribute Details
#action ⇒ Object (readonly)
-
‘CUSTOM’ - the propagation node is a custom propagation node
-
‘DB_WRITE’ - the propagation node is a database write propagation
node
-
‘APPEND’ - the propagation node is an append propagation node
-
‘CENTER’ - the propagation node is a center propagation node
-
‘INSERT’ - the propagation node is an insert propagation node
-
‘KEEP’ - the propagation node is a keep propagation node
-
‘NEXT’ - the propagation node is a next propagation node
-
‘BUFFER’ - the propagation node is a buffer propagation node
-
‘NOOP’ - the propagation node is a noop propagation node
-
‘PREPEND’ - the propagation node is a prepend propagation node
-
‘REPLACE’ - the propagation node is a replace propagation node
-
‘REMOVE’ - the propagation node is a remove propagation node
-
‘REVERSE’ - the propagation node is a reverse propagation node
-
‘RESPONSE’ - the propagation node is a response propagation node
-
‘SPLAT’ - the propagation node is a splat propagation node
-
‘SPLIT’ - the propagation node is a split propagation node
44 45 46 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 44 def action @action end |
#patch_class ⇒ Object
for this propagation node.
53 54 55 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 53 def patch_class @patch_class end |
#patch_method ⇒ Object (readonly)
contains the method to be called for this propagation node.
50 51 52 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 50 def patch_method @patch_method end |
#untags ⇒ Object (readonly)
target of this propagation node.
47 48 49 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 47 def @untags end |
Instance Method Details
#needs_args? ⇒ Boolean
150 151 152 153 154 155 156 157 158 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 150 def needs_args? if @_needs_args.nil? @_needs_args = action == Contrast::Utils::Assess::PropagationMethodUtils::CUSTOM_ACTION || action == Contrast::Utils::Assess::PropagationMethodUtils::DB_WRITE_ACTION || sources.any? { |source| source.is_a?(Integer) || source.is_a?(Symbol) } || targets.any? { |target| target.is_a?(Integer) || target.is_a?(Symbol) } end @_needs_args end |
#needs_object? ⇒ Boolean
Returns propagation node.
139 140 141 142 143 144 145 146 147 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 139 def needs_object? if @_needs_object.nil? @_needs_object = action == Contrast::Utils::Assess::PropagationMethodUtils::CUSTOM_ACTION || action == Contrast::Utils::Assess::PropagationMethodUtils::DB_WRITE_ACTION || sources.any?(Contrast::Utils::ObjectShare::OBJECT_KEY) || targets.any?(Contrast::Utils::ObjectShare::OBJECT_KEY) end @_needs_object end |
#node_class ⇒ String
Returns class name.
83 84 85 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 83 def node_class @_node_class ||= tagger? ? TAGGER : PROPAGATOR end |
#node_type ⇒ Symbol
Unlike the other agents, we don’t have separate tag & propagation events. To make TS happy, we need to have different types though. Pretty straight forward: if there’s a tag, this is a tagger
92 93 94 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 92 def node_type tagger? ? :TYPE_TAG : :TYPE_PROPAGATION end |
#tagger? ⇒ Boolean
This is a tagger if it has a tag or an untag. It indicates this method is more than just a transformation, it is an interesting security event that has a meaningful change.
166 167 168 169 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 166 def tagger? @_tagger = &.any? || &.any? if @_tagger.nil? @_tagger end |
#validate ⇒ Object
Standard validation + TS trace version two rules: Must have source, target, and action
@raise raises if any of the required propagation node field is not valid, or is missing
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 100 def validate super raise(ArgumentError, "Propagator #{ id } did not have a proper action. Unable to create.") unless action if @action == 'CUSTOM' unless patch_class raise(ArgumentError, "Propagator #{ id } did not have a proper patch_class. Unable to create.") end unless patch_method.is_a?(Symbol) raise(ArgumentError, "Propagator #{ id } did not have a proper patch_method. Unable to create.") end else unless targets&.any? raise(ArgumentError, "Propagator #{ id } did not have a proper target. Unable to create.") end unless sources&.any? raise(ArgumentError, "Propagator #{ id } did not have a proper source. Unable to create.") end end end |
#validate_untags ⇒ Object
@raise raises if any of the tags is invalid
123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/contrast/agent/assess/policy/propagation_node.rb', line 123 def return unless .each do |tag| unless Contrast::Agent::Reporting::FindingEventTaintRangeTags::VALID_TAGS.include?(tag) raise(ArgumentError, "#{ node_type } #{ id } did not have a valid untag. #{ tag } is not a known value.") end if &.include?(tag) raise(ArgumentError, "#{ node_type } #{ id } had the same tag and untag, #{ tag }.") end end end |