Class: Contrast::Agent::Assess::Policy::PolicyNode
- Inherits:
-
Patching::Policy::PolicyNode
- Object
- Patching::Policy::PolicyNode
- Contrast::Agent::Assess::Policy::PolicyNode
- Defined in:
- lib/contrast/agent/assess/policy/policy_node.rb
Overview
This class functions to translate our policy.json into an actionable Ruby object, allowing for dynamic patching over hardcoded patching.
Direct Known Subclasses
Constant Summary collapse
- JSON_TAGS =
'tags'
- JSON_DATAFLOW =
'dataflow'
- JSON_SOURCE =
The keys used to read from policy.json to create the individual policy nodes. These are common across node types
'source'
- ALL_TYPE =
'A'
- JSON_TARGET =
'target'
- TO_MARKER =
'2'
- ORIGINAL_OBJECT_METHODS =
Here are all methods that can use original objects without mutation the source. For methods with REMOVE action, their (!) bang alternative is not listed, since this methods tends to mutate the original (shortens it’s length, remove special symbols..) and causes mismatch in tags range representation of the target. In short preshift is needed.
%i[ capitalize capitalize! chomp to_s to_str downcase downcase! lstrip strip upcase! upcase ].cs__freeze
- TO_S =
%w[to_s to_str].cs__freeze
- RESPONSE_SOURCES =
Here are all Responses that will be tracked as sources, or methods they use, like body.
%w[Net::HTTPResponse Rack::Response Sinatra::Response].cs__freeze
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
-
#source_string ⇒ Object
readonly
Returns the value of attribute source_string.
-
#sources ⇒ Object
readonly
Returns the value of attribute sources.
-
#tags ⇒ Object
Returns the value of attribute tags.
-
#target_string ⇒ Object
Returns the value of attribute target_string.
-
#targets ⇒ Object
readonly
Returns the value of attribute targets.
-
#type ⇒ Object
Returns the value of attribute type.
Attributes inherited from Patching::Policy::PolicyNode
#class_name, #instance_method, #method_name, #method_scope, #method_visibility, #properties
Instance Method Summary collapse
-
#add_property(name, value) ⇒ Object
Sometimes we need to tie information to an event.
-
#assign_on_bang_check(policy_hash) ⇒ Object
If we have KEEP action on String, and the method is to_s, that method would return self: String#to_s => self or string.
-
#build_action ⇒ Object
Convert our action, built from our source and target, into the TS appropriate action.
- #feature ⇒ Object
- #get_property(name) ⇒ Object
-
#initialize(policy_hash = {}) ⇒ PolicyNode
constructor
A new instance of PolicyNode.
- #node_class ⇒ Object
- #node_type ⇒ Object
-
#response_source_node? ⇒ Boolean
This method will check if the policy node is for response method.
-
#use_original_object? ⇒ Boolean
This method will check if a method is fit to use it’s original object and that the method is without bang - it does not change the source, but rather creates a copy of it.
-
#use_original_on_bang_method? ⇒ Boolean
This method will check if a method is fit to use it’s original object and that the target return is the same as object - a bang method modifying the source.
-
#use_response_as_source? ⇒ Boolean
This method will check if policy is fit to use response as source.
-
#validate ⇒ Object
Don’t let nodes be created that will be missing things we need later on.
-
#validate_tags ⇒ Object
TeamServer is picky.
Methods included from Components::Logger::InstanceMethods
Methods inherited from Patching::Policy::PolicyNode
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(policy_hash = {}) ⇒ PolicyNode
Returns a new instance of PolicyNode.
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 55 def initialize policy_hash = {} super(policy_hash) @source_string = policy_hash[JSON_SOURCE] @target_string = policy_hash[JSON_TARGET] @tags = Set.new(policy_hash[JSON_TAGS]) @sources = convert_policy_markers(source_string) @targets = convert_policy_markers(target_string) @_use_original_object = ORIGINAL_OBJECT_METHODS.include?(@method_name) @_use_original_on_bang_method = assign_on_bang_check(policy_hash) @_use_response_as_source = RESPONSE_SOURCES.include?(@class_name) end |
Instance Attribute Details
#source_string ⇒ Object (readonly)
Returns the value of attribute source_string.
30 31 32 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 30 def source_string @source_string end |
#sources ⇒ Object (readonly)
Returns the value of attribute sources.
30 31 32 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 30 def sources @sources end |
#tags ⇒ Object
Returns the value of attribute tags.
29 30 31 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 29 def @tags end |
#target_string ⇒ Object
Returns the value of attribute target_string.
30 31 32 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 30 def target_string @target_string end |
#targets ⇒ Object (readonly)
Returns the value of attribute targets.
30 31 32 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 30 def targets @targets end |
#type ⇒ Object
Returns the value of attribute type.
29 30 31 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 29 def type @type end |
Instance Method Details
#add_property(name, value) ⇒ Object
Sometimes we need to tie information to an event. We’ll add a properties section to the patch node, which can pass them along to the pre-dtm event
99 100 101 102 103 104 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 99 def add_property name, value return unless name && value @properties ||= {} @properties[name] = value end |
#assign_on_bang_check(policy_hash) ⇒ Object
If we have KEEP action on String, and the method is to_s, that method would return self: String#to_s => self or string. This method is included here to cover the situations such as String.to_s.html_safe, where normally the dynamic sources properties get lost. To solve this we will simply return the original object here.
71 72 73 74 75 76 77 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 71 def assign_on_bang_check policy_hash return true if @_use_original_object && TO_S.include?(policy_hash[JSON_METHOD_NAME]) @_use_original_object && # Check if method name ends with a (!) bang unless is the to_s method: policy_hash[JSON_METHOD_NAME].end_with?(Contrast::Utils::ObjectShare::BANG) end |
#build_action ⇒ Object
Convert our action, built from our source and target, into the TS appropriate action. That’s a single source to single target marker (A,O,P,R)
Creation (source nodes) don’t have sources (they are the source) Trigger (trigger nodes) don’t have targets (they are the target) Everything else (propagation nodes) are Source2Target
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 146 def build_action @event_action ||= case node_class when Contrast::Agent::Assess::Policy::SourceNode::SOURCE :CREATION when Contrast::Agent::Assess::Policy::TriggerNode::TRIGGER :TRIGGER else if source_string.nil? :CREATION elsif target_string.nil? :TRIGGER else # TeamServer can't handle the multi-source or multi-target values. Give it some help # by changing them to 'A' source = all_type?(source_string) ? ALL_TYPE : source_string target = all_type?(target_string) ? ALL_TYPE : target_string str = source[0] + TO_MARKER + target[0] str.to_sym end end @event_action end |
#feature ⇒ Object
79 80 81 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 79 def feature 'Assess' end |
#get_property(name) ⇒ Object
106 107 108 109 110 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 106 def get_property name return unless @properties @properties[name] end |
#node_class ⇒ Object
83 84 85 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 83 def node_class 'Node' end |
#node_type ⇒ Object
87 88 89 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 87 def node_type :TYPE_METHOD end |
#response_source_node? ⇒ Boolean
This method will check if the policy node is for response method.
198 199 200 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 198 def response_source_node? @_use_response_as_source end |
#use_original_object? ⇒ Boolean
This method will check if a method is fit to use it’s original object and that the method is without bang - it does not change the source, but rather creates a copy of it.
175 176 177 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 175 def use_original_object? @_use_original_object && Contrast::ASSESS.track_original_object? end |
#use_original_on_bang_method? ⇒ Boolean
This method will check if a method is fit to use it’s original object and that the target return is the same as object - a bang method modifying the source.
184 185 186 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 184 def use_original_on_bang_method? @_use_original_on_bang_method && Contrast::ASSESS.track_original_object? end |
#use_response_as_source? ⇒ Boolean
This method will check if policy is fit to use response as source.
191 192 193 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 191 def use_response_as_source? Contrast::ASSESS.track_response_as_source? end |
#validate ⇒ Object
Don’t let nodes be created that will be missing things we need later on. Really, if they don’t have these things, they couldn’t have done their jobs anyway.
115 116 117 118 119 120 121 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 115 def validate super rescue ArgumentError => e logger.debug('Validation of policy node failed with: ', e) nil end |
#validate_tags ⇒ Object
TeamServer is picky. The tags here match to ENUMs there. If there isn’t a matching ENUM in TS land, the database gets got. We really don’t want to get them, so we’re going to prevent the node from being made. @raise raises if any of the tags is invalid
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/contrast/agent/assess/policy/policy_node.rb', line 128 def return unless .each do |tag| next if Contrast::Agent::Reporting::FindingEventTaintRangeTags::VALID_TAGS.include?(tag) || Contrast::Agent::Reporting::FindingEventTaintRangeTags::VALID_SOURCE_TAGS.include?(tag) raise(ArgumentError, "#{ node_class } #{ id } had an invalid tag. #{ tag } is not a known value.") end end |