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:

  • method_policy (Contrast::Agent::Patching::Policy::MethodPolicy)

    the policy that governs the patches to this method

  • preshift (Contrast::Agent::Assess::PreShift)

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

  • object (Object)

    the Object on which the method was invoked

  • ret (Object)

    the Return of the invoked method

  • args (Array<Object>)

    the Arguments with which the method was invoked

  • block (Block)

    the Block passed to the original method

Returns:

  • (Object, nil)

    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:



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:



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:



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:

  • (Bool)


108
109
110
# File 'lib/contrast/agent/assess/policy/propagation_method.rb', line 108

def context_available?
  !!Contrast::Agent::REQUEST_TRACKER.current
end