# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/config/protect_rule_configuration' module Contrast module Config # Common Configuration settings. Those in this section pertain to the protect rule modes of the Agent. class ProtectRulesConfiguration include Contrast::Config::BaseConfiguration attr_accessor :disabled_rules attr_reader :bot_blocker, :cmd_injection, :cmd_injection_command_backdoors, :cmd_injection_semantic_chained_commands, :cmd_injection_semantic_dangerous_paths, :method_tampering, :nosql_injection, :path_traversal, :path_traversal_semantic_file_security_bypass, :reflected_xss, :sql_injection, :sql_injection_semantic_dangerous_functions, :unsafe_file_upload, :untrusted_deserialization, :xxe, :rule_base BASE_RULE = 'Contrast::Agent::Protect::Rule::Base'.cs__freeze def initialize hsh = {} # rubocop:disable Metrics/AbcSize return unless hsh # IVs must be with the same name as rule_id @disabled_rules = hsh[:disabled_rules] @rule_base = Contrast::Config::ProtectRuleConfiguration.new(hsh[BASE_RULE.to_sym]) @bot_blocker = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'bot-blocker']) @cmd_injection = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'cmd-injection']) @cmd_injection_command_backdoors = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'cmd-injection-command-backdoors']) @cmd_injection_semantic_chained_commands = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'cmd-injection-semantic-chained-commands']) @cmd_injection_semantic_dangerous_paths = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'cmd-injection-semantic-dangerous-paths']) @method_tampering = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'method-tampering']) @nosql_injection = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'nosql-injection']) @path_traversal = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'path-traversal']) @path_traversal_semantic_file_security_bypass = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'path-traversal-semantic-file-security-bypass']) @reflected_xss = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'reflected-xss']) @sql_injection = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'sql-injection']) @sql_injection_semantic_dangerous_functions = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'sql-injection-semantic-dangerous-functions']) @unsafe_file_upload = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'unsafe-file-upload']) @untrusted_deserialization = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'untrusted-deserialization']) @xxe = Contrast::Config::ProtectRuleConfiguration.new(hsh[:xxe]) end def []= key, value instance_variable_set("@#{ convert_key(key) }".to_sym, value) end def [] key send(convert_key(key).to_sym) end def convert_key key return_proper_class(key).to_s.tr('-', '_') end # Convert instance variable names to format expected by TS # for adding to the hash def to_contrast_hash hsh = {} instance_variables.each do |iv| # strip the '@' to get the key key = return_proper_class(iv.to_s.delete('@')) hsh[key.tr('_', '-')] = send(key.to_sym) end hsh end # This method is to handle the specific case of # Contrast::Agent::Protect::Rule::Base from protect/base.rb#initialize # # @param str_key [String] the key we want to check form the config # @return String def return_proper_class str_key return BASE_RULE if str_key == 'rule_base' return 'rule_base' if str_key == BASE_RULE str_key end # if method 'Contrast::Agent::Protect::Rule::Base' is being called from convert_to_hash # handle missing method and call original getter def method_missing name, *_args return unless name.to_s.include?('Base') || name.to_s.start_with?('Contrast') @rule_base end def respond_to_missing? method_name, include_private = false (method_name.to_s.include?('Base') || method_name.to_s.start_with?('Contrast')) || super end end end end