# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/reporting/details/sqli_dangerous_functions' module Contrast module Agent module Protect module Rule # This class will include the check for SQL Injection Semantic Dangerous Functions class SqliDangerousFunctions < Contrast::Agent::Protect::Rule::SqliBaseRule NAME = 'sql-injection-semantic-dangerous-functions' BLOCK_MESSAGE = 'SQLi Semantic Dangerous Functions rule triggered. Response blocked.' SQL_DANGEROUS_FUNCTIONS = %w[unhex waitfor xp_cmdshell exec].cs__freeze def rule_name NAME end def infilter context, sql_query return false if protect_excluded_by_url?(rule_name, context.request.path) return unless violated?(sql_query) result = build_violation(context, sql_query) return unless result append_to_activity(context, result) cef_logging(result, :successful_attack) raise(Contrast::SecurityException.new(self, BLOCK_MESSAGE)) if blocked? end protected def violated? attack_string SQL_DANGEROUS_FUNCTIONS.any? { |dang_func| attack_string.downcase.include?(dang_func) } end def build_violation context, potential_attack_string result = build_attack_result(context) update_successful_attack_response(context, nil, result, potential_attack_string) append_sample(context, nil, result, potential_attack_string) result end # Override if rule can make use of the candidate string or kwargs to # build rasp rule sample. def build_sample context, ia_result, candidate_string, **_kwargs sample = build_base_sample(context, nil) sample.details = Contrast::Agent::Reporting::Details::SqliDangerousFunctions.new sample.details.query = candidate_string if ia_result.nil? ui = Contrast::Agent::Reporting::UserInput.new ui.input_type = :UNKNOWN ui.value = candidate_string sample.user_input = ui end sample end end end end end end