# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Components # This component encapsulates the statefulness of settings. # When we say 'settings', we're referring specifically to external # directives (likely provided by TeamServer) about product operation. # 'Settings' is not a generic term for 'configurable stuff'. module Settings APPLICATION_STATE_BASE = Struct.new(:modes_by_id, :exclusion_matchers).new( Hash.new { Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION }, []) PROTECT_STATE_BASE = Struct.new(:enabled, :rules).new(false, {}) ASSESS_STATE_BASE = Struct.new(:enabled, :sampling_settings, :disabled_assess_rules).new(false, nil, []) do def sampling_settings= new_val @sampling_settings = new_val Contrast::Utils::Assess::SamplingUtil.instance.update end end # This is a class. class Interface include Contrast::Components::ComponentBase include Contrast::Components::Interface access_component :config # tainted_columns are database columns that receive unsanitized input. attr_reader :tainted_columns # This can probably go into assess_state? attr_reader :assess_state, :protect_state, :application_state def initialize reset_state end def code_exclusions @application_state.exclusion_matchers.select(&:code?) end # @param server_features [Contrast::Api::Settings::ServerFeatures] def update_from_server_features server_features @protect_state.enabled = server_features.protect_enabled? @assess_state.enabled = server_features.assess_enabled? @assess_state.sampling_settings = server_features.assess.sampling end # @param application_settings [Contrast::Api::Settings::ApplicationSettings] def update_from_application_settings application_settings new_vals = application_settings.application_state_translation @application_state.modes_by_id = new_vals[:modes_by_id] @application_state.exclusion_matchers = new_vals[:exclusion_matchers] @assess_state.disabled_assess_rules = new_vals[:disabled_assess_rules] end # Wipe state to zero. def reset_state @protect_state = PROTECT_STATE_BASE.dup @assess_state = ASSESS_STATE_BASE.dup @application_state = APPLICATION_STATE_BASE.dup @tainted_columns = {} end def build_protect_rules @protect_state.rules = {} # Rules. They add themselves on initialize. Contrast::Agent::Protect::Rule::CmdInjection.new Contrast::Agent::Protect::Rule::Deserialization.new Contrast::Agent::Protect::Rule::HttpMethodTampering.new Contrast::Agent::Protect::Rule::NoSqli.new Contrast::Agent::Protect::Rule::PathTraversal.new Contrast::Agent::Protect::Rule::Sqli.new Contrast::Agent::Protect::Rule::UnsafeFileUpload.new Contrast::Agent::Protect::Rule::Xss.new Contrast::Agent::Protect::Rule::Xxe.new end end COMPONENT_INTERFACE = Interface.new end end end