# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/agent/protect/rule/base_service' require 'contrast/agent/protect/policy/applies_sqli_rule' require 'contrast/agent/protect/rule/sql_sample_builder' require 'contrast/agent/reporting/input_analysis/input_type' module Contrast module Agent module Protect module Rule # The Ruby implementation of the Protect SQL Injection rule. class Sqli < Contrast::Agent::Protect::Rule::BaseService # Generate a sample for the SQLI injection detection rule, allowing for reporting to and rendering # by TeamServer include SqlSampleBuilder::SqliSample # Defining build_attack_with_match method include SqlSampleBuilder::AttackBuilder include Contrast::Agent::Reporting::InputType class << self include Contrast::Agent::Reporting::InputType end APPLICABLE_USER_INPUTS = [ BODY, COOKIE_NAME, COOKIE_VALUE, HEADER, PARAMETER_NAME, PARAMETER_VALUE, JSON_VALUE, MULTIPART_VALUE, MULTIPART_FIELD_NAME, XML_VALUE, DWR_VALUE ].cs__freeze NAME = 'sql-injection' BLOCK_MESSAGE = 'SQLi rule triggered. Response blocked.' def rule_name NAME end def block_message BLOCK_MESSAGE end def infilter context, database, query_string return unless infilter?(context) result = find_attacker(context, query_string, database: database) return unless result append_to_activity(context, result) cef_logging result, :successful_attack, query_string raise Contrast::SecurityException.new(self, BLOCK_MESSAGE) if blocked? end private def find_attacker context, potential_attack_string, **kwargs ia_results = gather_ia_results(context) find_attacker_with_results(context, potential_attack_string, ia_results, **kwargs) end def infilter? context return false unless context&.agent_input_analysis&.results return false unless enabled? return false if protect_excluded_by_code? true end def gather_ia_results context context.agent_input_analysis.results.select do |ia_result| ia_result.rule_id == rule_name end end end end end end end