# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/utils/object_share' require 'contrast/agent/protect/input_analyzer/input_analyzer' require 'contrast/agent/reporting/attack_result/attack_result' require 'contrast/agent/reporting/attack_result/rasp_rule_sample' require 'contrast/utils/input_classification' module Contrast module Agent module Protect module Rule # This module will do the Input Classification stage of HttpMethodTampering rule # as a result input would be marked as DEFINETEATTACK or IGNORE, # to be analyzed at the sink level. module HttpMethodTamperingInputClassification # class << self # include InputClassificationBase # # # This method will determine actually if the user input is DEFINITEATTACK or IGNORE # # # # @param input_type [Contrast::Agent::Reporting::InputType] the type of the user input # # @param input_analysis [Contrast::Agent::Reporting::InputAnalysis] Holds all the results from the input # # analysis from the current request. # def classify input_type, input_analysis # return unless input_analysis.request # return unless input_type == METHOD # # rule_id = Contrast::Agent::Protect::Rule::HttpMethodTampering::NAME # # ia_result = method_tampering_new_input_analysis(input_analysis.request, rule_id, input_type) # input_analysis.results << ia_result # # return input_analysis if ia_result.score_level == IGNORE # # attack_result = build_attack_result ia_result, rule_id # # if Contrast::Api::Settings::ProtectionRule::Mode::BLOCK != Contrast::PROTECT.rule_mode(rule_id) # attack_result.response = :EXPLOITED # Contrast::Agent::EXPLOITS.push attack_result # return input_analysis # end # # attack_result.response = :BLOCKED # context.activity.results << attack_result # raise Contrast::SecurityException.new(self, # 'HTTP Method Tampering rule triggered. '\ # "Call to #{ input_analysis.request.path } with " \ # "#{ input_analysis.request.request_method } blocked.") # end # # private # # # @param request [Contrast::Agent::Request] the current request context. # def method_tampering_exploited? request # !Contrast::Agent::Protect::Rule::HttpMethodTampering::APPLICABLE_METHODS_INPUTS.include?(request.request_method) # rubocop:disable Layout/LineLength # end # # # This methods checks if input is tagged DEFINITEATTACK or IGNORE matches value with it's # # key if needed and Creates new instance of InputAnalysisResult. # # # # @param request [Contrast::Agent::Request] the current request context. # # @param rule_id [String] The name of the Protect Rule. # # @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input. # # # # @return res [Contrast::Agent::Reporting::InputAnalysisResult] # def method_tampering_new_input_analysis request, rule_id, input_type # ia_result = new_ia_result rule_id, input_type, request.path # if method_tampering_exploited? request # ia_result.score_level = DEFINITEATTACK # ia_result.ids << rule_id # else # ia_result.score_level = IGNORE # end # # ia_result # end # # def build_attack_result ia_result, rule_id # rasp_rule_sample = Contrast::Agent::Reporting::RaspRuleSample.new.build context, ia_result # result = Contrast::Agent::Reporting::AttackResult.new # result.rule_id = rule_id # result.samples << rasp_rule_sample # result # end # # def context # Contrast::Agent::REQUEST_TRACKER.current # end # end end end end end end