Module: Contrast::Utils::Assess::TriggerMethodUtils

Extended by:
EventLimitUtils
Included in:
Agent::Assess::Policy::TriggerMethod
Defined in:
lib/contrast/utils/assess/trigger_method_utils.rb

Overview

This module will include all methods for some internal validations/appliers in the TriggerMethod module and some other module methods from the same place, so we can ease the main module

Instance Method Summary collapse

Methods included from EventLimitUtils

event_limit?, event_limit_for_rule?, increment_event_count

Methods included from Components::Logger::InstanceMethods

#cef_logger, #logger

Instance Method Details

#apply_dataflow_rule(trigger_node, source, object, ret, *args) ⇒ Object

This is our method that actually checks the taint on the object our trigger_node targets for our Dataflow based rules.

Parameters:

  • trigger_node (Contrast::Agent::Assess::Policy::TriggerNode)

    the node to direct applying this trigger event

  • source (Object)

    the source of the Trigger Event

  • 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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 110

def apply_dataflow_rule trigger_node, source, object, ret, *args
  return unless source && Contrast::Agent::Assess::Tracker.tracked?(source)

  if Contrast::Agent::Assess::Tracker.trackable?(source)
    return unless trigger_node.violated?(source)

    finding = build_finding(trigger_node, source, object, ret, *args)
    report_finding(finding) if finding
  elsif Contrast::Utils::DuckUtils.iterable_hash?(source)
    source.each_pair do |key, value|
      apply_dataflow_rule(trigger_node, key, object, ret, *args)
      apply_dataflow_rule(trigger_node, value, object, ret, *args)
    end
  elsif Contrast::Utils::DuckUtils.iterable_enumerable?(source)
    source.each do |value|
      apply_dataflow_rule(trigger_node, value, object, ret, *args)
    end
  end
end

#apply_regexp_rule(trigger_node, source, object, ret, *args) ⇒ Object

This is our method that actually checks the taint on the object our trigger_node targets for our Regexp based rules.

Parameters:

  • trigger_node (Contrast::Agent::Assess::Policy::TriggerNode)

    the node to direct applying this trigger event

  • source (Object)

    the source of the Trigger Event

  • 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



92
93
94
95
96
97
98
99
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 92

def apply_regexp_rule trigger_node, source, object, ret, *args
  return unless source.is_a?(String)
  return if trigger_node.good_value && source.match?(trigger_node.good_value)
  return if trigger_node.bad_value && source !~ trigger_node.bad_value

  finding = build_finding(trigger_node, source, object, ret, *args)
  Contrast::Agent::Assess::Policy::TriggerMethod.report_finding(finding) if finding
end

#apply_trigger(trigger_node, source, object, ret, *args) ⇒ Object

APPLIERS =====

This is our method that actually checks the taint on the object our trigger_node targets.

Parameters:

  • trigger_node (Contrast::Agent::Assess::Policy::TriggerNode)

    the node to direct applying this trigger event

  • source (Object)

    the source of the Trigger Event

  • 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



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 64

def apply_trigger trigger_node, source, object, ret, *args
  return unless trigger_node
  return if trigger_node.rule_disabled?
  return if trigger_node.dataflow? && source.nil?

  if trigger_node.regexp_rule?
    apply_regexp_rule(trigger_node, source, object, ret, *args)
  elsif trigger_node.custom_trigger?
    trigger_node.apply_custom_trigger(trigger_node, source, object, ret, *args)
  elsif trigger_node.dataflow?
    apply_dataflow_rule(trigger_node, source, object, ret, *args)
  else # trigger rule - just calling the method is dangerous
    finding = build_finding(trigger_node, source, object, ret, *args)
    Contrast::Agent::Assess::Policy::TriggerMethod.report_finding(finding) if finding
  end
rescue StandardError => e
  logger.warn('Unable to apply trigger', e, node_id: trigger_node.id)
end

#find_event_request(event) ⇒ Contrast::Agent::Request?

Finds the first request along the left most tree of parent events



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 41

def find_event_request event
  return event.request if event&.source_type

  idx = 0
  while idx <= event.parent_events.length
    found = find_event_request(event.parent_events[idx])
    return found if found

    idx += 1
  end

  event.request
end

#find_request(source) ⇒ Contrast::Agent::Request?

Find the request for this finding. This assumes, for now, that if there is an active request, then that is the request to report. Otherwise, we’ll use the first request found in the events of the source_object if the non request tracking flag is set.

Parameters:

  • source (Object, nil)

    some Object used as the source of a trigger event

Returns:



29
30
31
32
33
34
35
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 29

def find_request source
  return Contrast::Agent::REQUEST_TRACKER.current.request if Contrast::Agent::REQUEST_TRACKER.current
  return unless ::Contrast::ASSESS.non_request_tracking?
  return unless (properties = Contrast::Agent::Assess::Tracker.properties(source))

  find_event_request(properties.event)
end

#reportable?(env) ⇒ Boolean

A request is reportable if it is not from ActionController::Live

Parameters:

  • env (Hash)

    the env of the Request

Returns:

  • (Boolean)


17
18
19
20
21
# File 'lib/contrast/utils/assess/trigger_method_utils.rb', line 17

def reportable? env
  !(defined?(ActionController::Live) &&
    env &&
    env['action_controller.instance'].cs__class.included_modules.include?(ActionController::Live))
end