# 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.' class << self # @param attack_sample [Contrast::Api::Dtm::RaspRuleSample] # @return [Hash] the details for this specific rule def extract_details attack_sample { start: attack_sample.sqli.start_idx, end: attack_sample.sqli.end_idx, boundaryOverrunIndex: attack_sample.sqli.boundary_overrun_idx, inputBoundaryIndex: attack_sample.sqli.input_boundary_idx, query: attack_sample.sqli.query } end end 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 end end end end end