# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/components/logger' require 'contrast/components/scope' require 'contrast/agent/reporting/reporter' require 'contrast/agent/reporting/reporting_utilities/dtm_message' require 'contrast/agent/reporting/masker/masker' module Contrast module Agent # This class is instantiated when we receive a request and the agent is enabled to process that request. It holds # the ruleset that we perform filtering operations on (currently prefilter and postfilter). class RequestHandler include Contrast::Components::Logger::InstanceMethods attr_reader :ruleset, :context # @param context [Contrast::Agent::RequestContext] the context of the request for which this handler applies def initialize context @context = context @ruleset = ::Contrast::AGENT.ruleset end # Send Activities messages to TS [Contrast::Agent::Reporting::ServerActivity, # Contrast::Api::Dtm::ServerActivity, # Contrast::Api::Dtm::Activity, # Contrast::Api::Dtm::ObservedRoute] # If bypass is enabled use the reporting service if not than the messages are # send with speedracer # TODO: RUBY-1355 # TODO: RUBY-1358 # TODO: RUBY-1438 -- remove def send_activity_messages events = [context.activity] unless Contrast::Agent::Reporter.enabled? Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.generate_library_usage(context.activity) events << context.server_activity events << context.observed_route end events.each do |message| Contrast::Agent.messaging_queue&.send_event_eventually(message) end end # reports events[Contrast::Agent::Reporting::ReporterEvent] to TS # This method is used to send our JSON messages directly to TeamServer at the end of each request. As we move # more endpoints over, this method will take the messages originally sent by #send_actiivty_messages. At the end, # that method should be removed. def report_activity # rubocop:disable Metrics/AbcSize return unless Contrast::Agent::Reporter.enabled? reporter = Contrast::Agent.reporter return unless reporter # Mask Sensitive Data Contrast::Agent::Reporting::Masker.mask context.activity Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.generate_library_usage(context.activity) [ context.new_observed_route, Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.server_activity), Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity.library_usages), Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity) ].each do |event| reporter.send_event(event) rescue StandardError => e logger.warn('Unable to send Event Activity', e) end context.activity.library_usages.clear # TODO: RUBY-1355 remove when no longer using activity end # If the response is streaming, we should only perform filtering on our stream safe rules def stream_safe_postfilter stream_safe_ruleset = ruleset.select(&:stream_safe?) postfilter_ruleset = Contrast::Agent::RuleSet.new(stream_safe_ruleset) postfilter_ruleset.postfilter end end end end