# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true cs__scoped_require 'contrast/utils/object_share' cs__scoped_require 'contrast/components/interface' module Contrast module Agent module Assess module Rule class Csrf # This class is called by our patches to determine if a CSRF # vulnerability exists within an application. It is used through a # CUSTOM propagation in order to capture that a Database call was # made in response to a request that did not have the Contrast CSRF # token. class CsrfApplicator include Contrast::Components::Interface access_component :logging, :analysis, :scope CS__CSRF_LOG_MSG = 'applying CSRF assess rule' def self.rule @_rule ||= Contrast::Agent::FeatureState.instance.assess_rule( Contrast::Agent::Assess::Rule::Csrf::NAME) end def self.csrf_tagger patcher, preshift, _ret, _block return unless rule&.enabled? idx = patcher.sources[0].to_i args = preshift.args return unless args&.length.to_i > idx sql = args[idx] return unless sql with_contrast_scope do logger.debug(nil, CS__CSRF_LOG_MSG) rule.record_db_state_change( Contrast::Agent::REQUEST_TRACKER.current, sql) end end def self.cs__assess_apply_csrf_rule sql context = Contrast::Agent::REQUEST_TRACKER.current return unless context&.app_loaded? return unless ASSESS.enabled? return unless sql rule = Contrast::Agent::FeatureState.instance.assess_rule( Contrast::Agent::Assess::Rule::Csrf::NAME) return unless rule&.enabled? with_contrast_scope do logger.debug(CS__CSRF_LOG_MSG) rule.record_db_state_change(context, sql) end rescue StandardError => e logger.warn(e, 'Error running CSRF assess rule') end end end end end end end