contrast-agent 6.15.1 → 6.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/contrast/agent/telemetry/base.rb +13 -4
 - data/lib/contrast/agent/telemetry/client.rb +3 -1
 - data/lib/contrast/agent/telemetry/telemetry.rb +6 -0
 - data/lib/contrast/agent/thread/thread_watcher.rb +7 -1
 - data/lib/contrast/agent/thread/worker_thread.rb +1 -1
 - data/lib/contrast/agent/version.rb +1 -1
 - data/lib/contrast/components/agent.rb +3 -0
 - data/lib/contrast/configuration.rb +9 -0
 - data/lib/contrast/framework/manager.rb +5 -2
 - data/lib/contrast/funchook/funchook.rb +0 -1
 - data/lib/contrast/logger/aliased_logging.rb +26 -0
 - data/lib/contrast/utils/job_servers_running.rb +8 -6
 - data/lib/contrast/utils/log_utils.rb +1 -1
 - data/lib/contrast/utils/middleware_utils.rb +4 -0
 - data/lib/contrast/utils/net_http_base.rb +9 -3
 - metadata +13 -13
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: a2f94b8a7a87febf8c10b58cf5133081a6dc3183c158ad59c202921efc23753e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 2e3fff601596655f725a4bea7a8b6f309a5f702557cfb009ad82b1d424da8d40
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: cd0a28ee1a7331401a4709e1aec63a44b272d9d93ba9e6dcebd47270078165b42e3955fe8d938311b10cae4ec60cfaa92d9bee088b3a6056a2461fb00c6a4ab8
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ba7ab7bebd769fd3057533da348a260e208bb622fe50aab3d0e68f8709413579bac258588680f04a65aa68ff4f5dbf0a2038d56fde7fd2ef2892a095e0e8e388
         
     | 
| 
         @@ -7,12 +7,13 @@ require 'contrast/agent/telemetry/client' 
     | 
|
| 
       7 
7 
     | 
    
         
             
            require 'contrast/agent/thread/worker_thread'
         
     | 
| 
       8 
8 
     | 
    
         
             
            require 'contrast/agent/telemetry/telemetry'
         
     | 
| 
       9 
9 
     | 
    
         
             
            require 'contrast/agent/telemetry/exception'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'contrast/utils/job_servers_running'
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            module Contrast
         
     | 
| 
       12 
13 
     | 
    
         
             
              module Agent
         
     | 
| 
       13 
14 
     | 
    
         
             
                module Telemetry
         
     | 
| 
       14 
15 
     | 
    
         
             
                  # This class will initialize and hold everything needed for the telemetry
         
     | 
| 
       15 
     | 
    
         
            -
                  class Base < WorkerThread
         
     | 
| 
      
 16 
     | 
    
         
            +
                  class Base < WorkerThread # rubocop:disable Metrics/ClassLength
         
     | 
| 
       16 
17 
     | 
    
         
             
                    include Contrast::Components::Logger::InstanceMethods
         
     | 
| 
       17 
18 
     | 
    
         
             
                    # this is where we will send the data from the agents
         
     | 
| 
       18 
19 
     | 
    
         
             
                    URL = 'https://telemetry.ruby.contrastsecurity.com/'
         
     | 
| 
         @@ -48,6 +49,8 @@ module Contrast 
     | 
|
| 
       48 
49 
     | 
    
         
             
                      private
         
     | 
| 
       49 
50 
     | 
    
         | 
| 
       50 
51 
     | 
    
         
             
                      def telemetry_enabled?
         
     | 
| 
      
 52 
     | 
    
         
            +
                        return false if Contrast::AGENT.disabled? || Contrast::Utils::JobServersRunning.job_servers_running?
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
       51 
54 
     | 
    
         
             
                        opt_out_telemetry = return_value(:telemetry_opt_outs).to_s
         
     | 
| 
       52 
55 
     | 
    
         
             
                        return false if opt_out_telemetry.casecmp?('true') || opt_out_telemetry == '1'
         
     | 
| 
       53 
56 
     | 
    
         | 
| 
         @@ -56,7 +59,9 @@ module Contrast 
     | 
|
| 
       56 
59 
     | 
    
         
             
                        @_client = Contrast::Agent::Telemetry::Client.new
         
     | 
| 
       57 
60 
     | 
    
         
             
                        ip_opt_out_telemetry = @_client.initialize_connection(URL)
         
     | 
| 
       58 
61 
     | 
    
         
             
                        if ip_opt_out_telemetry.nil?
         
     | 
| 
       59 
     | 
    
         
            -
                           
     | 
| 
      
 62 
     | 
    
         
            +
                          # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 63 
     | 
    
         
            +
                          #   an infinite loop w/ telemetry
         
     | 
| 
      
 64 
     | 
    
         
            +
                          logger.debug("[Telemetry] Connection was not established properly!!! \n
         
     | 
| 
       60 
65 
     | 
    
         
             
                                      Telemetry reporting will be disabled!")
         
     | 
| 
       61 
66 
     | 
    
         
             
                          return false
         
     | 
| 
       62 
67 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -74,6 +79,8 @@ module Contrast 
     | 
|
| 
       74 
79 
     | 
    
         
             
                    end
         
     | 
| 
       75 
80 
     | 
    
         | 
| 
       76 
81 
     | 
    
         
             
                    def attempt_to_start?
         
     | 
| 
      
 82 
     | 
    
         
            +
                      return unless super
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       77 
84 
     | 
    
         
             
                      unless cs__class.enabled?
         
     | 
| 
       78 
85 
     | 
    
         
             
                        logger.info('[Telemetry] Telemetry service is disabled!')
         
     | 
| 
       79 
86 
     | 
    
         
             
                        return false
         
     | 
| 
         @@ -92,7 +99,7 @@ module Contrast 
     | 
|
| 
       92 
99 
     | 
    
         | 
| 
       93 
100 
     | 
    
         
             
                    def send_event event
         
     | 
| 
       94 
101 
     | 
    
         
             
                      if ::Contrast::AGENT.disabled?
         
     | 
| 
       95 
     | 
    
         
            -
                        logger. 
     | 
| 
      
 102 
     | 
    
         
            +
                        logger.debug('[Telemetry] Attempted to queue event with Agent disabled', caller: caller, event: event)
         
     | 
| 
       96 
103 
     | 
    
         
             
                        return
         
     | 
| 
       97 
104 
     | 
    
         
             
                      end
         
     | 
| 
       98 
105 
     | 
    
         | 
| 
         @@ -148,7 +155,9 @@ module Contrast 
     | 
|
| 
       148 
155 
     | 
    
         
             
                                sleep(retry_sleep_time) unless retry_sleep_time.nil?
         
     | 
| 
       149 
156 
     | 
    
         
             
                              end
         
     | 
| 
       150 
157 
     | 
    
         
             
                            rescue StandardError => e
         
     | 
| 
       151 
     | 
    
         
            -
                               
     | 
| 
      
 158 
     | 
    
         
            +
                              # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 159 
     | 
    
         
            +
                              #   an infinite loop w/ telemetry
         
     | 
| 
      
 160 
     | 
    
         
            +
                              logger.debug('[Telemetry] Could not send message to service from telemetry queue.', e)
         
     | 
| 
       152 
161 
     | 
    
         
             
                              stop!
         
     | 
| 
       153 
162 
     | 
    
         
             
                            end
         
     | 
| 
       154 
163 
     | 
    
         
             
                          end
         
     | 
| 
         @@ -100,7 +100,9 @@ module Contrast 
     | 
|
| 
       100 
100 
     | 
    
         
             
                    def get_event_json event
         
     | 
| 
       101 
101 
     | 
    
         
             
                      Array(event.to_controlled_hash).to_json
         
     | 
| 
       102 
102 
     | 
    
         
             
                    rescue Exception => e # rubocop:disable Lint/RescueException
         
     | 
| 
       103 
     | 
    
         
            -
                       
     | 
| 
      
 103 
     | 
    
         
            +
                      # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 104 
     | 
    
         
            +
                      #   an infinite loop w/ telemetry
         
     | 
| 
      
 105 
     | 
    
         
            +
                      logger.debug('[Telemetry] Unable to convert TelemetryEvent to JSON string', e, hsh)
         
     | 
| 
       104 
106 
     | 
    
         
             
                      raise(e)
         
     | 
| 
       105 
107 
     | 
    
         
             
                    end
         
     | 
| 
       106 
108 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -94,6 +94,12 @@ module Contrast 
     | 
|
| 
       94 
94 
     | 
    
         
             
                    def telemetry_exceptions_enabled?
         
     | 
| 
       95 
95 
     | 
    
         
             
                      opts_out_telemetry = return_value(:telemetry_opt_outs).to_s
         
     | 
| 
       96 
96 
     | 
    
         
             
                      return false if opts_out_telemetry.casecmp?('true') || opts_out_telemetry == '1'
         
     | 
| 
      
 97 
     | 
    
         
            +
                      # Double check if telemetry is enabled, this includes a check for Agent enable setting in the
         
     | 
| 
      
 98 
     | 
    
         
            +
                      # config. In case of disabled Agent the queue won't be created and the Telemetry would not
         
     | 
| 
      
 99 
     | 
    
         
            +
                      # be enabled. This check is here to prevent a loop of error creations that could no be added
         
     | 
| 
      
 100 
     | 
    
         
            +
                      # to a queue ( because the client cannot be initialized if the Agent is disabled or settings are
         
     | 
| 
      
 101 
     | 
    
         
            +
                      # missing).
         
     | 
| 
      
 102 
     | 
    
         
            +
                      return false unless Contrast::Agent::Telemetry::Base.enabled?
         
     | 
| 
       97 
103 
     | 
    
         | 
| 
       98 
104 
     | 
    
         
             
                      true
         
     | 
| 
       99 
105 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -7,6 +7,7 @@ require 'contrast/agent/reporting/reporting_workers/reporting_workers' 
     | 
|
| 
       7 
7 
     | 
    
         
             
            require 'contrast/agent/telemetry/base'
         
     | 
| 
       8 
8 
     | 
    
         
             
            require 'contrast/agent/protect/input_analyzer/worth_watching_analyzer'
         
     | 
| 
       9 
9 
     | 
    
         
             
            require 'contrast/config/diagnostics'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'contrast/utils/job_servers_running'
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            module Contrast
         
     | 
| 
       12 
13 
     | 
    
         
             
              module Agent
         
     | 
| 
         @@ -28,6 +29,11 @@ module Contrast 
     | 
|
| 
       28 
29 
     | 
    
         
             
                  attr_reader :reporter_app_settings_worker
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                  def initialize
         
     | 
| 
      
 32 
     | 
    
         
            +
                    if Contrast::AGENT.disabled? || Contrast::Utils::JobServersRunning.job_servers_running?
         
     | 
| 
      
 33 
     | 
    
         
            +
                      logger.info('Agent Disabled, shutting down all threads...')
         
     | 
| 
      
 34 
     | 
    
         
            +
                      return
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       31 
37 
     | 
    
         
             
                    @heapdump_util = Contrast::Utils::HeapDumpUtil.new
         
     | 
| 
       32 
38 
     | 
    
         
             
                    @reporter = Contrast::Agent::Reporter.new
         
     | 
| 
       33 
39 
     | 
    
         
             
                    @reporter_heartbeat = Contrast::Agent::ReportingWorkers::ReporterHeartbeat.new
         
     | 
| 
         @@ -37,7 +43,7 @@ module Contrast 
     | 
|
| 
       37 
43 
     | 
    
         
             
                    @worth_watching_analyzer = Contrast::Agent::Protect::WorthWatchingInputAnalyzer.new unless protect_disabled?
         
     | 
| 
       38 
44 
     | 
    
         
             
                  end
         
     | 
| 
       39 
45 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  # @return [ 
     | 
| 
      
 46 
     | 
    
         
            +
                  # @return [Array<Contrast::Agent::WorkerThread>] map of process to thread startup status
         
     | 
| 
       41 
47 
     | 
    
         
             
                  def startup!
         
     | 
| 
       42 
48 
     | 
    
         
             
                    check_before_start
         
     | 
| 
       43 
49 
     | 
    
         | 
| 
         @@ -9,6 +9,7 @@ require 'contrast/components/security_logger' 
     | 
|
| 
       9 
9 
     | 
    
         
             
            require 'contrast/components/heap_dump'
         
     | 
| 
       10 
10 
     | 
    
         
             
            require 'contrast/components/ruby_component'
         
     | 
| 
       11 
11 
     | 
    
         
             
            require 'contrast/components/polling'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'contrast/agent/hooks/tracepoint_hook'
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
14 
     | 
    
         
             
            module Contrast
         
     | 
| 
       14 
15 
     | 
    
         
             
              module Components
         
     | 
| 
         @@ -23,6 +24,8 @@ module Contrast 
     | 
|
| 
       23 
24 
     | 
    
         
             
                    attr_reader :canon_name
         
     | 
| 
       24 
25 
     | 
    
         
             
                    # @return [Array]
         
     | 
| 
       25 
26 
     | 
    
         
             
                    attr_reader :config_values
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # @return [Boolean]
         
     | 
| 
      
 28 
     | 
    
         
            +
                    attr_accessor :enable
         
     | 
| 
       26 
29 
     | 
    
         | 
| 
       27 
30 
     | 
    
         
             
                    CANON_NAME = 'agent'
         
     | 
| 
       28 
31 
     | 
    
         
             
                    CONFIG_VALUES = %w[enabled? omit_body?].cs__freeze
         
     | 
| 
         @@ -53,6 +53,7 @@ module Contrast 
     | 
|
| 
       53 
53 
     | 
    
         
             
                # @return [String,nil]
         
     | 
| 
       54 
54 
     | 
    
         
             
                attr_reader :config_file
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
      
 56 
     | 
    
         
            +
                CONTRAST_ENV_MARKER = 'CONTRAST__'
         
     | 
| 
       56 
57 
     | 
    
         
             
                DEFAULT_YAML_PATH  = 'contrast_security.yaml'
         
     | 
| 
       57 
58 
     | 
    
         
             
                MILLISECOND_MARKER = '_ms'
         
     | 
| 
       58 
59 
     | 
    
         
             
                CONVERSION = {}.cs__freeze
         
     | 
| 
         @@ -67,6 +68,14 @@ module Contrast 
     | 
|
| 
       67 
68 
     | 
    
         
             
                  config_kv = deep_symbolize_all_keys(load_config)
         
     | 
| 
       68 
69 
     | 
    
         
             
                  config_sources = assign_source_to(config_kv, Contrast::Components::Config::Sources::YAML)
         
     | 
| 
       69 
70 
     | 
    
         | 
| 
      
 71 
     | 
    
         
            +
                  unless cli_options
         
     | 
| 
      
 72 
     | 
    
         
            +
                    cli_options = {}
         
     | 
| 
      
 73 
     | 
    
         
            +
                    ENV.each do |key, value|
         
     | 
| 
      
 74 
     | 
    
         
            +
                      next unless key.to_s.start_with?(CONTRAST_ENV_MARKER)
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                      cli_options[key] = value
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
       70 
79 
     | 
    
         
             
                  # Overlay CLI options - they take precedence over config file
         
     | 
| 
       71 
80 
     | 
    
         
             
                  cli_options = deep_symbolize_all_keys(cli_options)
         
     | 
| 
       72 
81 
     | 
    
         
             
                  if cli_options
         
     | 
| 
         @@ -11,6 +11,7 @@ require 'contrast/framework/rack/support' 
     | 
|
| 
       11 
11 
     | 
    
         
             
            require 'contrast/framework/rails/support'
         
     | 
| 
       12 
12 
     | 
    
         
             
            require 'contrast/framework/sinatra/support'
         
     | 
| 
       13 
13 
     | 
    
         
             
            require 'contrast/utils/class_util'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'contrast/utils/job_servers_running'
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
16 
     | 
    
         
             
            module Contrast
         
     | 
| 
       16 
17 
     | 
    
         
             
              module Framework
         
     | 
| 
         @@ -28,6 +29,8 @@ module Contrast 
     | 
|
| 
       28 
29 
     | 
    
         
             
                  ].cs__freeze
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                  def initialize
         
     | 
| 
      
 32 
     | 
    
         
            +
                    return if Contrast::AGENT.disabled? || Contrast::Utils::JobServersRunning.job_servers_running?
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       31 
34 
     | 
    
         
             
                    @_frameworks = SUPPORTED_FRAMEWORKS.map do |framework_klass|
         
     | 
| 
       32 
35 
     | 
    
         
             
                      next unless enable_framework_support?(framework_klass.detection_class)
         
     | 
| 
       33 
36 
     | 
    
         | 
| 
         @@ -116,8 +119,8 @@ module Contrast 
     | 
|
| 
       116 
119 
     | 
    
         
             
                  # @param request [Contrast::Agent::Request] the current request.
         
     | 
| 
       117 
120 
     | 
    
         
             
                  # @return [Contrast::Agent::Reporting::RouteCoverage] the current route as a Dtm.
         
     | 
| 
       118 
121 
     | 
    
         
             
                  def get_route_information request
         
     | 
| 
       119 
     | 
    
         
            -
                    @_frameworks 
     | 
| 
       120 
     | 
    
         
            -
                        reject(&:nil?) 
     | 
| 
      
 122 
     | 
    
         
            +
                    @_frameworks&.lazy&.map { |framework_support| framework_support.current_route_coverage(request) }&.
         
     | 
| 
      
 123 
     | 
    
         
            +
                        reject(&:nil?)&.first
         
     | 
| 
       121 
124 
     | 
    
         
             
                  end
         
     | 
| 
       122 
125 
     | 
    
         | 
| 
       123 
126 
     | 
    
         
             
                  # Sometimes the framework we want to instrument is loaded after our agent code. To catch that case, we'll detect
         
     | 
| 
         @@ -40,12 +40,38 @@ module Contrast 
     | 
|
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                  private
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
                  # There's a weird circular import in our code that we don't have time to untangle. This is 100% bad code and
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # I'm sorry to the future team, but this is all we got.
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # If the configuration we need is not available, we'll skip out for now - it means the agent isn't ready. We
         
     | 
| 
      
 47 
     | 
    
         
            +
                  # won't get telemetry exceptions at this point, but that means the agent hasn't initialized and there's a
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # chance we're not supposed to. Essentially, we fail closed.
         
     | 
| 
      
 49 
     | 
    
         
            +
                  #
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # Once we have the agent initialized, we'll use the value to check. Since it cannot change once set, we'll use
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # the saved value.
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # - HM
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # @return [Boolean]
         
     | 
| 
      
 56 
     | 
    
         
            +
                  def buildable?
         
     | 
| 
      
 57 
     | 
    
         
            +
                    if @_buildable.nil?
         
     | 
| 
      
 58 
     | 
    
         
            +
                      return false unless defined?(Contrast) &&
         
     | 
| 
      
 59 
     | 
    
         
            +
                          defined?(Contrast::Agent) &&
         
     | 
| 
      
 60 
     | 
    
         
            +
                          defined?(Contrast::Agent::Telemetry)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                      @_buildable = Contrast::Agent::Telemetry.exceptions_enabled?
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                    @_buildable
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
       43 
67 
     | 
    
         
             
                  # @param type [ALIASED_FATAL, ALIASED_ERROR, ALIASED_WARN] the type of error, used to indicate the function used
         
     | 
| 
       44 
68 
     | 
    
         
             
                  #   for logging
         
     | 
| 
       45 
69 
     | 
    
         
             
                  # @param message [String] the exception message
         
     | 
| 
       46 
70 
     | 
    
         
             
                  # @param exception [Exception] The exception or error
         
     | 
| 
       47 
71 
     | 
    
         
             
                  # @param data [Object] Any structured data
         
     | 
| 
       48 
72 
     | 
    
         
             
                  def build_exception type, message = nil, exception = nil, data = nil
         
     | 
| 
      
 73 
     | 
    
         
            +
                    return unless buildable?
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
       49 
75 
     | 
    
         
             
                    stack_trace = wrapped_caller_locations
         
     | 
| 
       50 
76 
     | 
    
         
             
                    caller_idx = stack_trace&.find_index { |stack| stack.to_s.include?(type) } || 0
         
     | 
| 
       51 
77 
     | 
    
         
             
                    # The caller_stack is the method in which the error occurred, so has to be above this method
         
     | 
| 
         @@ -1,15 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
         
     | 
| 
       2 
2 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            require 'contrast/components/ 
     | 
| 
      
 4 
     | 
    
         
            +
            require 'contrast/components/ruby_component'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            module Contrast
         
     | 
| 
       7 
7 
     | 
    
         
             
              module Utils
         
     | 
| 
       8 
8 
     | 
    
         
             
                # A module that detects whether any job servers attached to
         
     | 
| 
       9 
9 
     | 
    
         
             
                # the application are running
         
     | 
| 
       10 
10 
     | 
    
         
             
                module JobServersRunning
         
     | 
| 
       11 
     | 
    
         
            -
                  extend Contrast::Components::Logger::InstanceMethods
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
11 
     | 
    
         
             
                  class << self
         
     | 
| 
       14 
12 
     | 
    
         
             
                    def job_servers_running?
         
     | 
| 
       15 
13 
     | 
    
         
             
                      sidekiq_running? || rake_running?
         
     | 
| 
         @@ -20,7 +18,6 @@ module Contrast 
     | 
|
| 
       20 
18 
     | 
    
         
             
                    def sidekiq_running?
         
     | 
| 
       21 
19 
     | 
    
         
             
                      return unless defined?(Sidekiq) && Sidekiq.cs__respond_to?(:server?) && Sidekiq.server?
         
     | 
| 
       22 
20 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                      logger.trace('Detected the spawn of a Sidekiq process')
         
     | 
| 
       24 
21 
     | 
    
         
             
                      true
         
     | 
| 
       25 
22 
     | 
    
         
             
                    end
         
     | 
| 
       26 
23 
     | 
    
         | 
| 
         @@ -32,13 +29,18 @@ module Contrast 
     | 
|
| 
       32 
29 
     | 
    
         
             
                        return
         
     | 
| 
       33 
30 
     | 
    
         
             
                      end
         
     | 
| 
       34 
31 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                       
     | 
| 
      
 32 
     | 
    
         
            +
                      # This might be called before component even exist, so we backup to
         
     | 
| 
      
 33 
     | 
    
         
            +
                      # default disabled rake tasks.
         
     | 
| 
      
 34 
     | 
    
         
            +
                      disabled_rake_tasks = if Contrast.const_defined?(:APP_CONTEXT) # rubocop:disable Security/Module/ConstDefined
         
     | 
| 
      
 35 
     | 
    
         
            +
                                              Contrast::APP_CONTEXT.disabled_agent_rake_tasks
         
     | 
| 
      
 36 
     | 
    
         
            +
                                            else
         
     | 
| 
      
 37 
     | 
    
         
            +
                                              Contrast::Components::Ruby::Interface::DISABLED_RAKE_TASK_LIST
         
     | 
| 
      
 38 
     | 
    
         
            +
                                            end
         
     | 
| 
       36 
39 
     | 
    
         
             
                      has_disabled_task = Rake.application.top_level_tasks.any? do |top_level_task|
         
     | 
| 
       37 
40 
     | 
    
         
             
                        disabled_rake_tasks.include?(top_level_task)
         
     | 
| 
       38 
41 
     | 
    
         
             
                      end
         
     | 
| 
       39 
42 
     | 
    
         
             
                      return false unless has_disabled_task
         
     | 
| 
       40 
43 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                      logger.trace('Detected startup within Rake task')
         
     | 
| 
       42 
44 
     | 
    
         
             
                      true
         
     | 
| 
       43 
45 
     | 
    
         
             
                    end
         
     | 
| 
       44 
46 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -51,7 +51,7 @@ module Contrast 
     | 
|
| 
       51 
51 
     | 
    
         
             
                    logger.extend(Contrast::Logger::Application)
         
     | 
| 
       52 
52 
     | 
    
         
             
                    logger.extend(Contrast::Logger::Request)
         
     | 
| 
       53 
53 
     | 
    
         
             
                    logger.extend(Contrast::Logger::Time)
         
     | 
| 
       54 
     | 
    
         
            -
                    logger.extend(Contrast::Logger::AliasedLogging) 
     | 
| 
      
 54 
     | 
    
         
            +
                    logger.extend(Contrast::Logger::AliasedLogging)
         
     | 
| 
       55 
55 
     | 
    
         
             
                  end
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                  # Determine the valid path to which to log, given the precedence of config > settings > default.
         
     | 
| 
         @@ -2,6 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            require 'contrast/config/yaml_file'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'contrast/utils/job_servers_running'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Contrast
         
     | 
| 
       7 
8 
     | 
    
         
             
              module Utils
         
     | 
| 
         @@ -30,6 +31,9 @@ module Contrast 
     | 
|
| 
       30 
31 
     | 
    
         
             
                      logger.error('!!! CONFIG FILE IS INVALID - DISABLING CONTRAST AGENT !!!')
         
     | 
| 
       31 
32 
     | 
    
         
             
                    elsif ::Contrast::AGENT.disabled?
         
     | 
| 
       32 
33 
     | 
    
         
             
                      logger.warn('Contrast disabled by configuration. Continuing without instrumentation.')
         
     | 
| 
      
 34 
     | 
    
         
            +
                    elsif Contrast::Utils::JobServersRunning.job_servers_running?
         
     | 
| 
      
 35 
     | 
    
         
            +
                      logger.info('Server job detected disabling Agent...')
         
     | 
| 
      
 36 
     | 
    
         
            +
                      ::Contrast::AGENT.disable!
         
     | 
| 
       33 
37 
     | 
    
         
             
                    else
         
     | 
| 
       34 
38 
     | 
    
         
             
                      ::Contrast::AGENT.enable!
         
     | 
| 
       35 
39 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -43,7 +43,9 @@ module Contrast 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    logger.debug('Client verified', service: service_name, url: url)
         
     | 
| 
       44 
44 
     | 
    
         
             
                    net_http_client
         
     | 
| 
       45 
45 
     | 
    
         
             
                  rescue StandardError => e
         
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
      
 46 
     | 
    
         
            +
                    # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 47 
     | 
    
         
            +
                    #   an infinite loop w/ telemetry
         
     | 
| 
      
 48 
     | 
    
         
            +
                    logger.debug('Connection failed', e, service: service_name, url: url)
         
     | 
| 
       47 
49 
     | 
    
         
             
                    nil
         
     | 
| 
       48 
50 
     | 
    
         
             
                  end
         
     | 
| 
       49 
51 
     | 
    
         | 
| 
         @@ -72,7 +74,9 @@ module Contrast 
     | 
|
| 
       72 
74 
     | 
    
         
             
                         Errno::ETIMEDOUT, Errno::ESHUTDOWN, Errno::EHOSTDOWN, Errno::EHOSTUNREACH, Errno::EISCONN,
         
     | 
| 
       73 
75 
     | 
    
         
             
                         Errno::ECONNABORTED, Errno::ENETRESET, Errno::ENETUNREACH => e
         
     | 
| 
       74 
76 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
                     
     | 
| 
      
 77 
     | 
    
         
            +
                    # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 78 
     | 
    
         
            +
                    #   an infinite loop w/ telemetry
         
     | 
| 
      
 79 
     | 
    
         
            +
                    logger.debug("#{ service_name } connection failed", e.message)
         
     | 
| 
       76 
80 
     | 
    
         
             
                    false
         
     | 
| 
       77 
81 
     | 
    
         
             
                  end
         
     | 
| 
       78 
82 
     | 
    
         | 
| 
         @@ -110,7 +114,9 @@ module Contrast 
     | 
|
| 
       110 
114 
     | 
    
         
             
                      client.key = OpenSSL::PKey::RSA.new(File.read(Contrast::API.certification_key_file)).to_s
         
     | 
| 
       111 
115 
     | 
    
         
             
                    end
         
     | 
| 
       112 
116 
     | 
    
         
             
                  rescue Errno::ENOENT => e
         
     | 
| 
       113 
     | 
    
         
            -
                     
     | 
| 
      
 117 
     | 
    
         
            +
                    # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
         
     | 
| 
      
 118 
     | 
    
         
            +
                    #   an infinite loop w/ telemetry
         
     | 
| 
      
 119 
     | 
    
         
            +
                    logger.debug('Custom certificates failed', e.message)
         
     | 
| 
       114 
120 
     | 
    
         
             
                  end
         
     | 
| 
       115 
121 
     | 
    
         | 
| 
       116 
122 
     | 
    
         
             
                  # sets default setting for client validation of certificates and
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: contrast-agent
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 6.15. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 6.15.2
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - galen.palmer@contrastsecurity.com
         
     | 
| 
         @@ -13,7 +13,7 @@ authors: 
     | 
|
| 
       13 
13 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       15 
15 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       16 
     | 
    
         
            -
            date: 2023-02- 
     | 
| 
      
 16 
     | 
    
         
            +
            date: 2023-02-22 00:00:00.000000000 Z
         
     | 
| 
       17 
17 
     | 
    
         
             
            dependencies:
         
     | 
| 
       18 
18 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       19 
19 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -678,22 +678,22 @@ email: 
     | 
|
| 
       678 
678 
     | 
    
         
             
            executables: []
         
     | 
| 
       679 
679 
     | 
    
         
             
            extensions:
         
     | 
| 
       680 
680 
     | 
    
         
             
            - ext/cs__common/extconf.rb
         
     | 
| 
       681 
     | 
    
         
            -
            - ext/ 
     | 
| 
       682 
     | 
    
         
            -
            - ext/ 
     | 
| 
      
 681 
     | 
    
         
            +
            - ext/cs__assess_marshal_module/extconf.rb
         
     | 
| 
      
 682 
     | 
    
         
            +
            - ext/cs__assess_yield_track/extconf.rb
         
     | 
| 
      
 683 
     | 
    
         
            +
            - ext/cs__scope/extconf.rb
         
     | 
| 
       683 
684 
     | 
    
         
             
            - ext/cs__assess_kernel/extconf.rb
         
     | 
| 
       684 
     | 
    
         
            -
            - ext/ 
     | 
| 
       685 
     | 
    
         
            -
            - ext/ 
     | 
| 
      
 685 
     | 
    
         
            +
            - ext/cs__assess_array/extconf.rb
         
     | 
| 
      
 686 
     | 
    
         
            +
            - ext/cs__os_information/extconf.rb
         
     | 
| 
       686 
687 
     | 
    
         
             
            - ext/cs__assess_string/extconf.rb
         
     | 
| 
      
 688 
     | 
    
         
            +
            - ext/cs__assess_hash/extconf.rb
         
     | 
| 
       687 
689 
     | 
    
         
             
            - ext/cs__assess_regexp/extconf.rb
         
     | 
| 
       688 
     | 
    
         
            -
            - ext/cs__tests/extconf.rb
         
     | 
| 
       689 
690 
     | 
    
         
             
            - ext/cs__assess_module/extconf.rb
         
     | 
| 
       690 
     | 
    
         
            -
            - ext/ 
     | 
| 
       691 
     | 
    
         
            -
            - ext/ 
     | 
| 
       692 
     | 
    
         
            -
            - ext/cs__scope/extconf.rb
         
     | 
| 
      
 691 
     | 
    
         
            +
            - ext/cs__assess_string_interpolation/extconf.rb
         
     | 
| 
      
 692 
     | 
    
         
            +
            - ext/cs__tests/extconf.rb
         
     | 
| 
       693 
693 
     | 
    
         
             
            - ext/cs__assess_test/extconf.rb
         
     | 
| 
       694 
     | 
    
         
            -
            - ext/ 
     | 
| 
       695 
     | 
    
         
            -
            - ext/ 
     | 
| 
       696 
     | 
    
         
            -
            - ext/ 
     | 
| 
      
 694 
     | 
    
         
            +
            - ext/cs__assess_fiber_track/extconf.rb
         
     | 
| 
      
 695 
     | 
    
         
            +
            - ext/cs__assess_basic_object/extconf.rb
         
     | 
| 
      
 696 
     | 
    
         
            +
            - ext/cs__contrast_patch/extconf.rb
         
     | 
| 
       697 
697 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       698 
698 
     | 
    
         
             
            files:
         
     | 
| 
       699 
699 
     | 
    
         
             
            - ".clang-format"
         
     |