Module: Contrast::Agent::Assess::Policy::PropagationMethod

Extended by:
Components::Logger::InstanceMethods, Utils::Assess::EventLimitUtils, Utils::Assess::PropagationMethodUtils
Included in:
Patching::Policy::Patch
Defined in:
lib/contrast/agent/assess/policy/propagation_method.rb

Overview

This class is responsible for the continuation of traces. A Propagator is any method that transforms an untrusted value. In general, these methods work on the String class or a holder of Strings. rubocop:disable Metrics/ModuleLength

Constant Summary

Constants included from Utils::Assess::PropagationMethodUtils

Utils::Assess::PropagationMethodUtils::APPEND_ACTION, Utils::Assess::PropagationMethodUtils::BUFFER_ACTION, Utils::Assess::PropagationMethodUtils::CENTER_ACTION, Utils::Assess::PropagationMethodUtils::CUSTOM_ACTION, Utils::Assess::PropagationMethodUtils::DB_WRITE_ACTION, Utils::Assess::PropagationMethodUtils::INSERT_ACTION, Utils::Assess::PropagationMethodUtils::KEEP_ACTION, Utils::Assess::PropagationMethodUtils::NEXT_ACTION, Utils::Assess::PropagationMethodUtils::NOOP_ACTION, Utils::Assess::PropagationMethodUtils::PREPEND_ACTION, Utils::Assess::PropagationMethodUtils::PROPAGATION_ACTIONS, Utils::Assess::PropagationMethodUtils::REMOVE_ACTION, Utils::Assess::PropagationMethodUtils::REPLACE_ACTION, Utils::Assess::PropagationMethodUtils::RESPONSE_ACTION, Utils::Assess::PropagationMethodUtils::REVERSE_ACTION, Utils::Assess::PropagationMethodUtils::SPLAT_ACTION, Utils::Assess::PropagationMethodUtils::SPLIT_ACTION, Utils::Assess::PropagationMethodUtils::ZERO_LENGTH_ACTIONS

Class Method Summary collapse

Methods included from Components::Logger::InstanceMethods

cef_logger, logger

Methods included from Utils::Assess::PropagationMethodUtils

appropriate_source?, appropriate_target?, can_propagate?, determine_target, valid_length?, valid_target?

Methods included from Utils::Assess::EventLimitUtils

event_limit?, event_limit_for_rule?, increment_event_count

Class Method Details

.apply_propagation(method_policy, preshift, object, ret, args, block) ⇒ Object?

Returns the tracked Return or nil if no changes were made; will replace the return of the original function if not nil.

Parameters:

  • the policy that governs the patches to this method

  • The capture of the state of the code just prior to the invocation of the patched method.

  • the Object on which the method was invoked

  • the Return of the invoked method

  • the Arguments with which the method was invoked

  • the Block passed to the original method

Returns:

  • the tracked Return or nil if no changes were made; will replace the return of the original function if not nil



40
41
42
43
44
45
46
47
48
# File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 40

def apply_propagation method_policy, preshift, object, ret, args, block
  return unless (propagation_node = method_policy.propagation_node)
  return unless propagation_node.use_original_object? || preshift
  return if event_limit?(method_policy)

  target = determine_target(propagation_node, ret, object, args)
  propagation_data = Contrast::Agent::Assess::Events::EventData.new(nil, nil, object, ret, args)
  PropagationMethod.apply_propagator(propagation_node, preshift, target, propagation_data, block)
end

.apply_propagator(propagation_node, preshift, target, propagation_data, block) ⇒ Object

I lied above. We had to figure out what the target of the propagation was. Now that we know, we'll actually do things to it. Note that the return of this method will replace the original return of the patched function unless it is nil, so be sure you're returning what you intend.

Parameters:

  • the node that governs this propagation event.

  • The capture of the state of the code just prior to the invocation of the patched method.

  • the Target to which to propagate.

  • this will hold the object [Object] the Object on which the method was invoked ret [Object] the Return of the invoked method args [Array] the Arguments with which the method was invoked

  • the Block passed to the original method

  • 
    
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    # File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 64
    
    def apply_propagator propagation_node, preshift, target, propagation_data, block
      return unless propagation_possible?(propagation_node, target)
    
      if propagation_node.action == DB_WRITE_ACTION
        Contrast::Agent::Assess::Policy::Propagator::DatabaseWrite.propagate(propagation_node,
                                                                             preshift,
                                                                             propagation_data.ret)
      elsif propagation_node.action == CUSTOM_ACTION
        Contrast::Agent::Assess::Policy::Propagator::Custom.propagate(propagation_node,
                                                                      preshift,
                                                                      propagation_data.ret,
                                                                      block)
      elsif propagation_node.action == SPLIT_ACTION
        Contrast::Agent::Assess::Policy::Propagator::Split.propagate(propagation_node, preshift, target)
      elsif Contrast::Utils::DuckUtils.iterable_hash?(target)
        handle_hash_propagation(propagation_node, preshift, target, propagation_data, block)
      elsif Contrast::Utils::DuckUtils.iterable_enumerable?(target)
        handle_enumerable_propagation(propagation_node, preshift, target, propagation_data, block)
      else
        handle_cs_properties_propagation(propagation_node, preshift, target, propagation_data, block)
      end
    rescue StandardError => e
      logger.warn('Unable to apply propagation', e, node_id: propagation_node.id)
      nil
    end

    .apply_tags(propagation_node, target) ⇒ Object

    If this patcher has tags, apply them to the entire target

    Parameters:

    • the node that governs this propagation event.

    • the Target to which to propagate.

    
    
    95
    96
    97
    98
    99
    100
    101
    102
    103
    # File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 95
    
    def apply_tags propagation_node, target
      return unless (propagation_tags = propagation_node.tags)
      return unless (properties = Contrast::Agent::Assess::Tracker.properties(target))
    
      length = Contrast::Utils::StringUtils.ret_length(target)
      propagation_tags.each do |tag|
        properties.add_tag(tag, 0...length)
      end
    end

    .apply_untags(propagation_node, target) ⇒ Object

    If this patcher has tags, remove them from the entire target

    Parameters:

    • the node that governs this propagation event.

    • the Target to which to propagate.

    
    
    117
    118
    119
    120
    121
    122
    123
    124
    # File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 117
    
    def apply_untags propagation_node, target
      return unless propagation_node.untags
      return unless (properties = Contrast::Agent::Assess::Tracker.properties(target))
    
      propagation_node.untags.each do |tag|
        properties.delete_tags(tag)
      end
    end

    .context_available?Bool

    Checks to see if the given target is valid for propagation.

    Returns:

    
    
    108
    109
    110
    # File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 108
    
    def context_available?
      !!Contrast::Agent::REQUEST_TRACKER.current
    end