contrast-agent 4.6.0 → 4.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +6 -1
- data/.gitmodules +1 -1
- data/.simplecov +1 -0
- data/Rakefile +1 -2
- data/ext/build_funchook.rb +3 -3
- data/ext/extconf_common.rb +1 -5
- data/lib/contrast.rb +24 -14
- data/lib/contrast/agent/assess.rb +1 -1
- data/lib/contrast/agent/assess/contrast_event.rb +1 -4
- data/lib/contrast/agent/assess/contrast_object.rb +2 -2
- data/lib/contrast/agent/assess/events/event_factory.rb +2 -1
- data/lib/contrast/agent/assess/finalizers/hash.rb +2 -4
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +6 -3
- data/lib/contrast/agent/assess/policy/patcher.rb +16 -21
- data/lib/contrast/agent/assess/policy/policy.rb +1 -1
- data/lib/contrast/agent/assess/policy/policy_node.rb +25 -33
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +3 -5
- data/lib/contrast/agent/assess/policy/preshift.rb +7 -5
- data/lib/contrast/agent/assess/policy/propagation_method.rb +10 -19
- data/lib/contrast/agent/assess/policy/propagation_node.rb +19 -8
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
- data/lib/contrast/agent/assess/policy/propagator/center.rb +2 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +3 -6
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +3 -1
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -1
- data/lib/contrast/agent/assess/policy/propagator/rack_protection.rb +73 -0
- data/lib/contrast/agent/assess/policy/propagator/select.rb +2 -12
- data/lib/contrast/agent/assess/policy/propagator/split.rb +12 -13
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +3 -10
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -15
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +13 -10
- data/lib/contrast/agent/assess/policy/source_method.rb +12 -12
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -3
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +5 -1
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +0 -3
- data/lib/contrast/agent/assess/policy/trigger_method.rb +8 -18
- data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -2
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +4 -3
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +1 -2
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +1 -8
- data/lib/contrast/agent/assess/property/evented.rb +8 -5
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +11 -5
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +4 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +7 -9
- data/lib/contrast/agent/at_exit_hook.rb +3 -3
- data/lib/contrast/agent/class_reopener.rb +9 -6
- data/lib/contrast/agent/disable_reaction.rb +4 -7
- data/lib/contrast/agent/exclusion_matcher.rb +7 -14
- data/lib/contrast/agent/inventory/dependencies.rb +2 -0
- data/lib/contrast/agent/inventory/dependency_analysis.rb +2 -6
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +3 -5
- data/lib/contrast/agent/inventory/policy/datastores.rb +3 -4
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/middleware.rb +17 -18
- data/lib/contrast/agent/module_data.rb +3 -3
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +3 -3
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +9 -9
- data/lib/contrast/agent/patching/policy/method_policy.rb +6 -2
- data/lib/contrast/agent/patching/policy/module_policy.rb +14 -7
- data/lib/contrast/agent/patching/policy/patch.rb +20 -25
- data/lib/contrast/agent/patching/policy/patch_status.rb +6 -7
- data/lib/contrast/agent/patching/policy/patcher.rb +21 -18
- data/lib/contrast/agent/patching/policy/policy.rb +2 -4
- data/lib/contrast/agent/patching/policy/policy_node.rb +16 -7
- data/lib/contrast/agent/patching/policy/trigger_node.rb +21 -8
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +2 -3
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +5 -9
- data/lib/contrast/agent/protect/policy/policy.rb +1 -1
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +7 -9
- data/lib/contrast/agent/protect/rule/base.rb +20 -23
- data/lib/contrast/agent/protect/rule/base_service.rb +9 -5
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +18 -23
- data/lib/contrast/agent/protect/rule/deserialization.rb +6 -13
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +3 -14
- data/lib/contrast/agent/protect/rule/no_sqli.rb +6 -2
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -3
- data/lib/contrast/agent/protect/rule/path_traversal.rb +6 -10
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
- data/lib/contrast/agent/protect/rule/xss.rb +1 -1
- data/lib/contrast/agent/protect/rule/xxe.rb +5 -12
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +1 -2
- data/lib/contrast/agent/reaction_processor.rb +13 -13
- data/lib/contrast/agent/request.rb +27 -26
- data/lib/contrast/agent/request_context.rb +17 -22
- data/lib/contrast/agent/request_handler.rb +5 -3
- data/lib/contrast/agent/response.rb +2 -3
- data/lib/contrast/agent/rewriter.rb +9 -6
- data/lib/contrast/agent/rule_set.rb +5 -4
- data/lib/contrast/agent/service_heartbeat.rb +4 -6
- data/lib/contrast/agent/static_analysis.rb +6 -5
- data/lib/contrast/agent/thread.rb +2 -4
- data/lib/contrast/agent/thread_watcher.rb +3 -4
- data/lib/contrast/agent/tracepoint_hook.rb +5 -5
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +4 -5
- data/lib/contrast/api/communication/response_processor.rb +11 -13
- data/lib/contrast/api/communication/service_lifecycle.rb +9 -6
- data/lib/contrast/api/communication/socket_client.rb +22 -31
- data/lib/contrast/api/communication/speedracer.rb +8 -13
- data/lib/contrast/api/decorators/address.rb +2 -3
- data/lib/contrast/api/decorators/agent_startup.rb +7 -9
- data/lib/contrast/api/decorators/application_startup.rb +12 -10
- data/lib/contrast/api/decorators/application_update.rb +0 -4
- data/lib/contrast/api/decorators/http_request.rb +3 -7
- data/lib/contrast/api/decorators/instrumentation_mode.rb +3 -5
- data/lib/contrast/api/decorators/library.rb +8 -6
- data/lib/contrast/api/decorators/message.rb +9 -9
- data/lib/contrast/api/decorators/trace_event.rb +3 -1
- data/lib/contrast/api/decorators/trace_event_object.rb +3 -6
- data/lib/contrast/api/decorators/trace_taint_range_tags.rb +1 -6
- data/lib/contrast/components/agent.rb +17 -17
- data/lib/contrast/components/app_context.rb +11 -15
- data/lib/contrast/components/assess.rb +16 -16
- data/lib/contrast/components/base.rb +40 -0
- data/lib/contrast/components/config.rb +2 -3
- data/lib/contrast/components/contrast_service.rb +12 -18
- data/lib/contrast/components/heap_dump.rb +5 -4
- data/lib/contrast/components/inventory.rb +2 -7
- data/lib/contrast/components/logger.rb +1 -2
- data/lib/contrast/components/protect.rb +10 -13
- data/lib/contrast/components/sampling.rb +13 -7
- data/lib/contrast/components/scope.rb +0 -4
- data/lib/contrast/components/settings.rb +5 -7
- data/lib/contrast/config/assess_rules_configuration.rb +1 -3
- data/lib/contrast/config/base_configuration.rb +4 -5
- data/lib/contrast/config/exception_configuration.rb +1 -5
- data/lib/contrast/config/heap_dump_configuration.rb +12 -6
- data/lib/contrast/config/logger_configuration.rb +1 -5
- data/lib/contrast/configuration.rb +6 -18
- data/lib/contrast/extension/assess/array.rb +3 -10
- data/lib/contrast/extension/assess/erb.rb +1 -7
- data/lib/contrast/extension/assess/eval_trigger.rb +4 -9
- data/lib/contrast/extension/assess/exec_trigger.rb +3 -9
- data/lib/contrast/extension/assess/fiber.rb +8 -17
- data/lib/contrast/extension/assess/hash.rb +3 -3
- data/lib/contrast/extension/assess/kernel.rb +4 -13
- data/lib/contrast/extension/assess/marshal.rb +6 -10
- data/lib/contrast/extension/assess/regexp.rb +6 -10
- data/lib/contrast/extension/assess/string.rb +8 -6
- data/lib/contrast/extension/kernel.rb +2 -2
- data/lib/contrast/extension/protect/kernel.rb +0 -5
- data/lib/contrast/framework/manager.rb +3 -5
- data/lib/contrast/framework/rack/patch/session_cookie.rb +11 -24
- data/lib/contrast/framework/rack/patch/support.rb +6 -4
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +12 -9
- data/lib/contrast/framework/rails/patch/support.rb +41 -35
- data/lib/contrast/framework/rails/railtie.rb +34 -0
- data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +4 -1
- data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +2 -0
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +5 -4
- data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +2 -0
- data/lib/contrast/framework/rails/support.rb +2 -2
- data/lib/contrast/framework/sinatra/support.rb +3 -1
- data/lib/contrast/funchook/funchook.rb +5 -8
- data/lib/contrast/logger/application.rb +13 -15
- data/lib/contrast/logger/format.rb +2 -5
- data/lib/contrast/logger/log.rb +26 -9
- data/lib/contrast/logger/request.rb +1 -6
- data/lib/contrast/security_exception.rb +1 -1
- data/lib/contrast/tasks/config.rb +0 -1
- data/lib/contrast/tasks/service.rb +6 -7
- data/lib/contrast/utils/assess/sampling_util.rb +2 -3
- data/lib/contrast/utils/assess/tracking_util.rb +3 -6
- data/lib/contrast/utils/class_util.rb +0 -8
- data/lib/contrast/utils/hash_digest.rb +2 -5
- data/lib/contrast/utils/heap_dump_util.rb +5 -3
- data/lib/contrast/utils/invalid_configuration_util.rb +4 -3
- data/lib/contrast/utils/inventory_util.rb +2 -3
- data/lib/contrast/utils/io_util.rb +3 -5
- data/lib/contrast/utils/job_servers_running.rb +13 -7
- data/lib/contrast/utils/os.rb +4 -4
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -1
- data/lib/contrast/utils/string_utils.rb +2 -3
- data/lib/contrast/utils/tag_util.rb +25 -19
- data/resources/assess/policy.json +55 -0
- data/ruby-agent.gemspec +17 -16
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- data/sonar-project.properties +9 -0
- metadata +61 -46
- data/lib/contrast/agent/railtie.rb +0 -31
- data/lib/contrast/components/interface.rb +0 -195
- data/lib/contrast/delegators/input_analysis.rb +0 -12
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/utils/job_servers_running'
|
5
|
+
require 'contrast/components/logger'
|
6
|
+
|
7
|
+
module Contrast
|
8
|
+
module Framework
|
9
|
+
module Rails
|
10
|
+
# A Railtie to allow for the automatic hooking of the Agent into a Rails application.
|
11
|
+
class Railtie < ::Rails::Railtie
|
12
|
+
include Contrast::Components::Logger::InstanceMethods
|
13
|
+
|
14
|
+
initializer 'Contrast Ruby Agent Initializer' do |app|
|
15
|
+
log_rails = defined?(Rails) && defined?(Rails.logger)
|
16
|
+
|
17
|
+
Rails.logger.debug("In railtie ::#{ app.middleware.inspect }") if log_rails
|
18
|
+
|
19
|
+
if ::Contrast::APP_CONTEXT.instrument_middleware_stack?
|
20
|
+
::Contrast::AGENT.insert_middleware(app)
|
21
|
+
else
|
22
|
+
Rails.logger.debug('Detected a running job server, skipping Contrast middleware insertion.') if log_rails
|
23
|
+
logger.debug('Disabling Contrast for process', p_id: Process.pid)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
rake_tasks do
|
28
|
+
load 'contrast/tasks/service.rb'
|
29
|
+
load 'contrast/tasks/config.rb'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
return unless RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
5
|
+
|
4
6
|
module Contrast
|
5
7
|
module Framework
|
6
8
|
module Rails
|
@@ -19,7 +21,8 @@ module Contrast
|
|
19
21
|
alias_method :cs__patched_helper_inherited, :inherited
|
20
22
|
def inherited klass # rubocop:disable Lint/MissingSuper
|
21
23
|
klass&.instance_variable_set(:@cs__defining_class, true)
|
22
|
-
|
24
|
+
# This calls the original inherited, which should handle super as needed.
|
25
|
+
cs__patched_helper_inherited(klass)
|
23
26
|
ensure
|
24
27
|
klass&.instance_variable_set(:@cs__defining_class, false)
|
25
28
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
return unless RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
5
|
+
|
4
6
|
module Contrast
|
5
7
|
module Framework
|
6
8
|
module Rails
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
return unless RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
5
|
+
|
6
|
+
require 'contrast/components/logger'
|
5
7
|
|
6
8
|
module Contrast
|
7
9
|
module Framework
|
@@ -15,12 +17,11 @@ module Contrast
|
|
15
17
|
# @deprecated Changes to this class are discouraged as this approach is
|
16
18
|
# being phased out with support for those language versions.
|
17
19
|
class ActiveRecordNamed
|
18
|
-
include Contrast::Components::
|
19
|
-
access_component :agent, :logging
|
20
|
+
include Contrast::Components::Logger::InstanceMethods
|
20
21
|
|
21
22
|
class << self
|
22
23
|
def rewrite mod, method_name, body
|
23
|
-
return body unless AGENT.rewrite_interpolation?
|
24
|
+
return body unless ::Contrast::AGENT.rewrite_interpolation?
|
24
25
|
return body unless body.is_a?(Proc)
|
25
26
|
|
26
27
|
location = body.source_location
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
return unless RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
5
|
+
|
4
6
|
module Contrast
|
5
7
|
module Framework
|
6
8
|
module Rails
|
@@ -27,8 +27,8 @@ module Contrast
|
|
27
27
|
|
28
28
|
def application_name
|
29
29
|
app_class = ::Rails.application.cs__class
|
30
|
-
# Rails version 6.0.0 deprecated Rails::Application#parent_name, in Rails 6.1.0 that method will be removed
|
31
|
-
# and instead we need to use parent_module_name
|
30
|
+
# Rails version 6.0.0 deprecated Rails::Application#parent_name, in Rails 6.1.0 that method will be removed
|
31
|
+
# entirely and instead we need to use parent_module_name
|
32
32
|
return app_class.parent_module_name if Gem::Version.new(::Rails.version) >= RAILS_MODULE_NAME_VERSION
|
33
33
|
|
34
34
|
app_class.parent_name
|
@@ -114,7 +114,9 @@ module Contrast
|
|
114
114
|
return controller, route_pattern if route_pattern
|
115
115
|
|
116
116
|
# Check routes defined in superclass if present.
|
117
|
-
return
|
117
|
+
return unless controller.superclass&.instance_variable_get(:@routes)
|
118
|
+
|
119
|
+
_route_recurse(controller.superclass, method, route)
|
118
120
|
end
|
119
121
|
|
120
122
|
# Get route and do some cleanup matching that of Sinatra::Base#process_route.
|
@@ -1,22 +1,19 @@
|
|
1
1
|
# Copyright (c) 2021 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/logger'
|
5
|
+
|
5
6
|
# This module is used to find funchook library and determine availability
|
6
7
|
module Funchook
|
7
|
-
|
8
|
-
|
8
|
+
extend Contrast::Components::Logger::InstanceMethods
|
9
|
+
|
9
10
|
attr_accessor :path
|
10
11
|
|
11
12
|
# Possible platform library files
|
12
13
|
ACCEPTABLE_FILES = %w[libfunchook.dylib libfunchook.so].cs__freeze
|
13
14
|
|
14
15
|
# Top level agent directories that should have the funchook libraries
|
15
|
-
SEARCH_DIRS = [
|
16
|
-
File.join('ext'),
|
17
|
-
File.join('shared_libraries'),
|
18
|
-
File.join('funchook', 'src')
|
19
|
-
].cs__freeze
|
16
|
+
SEARCH_DIRS = [File.join('ext'), File.join('shared_libraries'), File.join('funchook', 'src')].cs__freeze
|
20
17
|
|
21
18
|
AGENT_ROOT = File.join(__dir__, '..', '..', '..')
|
22
19
|
|
@@ -1,25 +1,18 @@
|
|
1
1
|
# Copyright (c) 2021 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/interface'
|
5
|
-
|
6
4
|
module Contrast
|
7
5
|
module Logger
|
8
6
|
# Our decorator for the Ougai logger allowing for the logging of the
|
9
7
|
# application environment, used to provide context during troubleshooting.
|
10
8
|
module Application
|
11
|
-
include Contrast::Components::Interface
|
12
|
-
access_component :config
|
13
|
-
|
14
9
|
ENV_KEYS = %w[HOME PWD RACK_ENV RAILS_ENV RUBY_VERSION GEM_HOME GEM_PATH].cs__freeze
|
15
10
|
# Utility method to log some current ruby and rails information from environment
|
16
11
|
def application_environment
|
17
12
|
return unless info?
|
18
13
|
|
19
|
-
info('Process environment information',
|
20
|
-
|
21
|
-
pp_id: Process.ppid,
|
22
|
-
agent_version: Contrast::Agent::VERSION)
|
14
|
+
info('Process environment information', p_id: Process.pid, pp_id: Process.ppid,
|
15
|
+
agent_version: Contrast::Agent::VERSION)
|
23
16
|
ENV.each do |env_key, env_value|
|
24
17
|
env_key = env_key.to_s
|
25
18
|
next unless ENV_KEYS.include?(env_key) ||
|
@@ -33,9 +26,11 @@ module Contrast
|
|
33
26
|
def application_configuration
|
34
27
|
return unless info?
|
35
28
|
|
36
|
-
loggable = CONFIG.loggable
|
29
|
+
loggable = ::Contrast::CONFIG.loggable
|
37
30
|
info('Current configuration', configuration: loggable)
|
38
|
-
env_keys = ENV.keys.select
|
31
|
+
env_keys = ENV.keys.select do |env_key|
|
32
|
+
env_key&.to_s&.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER)
|
33
|
+
end
|
39
34
|
env_items = env_keys.map { |env_key| Contrast::Utils::EnvConfigurationItem.new(env_key, nil) }
|
40
35
|
env_translations = env_items.each_with_object({}) do |conversion, hash|
|
41
36
|
hash[conversion.key] = conversion.dot_path_array.join('.')
|
@@ -52,7 +47,10 @@ module Contrast
|
|
52
47
|
end
|
53
48
|
|
54
49
|
FRAMEWORKS = %w[rails sinatra grape].cs__freeze
|
55
|
-
WEB_SERVERS = %w[
|
50
|
+
WEB_SERVERS = %w[
|
51
|
+
agoo falcon hoof iodine mongrel mongrel2 passenger puma rack skinny thin trinidad unicorn
|
52
|
+
webrick yarn
|
53
|
+
].cs__freeze
|
56
54
|
LIBRARIES = %w[excon json mongo moped mysql nokogiri oga ox pg psych sqlite3 typhoeus yaml].cs__freeze
|
57
55
|
def log_specific_libraries
|
58
56
|
FRAMEWORKS.each(&cs__method(:log_gem_data))
|
@@ -67,6 +65,7 @@ module Contrast
|
|
67
65
|
|
68
66
|
Gem.loaded_specs.each_pair do |_name, gem_spec|
|
69
67
|
debug('Gem loaded',
|
68
|
+
# rubocop:disable Security/Module/Name -- gems builtin.
|
70
69
|
gem_name: gem_spec.name,
|
71
70
|
gem_version: gem_spec.version.to_s)
|
72
71
|
end
|
@@ -76,9 +75,8 @@ module Contrast
|
|
76
75
|
gem_spec = Gem.loaded_specs[gem_name]
|
77
76
|
return unless gem_spec
|
78
77
|
|
79
|
-
info('Gem loaded',
|
80
|
-
|
81
|
-
gem_version: gem_spec.version.to_s)
|
78
|
+
info('Gem loaded', gem_name: gem_spec.name, gem_version: gem_spec.version.to_s)
|
79
|
+
# rubocop:enable Security/Module/Name
|
82
80
|
end
|
83
81
|
end
|
84
82
|
end
|
@@ -43,9 +43,7 @@ module Contrast
|
|
43
43
|
def thread_hash
|
44
44
|
hash = LOG_TRACKER.get(:logging_hash)
|
45
45
|
unless hash
|
46
|
-
hash = {
|
47
|
-
thread_id: Thread.current.object_id
|
48
|
-
}
|
46
|
+
hash = { thread_id: Thread.current.object_id }
|
49
47
|
LOG_TRACKER.set(:logging_hash, hash)
|
50
48
|
end
|
51
49
|
hash
|
@@ -53,8 +51,7 @@ module Contrast
|
|
53
51
|
|
54
52
|
NO_REQUEST_HASH = { request_id: -1 }.cs__freeze
|
55
53
|
def request_hash
|
56
|
-
@request_tracker_defined ||= defined?(Contrast::Agent) &&
|
57
|
-
defined?(Contrast::Agent::REQUEST_TRACKER)
|
54
|
+
@request_tracker_defined ||= defined?(Contrast::Agent) && defined?(Contrast::Agent::REQUEST_TRACKER)
|
58
55
|
return NO_REQUEST_HASH unless @request_tracker_defined
|
59
56
|
|
60
57
|
Contrast::Agent::REQUEST_TRACKER&.current&.logging_hash || NO_REQUEST_HASH
|
data/lib/contrast/logger/log.rb
CHANGED
@@ -5,21 +5,37 @@ require 'logger'
|
|
5
5
|
require 'ougai'
|
6
6
|
require 'singleton'
|
7
7
|
|
8
|
-
require 'contrast/components/interface'
|
9
8
|
require 'contrast/extension/module'
|
10
9
|
require 'contrast/logger/application'
|
11
10
|
require 'contrast/logger/format'
|
12
11
|
require 'contrast/logger/request'
|
13
12
|
require 'contrast/logger/time'
|
13
|
+
require 'contrast/components/config'
|
14
14
|
|
15
15
|
module Contrast
|
16
16
|
module Logger
|
17
|
+
# For development set following env var to raise logged exceptions instead of just logging.
|
18
|
+
if ENV['CONTRAST__AGENT__RUBY_MORE_COWBELL']
|
19
|
+
Ougai::Logger.class_eval do
|
20
|
+
alias_method :cs__error, :error
|
21
|
+
alias_method :cs__warn, :warn
|
22
|
+
|
23
|
+
def error msg, exc, **kwargs
|
24
|
+
cs__error(msg, exc, **kwargs)
|
25
|
+
raise exc if exc && exc.cs__class < Exception
|
26
|
+
end
|
27
|
+
|
28
|
+
def warn msg, exc, **kwargs
|
29
|
+
cs__warn(msg, exc, **kwargs)
|
30
|
+
raise exc if exc && exc.cs__class < Exception
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
17
35
|
# This class functions to serve as a wrapper around our logging, as we need
|
18
36
|
# to be able to dynamically update level based on updates to TeamServer.
|
19
37
|
class Log
|
20
38
|
include Singleton
|
21
|
-
include Contrast::Components::Interface
|
22
|
-
access_component :config
|
23
39
|
|
24
40
|
DEFAULT_NAME = 'contrast.log'
|
25
41
|
DEFAULT_LEVEL = ::Ougai::Logging::Severity::INFO
|
@@ -27,8 +43,7 @@ module Contrast
|
|
27
43
|
STDOUT_STR = 'STDOUT'
|
28
44
|
STDERR_STR = 'STDERR'
|
29
45
|
|
30
|
-
attr_reader :previous_path,
|
31
|
-
:previous_level
|
46
|
+
attr_reader :previous_path, :previous_level
|
32
47
|
|
33
48
|
def initialize
|
34
49
|
update
|
@@ -108,8 +123,8 @@ module Contrast
|
|
108
123
|
# TeamServer.
|
109
124
|
# @return [String] the path to which to log or STDOUT / STDERR if one of those values provided.
|
110
125
|
def find_valid_path log_file
|
111
|
-
config = CONFIG.root.agent.logger
|
112
|
-
config_path = config
|
126
|
+
config = ::Contrast::CONFIG.root.agent.logger
|
127
|
+
config_path = config&.path&.length.to_i.positive? ? config.path : nil
|
113
128
|
valid_path(config_path || log_file)
|
114
129
|
end
|
115
130
|
|
@@ -124,7 +139,9 @@ module Contrast
|
|
124
139
|
elsif write_permission?(DEFAULT_NAME)
|
125
140
|
# Log once when the path is invalid. We'll change to this path, so no
|
126
141
|
# need to log again.
|
127
|
-
|
142
|
+
if previous_path != DEFAULT_NAME
|
143
|
+
puts "[!] Unable to write to '#{ path }'. Writing to default log '#{ DEFAULT_NAME }' instead."
|
144
|
+
end
|
128
145
|
DEFAULT_NAME
|
129
146
|
else
|
130
147
|
# Log once when the path is invalid. We'll change to this path, so no
|
@@ -140,7 +157,7 @@ module Contrast
|
|
140
157
|
# TeamServer.
|
141
158
|
# @return [::Ougai::Logging::Severity] the level at which to log
|
142
159
|
def find_valid_level log_level
|
143
|
-
config = CONFIG.root.agent.logger
|
160
|
+
config = ::Contrast::CONFIG.root.agent.logger
|
144
161
|
config_level = config.level&.length&.positive? ? config.level : nil
|
145
162
|
valid_level(config_level || log_level)
|
146
163
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Copyright (c) 2021 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/interface'
|
5
4
|
require 'contrast/utils/timer'
|
6
5
|
|
7
6
|
module Contrast
|
@@ -9,9 +8,6 @@ module Contrast
|
|
9
8
|
# Our decorator for the Ougai logger allowing for the logging of the
|
10
9
|
# request lifecycle, used to provide context during troubleshooting.
|
11
10
|
module Request
|
12
|
-
include Contrast::Components::Interface
|
13
|
-
access_component :config
|
14
|
-
|
15
11
|
# Utility method to log the start of a request
|
16
12
|
def request_start
|
17
13
|
debug('Beginning request analysis')
|
@@ -22,8 +18,7 @@ module Contrast
|
|
22
18
|
def request_end
|
23
19
|
context = Contrast::Agent::REQUEST_TRACKER.current
|
24
20
|
elapsed_time = context ? (Contrast::Utils::Timer.now_ms - context.timer.start_ms) : -1
|
25
|
-
debug('Ending request analysis',
|
26
|
-
elapsed_time_ms: elapsed_time)
|
21
|
+
debug('Ending request analysis', elapsed_time_ms: elapsed_time)
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -8,7 +8,7 @@ module Contrast
|
|
8
8
|
# to be handled by our customer's applications.
|
9
9
|
class SecurityException < StandardError
|
10
10
|
def initialize rule, message = nil
|
11
|
-
super(message || "Rule #{ rule.
|
11
|
+
super(message || "Rule #{ rule.rule_name } threw a security exception")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -7,7 +7,6 @@ module Contrast
|
|
7
7
|
# A Rake task to generate a contrast_security.yaml file with some basic settings
|
8
8
|
module Config
|
9
9
|
extend Rake::DSL
|
10
|
-
include Contrast::Components::Interface
|
11
10
|
DEFAULT_CONFIG = {
|
12
11
|
'api' => {
|
13
12
|
'url' => 'Enter your Contrast URL ex: https://app.contrastsecurity.com/Contrast',
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Copyright (c) 2021 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/interface'
|
5
4
|
require 'contrast/utils/os'
|
6
5
|
|
7
6
|
module Contrast
|
@@ -10,14 +9,10 @@ module Contrast
|
|
10
9
|
# forked from the application
|
11
10
|
module Service
|
12
11
|
extend Rake::DSL
|
13
|
-
include Contrast::Components::Interface
|
14
|
-
|
15
|
-
access_component :contrast_service
|
16
|
-
|
17
12
|
# Start the service if it is not already running
|
18
13
|
def self.start_service
|
19
14
|
puts 'Starting Contrast Service'
|
20
|
-
service_log = CONTRAST_SERVICE.logger_path
|
15
|
+
service_log = ::Contrast::CONTRAST_SERVICE.logger_path
|
21
16
|
if File.writable?(service_log)
|
22
17
|
spawn('contrast_service', out: File::NULL, err: service_log)
|
23
18
|
else
|
@@ -74,7 +69,11 @@ module Contrast
|
|
74
69
|
sleep(0.05) while Contrast::Utils::OS.running?
|
75
70
|
end
|
76
71
|
watcher.join(1)
|
77
|
-
|
72
|
+
if Contrast::Utils::OS.running?
|
73
|
+
puts 'Contrast Service did not stop.'
|
74
|
+
else
|
75
|
+
puts 'Contrast Service stopped successfully.'
|
76
|
+
end
|
78
77
|
else
|
79
78
|
puts 'Contrast Service is not already running. No need to stop.'
|
80
79
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'singleton'
|
5
|
-
require 'contrast/components/
|
5
|
+
require 'contrast/components/sampling'
|
6
6
|
|
7
7
|
module Contrast
|
8
8
|
module Utils
|
@@ -11,8 +11,7 @@ module Contrast
|
|
11
11
|
class SamplingUtil
|
12
12
|
include Singleton
|
13
13
|
|
14
|
-
|
15
|
-
access_component :sampling
|
14
|
+
extend Contrast::Components::Sampling::InstanceMethods
|
16
15
|
|
17
16
|
def initialize
|
18
17
|
@requests = {}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/assess/tracker'
|
5
|
-
require 'contrast/components/
|
5
|
+
require 'contrast/components/logger'
|
6
6
|
require 'contrast/utils/duck_utils'
|
7
7
|
|
8
8
|
module Contrast
|
@@ -10,9 +10,7 @@ module Contrast
|
|
10
10
|
module Assess
|
11
11
|
# TrackingUtil has methods for determining if a object is being tracked
|
12
12
|
class TrackingUtil
|
13
|
-
|
14
|
-
|
15
|
-
access_component :logging
|
13
|
+
extend Contrast::Components::Logger::InstanceMethods
|
16
14
|
|
17
15
|
class << self
|
18
16
|
# Public interface to our tracking check, isolating the internals
|
@@ -53,8 +51,7 @@ module Contrast
|
|
53
51
|
idx += 1
|
54
52
|
if Contrast::Utils::DuckUtils.iterable_hash?(obj)
|
55
53
|
obj.each_pair do |k, v|
|
56
|
-
return true if _tracked?(k, idx)
|
57
|
-
return true if _tracked?(v, idx)
|
54
|
+
return true if _tracked?(k, idx) || _tracked?(v, idx)
|
58
55
|
end
|
59
56
|
false
|
60
57
|
elsif Contrast::Utils::DuckUtils.iterable_enumerable?(obj)
|