# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'cs__scope/cs__scope' module Contrast module Agent # Scope lets us disable Contrast for certain code calls. We need to do this so # that we don't propagate through our own code. # # Think logging: If you have # something like "The source was '" + source + "'", and source is tracked, # you'll trigger propagation with the + method. This in turn would cause # propagation if you log there "The target ''" + target + "' was propagated'" # Which would then cause another propagation with the '+' method, forever. # # Instead, we should say "If I'm already doing Contrast things, don't track # this" # # Scope Exits... # by design, can go below zero. # every exit/enter pair (regardless of series) # should cancel each other out. # # so we prefer this sequence: # scope = 0 # exit = -1 # enter = 0 # enter = 1 # exit = 0 # scope = 0 # # over this sequence: # scope = 0 # exit = 0 # enter = 1 # enter = 2 # exit = 1 # scope = 1 # # This class have been moved to C and it's called from there. Here remains # the validation and wrapper methods. # # Methods defined in C: # # sets scope instance variables. # def initialize end; # # Check if we are in contrast scope. # def in_contrast_scope? end; # @return [Boolean] check if we are in contrast scope # if the scope is above 0 return true. # # check if we are in deserialization scope. # def in_deserialization_scope? end; # @return [Boolean] check if we are in contrast scope # if the scope is above 0 return true. # # check if we are in split scope. # def in_split_scope? end; # @return [Boolean] check if we are in contrast scope # if the scope is above 0 return true. # # enter contrast scope. # def enter_contrast_scope! end; # @return @contrast_scope [Integer] contrast scope increased. # # enter deserialization scope. # def enter_deserialization_scope! end; # @return @deserialization_scope [Integer] deserialization scope increased. # # enter split scope. # def enter_split_scope! end; # @return @split_scope [Integer] split scope increased. # # check split scope depth. # def split_scope_depth end; # @return @split_scope [Integer] split scope depth. # # exit contrast scope. # def exit_contrast_scope! end; # @return @contrast_scope [Integer] contrast scope decreased. # # exit deserialization scope. # def exit_deserialization_scope! end; # @return @deserialization_scope [Integer] deserialization scope decreased. # # exit split scope. # def exit_split_scope! end; # @return @split_scope [Integer] split scope decreased. # # Static methods to be used, the cases are defined by the usage from the above methods # # check if we are in specific scope. # def in_scope? name end; # @param name [Symbol] scope symbol representing scope to check. # @return [Boolean] check if we are in passed scope. # # enter specific scope. # def enter_scope! name end; # @param name [Symbol] scope symbol representing scope to enter. # @return scope [Integer] entered scope value increased. # # exit specific scope. # def exit_cope! name end; # @param name [Symbol] scope symbol representing scope to exit. # @return scope [Integer] entered scope value decreased. class Scope SCOPE_LIST = %i[contrast deserialization split].cs__freeze # Wraps block to be executed in contrast scope. # On completion exits scope. def with_contrast_scope enter_contrast_scope! yield ensure exit_contrast_scope! end # Wraps block to be executed in deserialization scope. # On completion exits scope. def with_deserialization_scope enter_deserialization_scope! yield ensure exit_deserialization_scope! end # Wraps block to be executed in split scope. # On completion exits scope. def with_split_scope enter_split_scope! yield ensure exit_split_scope! end class << self # Validates scope. To be valid the scope must be one of: # :contrast, :split, :deserialization # # @param scope_sym [Symbol] scope to check. # @return [Boolean] true | false def valid_scope? scope_sym Contrast::Agent::Scope::SCOPE_LIST.include?(scope_sym) end end end end end