# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'rubygems/version' require 'contrast/agent/rule_set' module Contrast module Components module Agent # A wrapper build around the Common Agent Configuration project to allow # for access of the values contained in its parent_configuration_spec.yaml. # Specifically, this allows for querying the state of the Agent. class Interface include Contrast::Components::ComponentBase def enabled? @_enabled = !false?(::Contrast::CONFIG.root.enable) if @_enabled.nil? @_enabled end def disabled? !enabled? end def enable! @_enabled = true end def disable! @_enabled = false Contrast::Agent::TracePointHook.disable Contrast::Agent.thread_watcher&.shutdown! end def ruleset @_ruleset ||= Contrast::Agent::RuleSet.new(retrieve_protect_ruleset&.values) end def reset_ruleset @_ruleset = nil end def patch_interpolation? interpolation_patch_possible? end def rewrite_interpolation? !interpolation_patch_possible? end def patch_yield? @_patch_yield = !false?(::Contrast::CONFIG.root.agent.ruby.propagate_yield) if @_patch_yield.nil? @_patch_yield end def interpolation_enabled? if @_interpolation_enabled.nil? @_interpolation_enabled = !false?(::Contrast::CONFIG.root.agent.ruby.interpolate) end @_interpolation_enabled end def omit_body? @_omit_body = true?(::Contrast::CONFIG.root.agent.omit_body) if @_omit_body.nil? @_omit_body end def exception_control @_exception_control ||= { enable: true?(::Contrast::CONFIG.root.agent.ruby.exceptions.capture), status: ::Contrast::CONFIG.root.agent.ruby.exceptions.override_status || 403, message: ::Contrast::CONFIG.root.agent.ruby.exceptions.override_message || Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE } end def skip_instrumentation? loaded_module_name return true unless loaded_module_name loaded_module_name.start_with?(*::Contrast::CONFIG.root.agent.ruby.uninstrument_namespace) end # Insert ourselves into the application, keeping our middleware at the outermost layer of the onion def insert_middleware app app.middleware.insert_before 0, Contrast::Agent::Middleware end def enable_tracepoint Contrast::Agent::TracePointHook.enable! end protected INTERPOLATION_HOOKABLE_VERSION = Gem::Version.new('2.6.0') # Ruby exposed the C method for interpolation in version 2.6.0, meaning # we can attempt to patch using Funchook for that version and later. def interpolation_patch_possible? if @_interpolation_patch_possible.nil? @_interpolation_patch_possible = Gem::Version.new(RUBY_VERSION) >= INTERPOLATION_HOOKABLE_VERSION end @_interpolation_patch_possible end def retrieve_protect_ruleset return {} unless enabled? && ::Contrast::PROTECT.enabled? ::Contrast::PROTECT.rules end end end end end