# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/assess/policy/propagator/select' require 'contrast/utils/duck_utils' module Contrast module Agent module Assess module Policy module Propagator # Propagation that results in all the tags of the source being # applied to the target at the point of insertion. The target's # preexisting tags are shifted to account for this insertion. class Response < Contrast::Agent::Assess::Policy::Propagator::Base class << self # This will path the Net::HTTP.request method. It takes two parameters: # - req: Net::HTTPGenericRequest # - body: String # As body may be optional, we need to check if it's nil or not. # # @param propagation_node [Contrast::Agent::Assess::Policy::PropagationNode] # @param preshift [Contrast::Agent::Assess::Preshift] # @param ret [Object] Return targer from method invocation. # @param _block [nil, {}] block passed. def net_response_keep propagation_node, preshift, ret, _block return unless Contrast::ASSESS.track_response_as_source? # Check to see if the argument is of correct type, and whether the body is tracked or not. # if it's tracked and the body is not nil, then copy the properties from the source's body # to the target's body. source_body = if preshift.args.length == 2 preshift.args[1] else preshift.args[0]&.body end copy_body_tags(propagation_node, source_body, ret) end private # Copy the properties form source body to the response body, if one is present. # # @param propagation_node [Contrast::Agent::Assess::Policy::PropagationNode] # @param source_body [String] the tracked body to copy from. # @param ret [String] the return target from method invocation. # @return [String, nil] def copy_body_tags propagation_node, source_body, ret return if Contrast::Utils::DuckUtils.empty_duck?(source_body) return unless ret&.body&.cs__is_a?(String) return unless source_body&.cs__is_a?(String) return unless (properties = Contrast::Agent::Assess::Tracker.properties!(ret.body)) # KEEP properties.copy_from(source_body, ret.body, 0, propagation_node.untags) ret end end end end end end end end