# Copyright (c) 2022 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_writer :bot_blocker, :cmd_injection, :sql_injection, :nosql_injection, :untrusted_deserialization, :xxe, :path_traversal, :reflected_xss, :unsafe_file_upload, :rule_base BASE_RULE = 'Contrast::Agent::Protect::Rule::Base'.cs__freeze def initialize hsh = {} return unless hsh @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']) @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']) @reflected_xss = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'reflected-xss']) @sql_injection = Contrast::Config::ProtectRuleConfiguration.new(hsh[:'sql-injection']) @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 bot_blocker @bot_blocker ||= Contrast::Config::ProtectRuleConfiguration.new end def cmd_injection @cmd_injection ||= Contrast::Config::ProtectRuleConfiguration.new end def sql_injection @sql_injection ||= Contrast::Config::ProtectRuleConfiguration.new end def nosql_injection @nosql_injection ||= Contrast::Config::ProtectRuleConfiguration.new end def untrusted_deserialization @untrusted_deserialization ||= Contrast::Config::ProtectRuleConfiguration.new end def method_tampering @method_tampering ||= Contrast::Config::ProtectRuleConfiguration.new end def xxe @xxe ||= Contrast::Config::ProtectRuleConfiguration.new end def path_traversal @path_traversal ||= Contrast::Config::ProtectRuleConfiguration.new end def reflected_xss @reflected_xss ||= Contrast::Config::ProtectRuleConfiguration.new end def unsafe_file_upload @unsafe_file_upload ||= Contrast::Config::ProtectRuleConfiguration.new end def rule_base @rule_base ||= Contrast::Config::ProtectRuleConfiguration.new 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_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