# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/utils/input_classification_base' module Contrast module Agent module Protect module Rule # The Ruby implementation of the Protect Path Traversal rule # Input classification module PathTraversalInputClassification PATH_TRAVERSAL_MATCH = 'path-traversal-input-tracing-v1' WORTHWATCHING_MATCH = 'path-traversal-worth-watching-v2' THRESHOLD = 90.cs__freeze class << self include InputClassificationBase private # This methods checks if input is tagged DEFINITEATTACK or IGNORE matches value with it's # key if needed and Creates new isntance 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. # @param value [String, Array] the value of the input. # # @return res [Contrast::Agent::Reporting::InputAnalysisResult] def create_new_input_result request, rule_id, input_type, value return unless Contrast::AGENT_LIB input_eval = Contrast::AGENT_LIB.eval_input(value, convert_input_type(input_type), Contrast::AGENT_LIB.rule_set[rule_id], Contrast::AGENT_LIB.eval_option[:PREFER_WORTH_WATCHING]) ia_result = new_ia_result(rule_id, input_type, request.path, value) score = input_eval&.score || 0 if score >= THRESHOLD ia_result.score_level = DEFINITEATTACK ia_result.ids << PATH_TRAVERSAL_MATCH elsif score == 10 # There is one pattern to match 10 and thus on its own will be reported as a probe. # This rule can report WORTHWATCHING: # https://protect-spec.prod.dotnet.contsec.com/rules/path-traversal.html#applicable-input-types ia_result.score_level = WORTHWATCHING ia_result.ids << WORTHWATCHING_MATCH else ia_result.score_level = IGNORE end add_needed_key(request, ia_result, input_type, value) ia_result end end end end end end end