lib/contrast/agent/assess/policy/propagator/split.rb in contrast-agent-4.14.1 vs lib/contrast/agent/assess/policy/propagator/split.rb in contrast-agent-5.0.0

- old
+ new

@@ -1,13 +1,15 @@ -# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. +# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/assess/policy/preshift' require 'contrast/components/agent' require 'contrast/components/logger' require 'contrast/components/scope' require 'contrast/utils/thread_tracker' +require 'contrast/utils/assess/split_utils' +require 'contrast/agent/assess/events/event_data' module Contrast module Agent module Assess module Policy @@ -15,10 +17,11 @@ # This class is specifically for String#split & String#grapheme_clusters propagation # it propagates tag ranges from a string to elements within an untracked array class Split < Contrast::Agent::Assess::Policy::Propagator::Base extend Contrast::Components::Scope::InstanceMethods extend Contrast::Components::Logger::InstanceMethods + extend Contrast::Utils::Assess::SplitUtils SPLIT_TRACKER = Contrast::Utils::ThreadTracker.new class << self # Propagate taint from a source as it is split into composite sections. @@ -36,28 +39,11 @@ logger.trace('Propagation detected', node_id: propagation_node.id, target_id: target.__id__) source = find_source(propagation_node.sources[0], preshift) return unless (source_properties = Contrast::Agent::Assess::Tracker.properties(source)) - separator_length = find_separator_length(propagation_node, preshift) - - current_index = 0 - target.each do |target_elem| - next unless (elem_properties = Contrast::Agent::Assess::Tracker.properties!(target_elem)) - - # Get tags for element from source by element range. - range = current_index...(current_index + target_elem.length) - tags = source_properties.tags_at_range(range) - - # Set element properties accordingly. - elem_properties.clear_tags - tags.each_pair { |key, value| elem_properties.set_tags(key, value) } - elem_properties.build_event(propagation_node, target_elem, preshift.object, target, preshift.args, 0) - elem_properties.add_properties(propagation_node.properties) - - current_index = range.end + separator_length - end + update_element_properties propagation_node, target, preshift, source_properties nil end # Context for block split execution. # @@ -158,15 +144,31 @@ end # Save the target to the ThreadLocal; not useless. split_value[split_scope_depth] = target # rubocop:disable Lint/UselessSetterCall end - # Quick hook to the String#split propagation node in our Assess policy - # - # @return [Contrast::Agent::Assess::Policy::PropagationNode] String#split node - def split_node - @_split_node ||= Contrast::Agent::Assess::Policy::Policy.instance.propagators.find do |node| - node.class_name == 'String' && node.method_name == :split && node.instance_method? + def update_element_properties propagation_node, target, preshift, source_properties + separator_length = find_separator_length(propagation_node, preshift) + current_index = 0 + target.each do |target_elem| + next unless (elem_properties = Contrast::Agent::Assess::Tracker.properties!(target_elem)) + + # Get tags for element from source by element range. + range = current_index...(current_index + target_elem.length) + tags = source_properties.tags_at_range(range) + + # Set element properties accordingly. + elem_properties.clear_tags + tags.each_pair { |key, value| elem_properties.set_tags(key, value) } + event_data = Contrast::Agent::Assess::Events::EventData.new(propagation_node, + target_elem, + preshift.object, + target, + preshift.args) + elem_properties.build_event(event_data, 0) + elem_properties.add_properties(propagation_node.properties) + + current_index = range.end + separator_length end end end end end