contrast-agent 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +1 -1
- data/Rakefile +1 -2
- data/ext/build_funchook.rb +3 -3
- data/ext/extconf_common.rb +1 -5
- data/lib/contrast/agent/assess.rb +1 -1
- 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/policy/dynamic_source_factory.rb +6 -3
- data/lib/contrast/agent/assess/policy/patcher.rb +10 -17
- data/lib/contrast/agent/assess/policy/policy_node.rb +25 -33
- data/lib/contrast/agent/assess/policy/preshift.rb +3 -1
- data/lib/contrast/agent/assess/policy/propagation_method.rb +6 -15
- data/lib/contrast/agent/assess/policy/propagation_node.rb +19 -8
- data/lib/contrast/agent/assess/policy/propagator/center.rb +2 -1
- 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/select.rb +2 -12
- data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -7
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -7
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -15
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +6 -3
- data/lib/contrast/agent/assess/policy/source_method.rb +6 -6
- 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_method.rb +6 -15
- data/lib/contrast/agent/assess/policy/trigger_node.rb +2 -1
- 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 +3 -5
- data/lib/contrast/agent/class_reopener.rb +3 -1
- data/lib/contrast/agent/disable_reaction.rb +1 -3
- data/lib/contrast/agent/exclusion_matcher.rb +5 -11
- data/lib/contrast/agent/inventory/dependencies.rb +2 -0
- data/lib/contrast/agent/middleware.rb +3 -5
- data/lib/contrast/agent/module_data.rb +3 -3
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +6 -5
- 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 +11 -16
- data/lib/contrast/agent/patching/policy/patch_status.rb +6 -7
- data/lib/contrast/agent/patching/policy/patcher.rb +15 -12
- data/lib/contrast/agent/patching/policy/policy_node.rb +14 -4
- 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/rule_applicator.rb +5 -5
- data/lib/contrast/agent/protect/rule/base.rb +13 -16
- data/lib/contrast/agent/protect/rule/base_service.rb +9 -5
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +14 -18
- 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 +5 -5
- 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 +11 -10
- data/lib/contrast/agent/request.rb +23 -23
- data/lib/contrast/agent/request_context.rb +9 -14
- data/lib/contrast/agent/rewriter.rb +5 -3
- data/lib/contrast/agent/service_heartbeat.rb +2 -3
- data/lib/contrast/agent/tracepoint_hook.rb +1 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/response_processor.rb +2 -4
- data/lib/contrast/api/communication/service_lifecycle.rb +4 -2
- data/lib/contrast/api/communication/socket_client.rb +8 -21
- data/lib/contrast/api/communication/speedracer.rb +3 -7
- data/lib/contrast/api/decorators/application_startup.rb +6 -2
- data/lib/contrast/api/decorators/library.rb +8 -6
- data/lib/contrast/api/decorators/message.rb +3 -3
- data/lib/contrast/api/decorators/trace_event.rb +3 -1
- data/lib/contrast/api/decorators/trace_event_object.rb +1 -3
- data/lib/contrast/api/decorators/trace_taint_range_tags.rb +1 -6
- data/lib/contrast/components/agent.rb +9 -4
- data/lib/contrast/components/app_context.rb +6 -6
- data/lib/contrast/components/config.rb +2 -1
- data/lib/contrast/components/contrast_service.rb +7 -8
- data/lib/contrast/components/interface.rb +3 -2
- data/lib/contrast/components/sampling.rb +8 -2
- data/lib/contrast/components/settings.rb +4 -2
- 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 +3 -14
- data/lib/contrast/extension/assess/array.rb +1 -6
- data/lib/contrast/extension/assess/erb.rb +1 -7
- data/lib/contrast/extension/assess/eval_trigger.rb +2 -6
- data/lib/contrast/extension/assess/exec_trigger.rb +3 -9
- data/lib/contrast/extension/assess/fiber.rb +2 -12
- data/lib/contrast/extension/assess/kernel.rb +2 -9
- data/lib/contrast/extension/assess/marshal.rb +2 -6
- data/lib/contrast/extension/assess/regexp.rb +1 -6
- data/lib/contrast/extension/assess/string.rb +3 -1
- data/lib/contrast/extension/kernel.rb +4 -2
- data/lib/contrast/framework/manager.rb +1 -2
- data/lib/contrast/framework/rack/patch/session_cookie.rb +5 -18
- data/lib/contrast/framework/rack/patch/support.rb +6 -4
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +7 -2
- data/lib/contrast/framework/rails/patch/support.rb +4 -2
- 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 +2 -0
- 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 +1 -5
- data/lib/contrast/logger/application.rb +12 -9
- data/lib/contrast/logger/format.rb +2 -5
- data/lib/contrast/logger/log.rb +4 -3
- data/lib/contrast/logger/request.rb +1 -2
- data/lib/contrast/security_exception.rb +1 -1
- data/lib/contrast/tasks/service.rb +5 -1
- data/lib/contrast/utils/assess/tracking_util.rb +1 -2
- data/lib/contrast/utils/class_util.rb +0 -8
- data/lib/contrast/utils/hash_digest.rb +2 -5
- data/lib/contrast/utils/io_util.rb +1 -1
- data/lib/contrast/utils/job_servers_running.rb +9 -4
- data/lib/contrast/utils/os.rb +2 -1
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -1
- data/ruby-agent.gemspec +13 -14
- data/sonar-project.properties +9 -0
- metadata +37 -36
@@ -31,12 +31,8 @@ module Contrast
|
|
31
31
|
# source might not be all the args passed in, but it is the one we care
|
32
32
|
# about. we could pass in all the args in the last param here if it
|
33
33
|
# becomes an issue in rendering on TS
|
34
|
-
Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(
|
35
|
-
|
36
|
-
source,
|
37
|
-
self,
|
38
|
-
ret,
|
39
|
-
*args)
|
34
|
+
Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(trigger_node('Marshal', :load), source,
|
35
|
+
self, ret, *args)
|
40
36
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties!(ret))
|
41
37
|
|
42
38
|
properties.copy_from(source, ret)
|
@@ -53,12 +53,7 @@ module Contrast
|
|
53
53
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))
|
54
54
|
|
55
55
|
properties.splat_from(string, target)
|
56
|
-
properties.build_event(
|
57
|
-
REGEXP_EQUAL_SQUIGGLE_NODE,
|
58
|
-
target,
|
59
|
-
self,
|
60
|
-
result,
|
61
|
-
[string])
|
56
|
+
properties.build_event(REGEXP_EQUAL_SQUIGGLE_NODE, target, self, result, [string])
|
62
57
|
end
|
63
58
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
64
59
|
logger.error('Unable to propagate during Regexp#=~', e)
|
@@ -66,7 +66,9 @@ module Contrast
|
|
66
66
|
def instrument_string_interpolation
|
67
67
|
if @_instrument_string_interpolation.nil?
|
68
68
|
@_instrument_string_interpolation = begin
|
69
|
-
|
69
|
+
if AGENT.patch_interpolation? && Funchook.available?
|
70
|
+
require 'cs__assess_string_interpolation26/cs__assess_string_interpolation26'
|
71
|
+
end
|
70
72
|
true
|
71
73
|
rescue StandardError, LoadError => e
|
72
74
|
logger.error('Error loading interpolation patch', e)
|
@@ -41,13 +41,15 @@ module Kernel # :nodoc:
|
|
41
41
|
|
42
42
|
def catch *args, &block
|
43
43
|
# Save current scope level
|
44
|
-
scope_level =
|
44
|
+
scope_level =
|
45
|
+
Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
|
45
46
|
|
46
47
|
# Run original catch with block.
|
47
48
|
retval = cs__catch(*args, &block)
|
48
49
|
|
49
50
|
# Restore scope.
|
50
|
-
Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_set(:@contrast_scope,
|
51
|
+
Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_set(:@contrast_scope,
|
52
|
+
scope_level)
|
51
53
|
|
52
54
|
retval
|
53
55
|
end
|
@@ -19,8 +19,7 @@ module Contrast
|
|
19
19
|
# Rack will be a special case that may involve updating some logic to handle only applying Rack if Rails/Sinatra
|
20
20
|
# do not exist
|
21
21
|
SUPPORTED_FRAMEWORKS = [
|
22
|
-
Contrast::Framework::Rails::Support,
|
23
|
-
Contrast::Framework::Sinatra::Support,
|
22
|
+
Contrast::Framework::Rails::Support, Contrast::Framework::Sinatra::Support,
|
24
23
|
Contrast::Framework::Rack::Support
|
25
24
|
].cs__freeze
|
26
25
|
|
@@ -61,16 +61,9 @@ module Contrast
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def apply_secure_session options
|
64
|
-
return unless vulnerable_setting?(
|
65
|
-
|
66
|
-
|
67
|
-
options,
|
68
|
-
safe_default: false)
|
69
|
-
|
70
|
-
cs__report_finding(
|
71
|
-
CS__SECURE_RULE_NAME,
|
72
|
-
options,
|
73
|
-
caller_locations(10, 9)[0])
|
64
|
+
return unless vulnerable_setting?(:secure, true, options, safe_default: false)
|
65
|
+
|
66
|
+
cs__report_finding(CS__SECURE_RULE_NAME, options, caller_locations(10, 9)[0])
|
74
67
|
rescue StandardError => e
|
75
68
|
begin
|
76
69
|
logger.error('Unable to track call to secure session', e)
|
@@ -86,10 +79,7 @@ module Contrast
|
|
86
79
|
safe_default: false,
|
87
80
|
comparison_type: :greater_than)
|
88
81
|
|
89
|
-
cs__report_finding(
|
90
|
-
CS__SESSION_TIMEOUT_NAME,
|
91
|
-
options,
|
92
|
-
caller_locations(10, 9)[0])
|
82
|
+
cs__report_finding(CS__SESSION_TIMEOUT_NAME, options, caller_locations(10, 9)[0])
|
93
83
|
rescue StandardError => e
|
94
84
|
begin
|
95
85
|
logger.error('Unable to track call to set session timeout', e)
|
@@ -101,10 +91,7 @@ module Contrast
|
|
101
91
|
def apply_httponly options
|
102
92
|
return unless vulnerable_setting?(:httponly, true, options)
|
103
93
|
|
104
|
-
cs__report_finding(
|
105
|
-
CS__HTTPONLY_NAME,
|
106
|
-
options,
|
107
|
-
caller_locations(10, 9)[0])
|
94
|
+
cs__report_finding(CS__HTTPONLY_NAME, options, caller_locations(10, 9)[0])
|
108
95
|
rescue StandardError => e
|
109
96
|
begin
|
110
97
|
logger.error('Unable to track call to httponly', e)
|
@@ -12,10 +12,12 @@ module Contrast
|
|
12
12
|
module Support
|
13
13
|
# (See BaseSupport#after_load_patches)
|
14
14
|
def after_load_patches
|
15
|
-
Set.new([
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
Set.new([
|
16
|
+
Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
|
17
|
+
'Rack::Session::Cookie',
|
18
|
+
'contrast/framework/rack/patch/session_cookie',
|
19
|
+
instrumenting_module: 'Contrast::Framework::Rack::Patch::SessionCookie')
|
20
|
+
])
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -32,7 +32,11 @@ module Contrast
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def vulnerable_setting?
|
35
|
+
def vulnerable_setting?(setting_key,
|
36
|
+
safe_settings_value,
|
37
|
+
original_args,
|
38
|
+
safe_default: true,
|
39
|
+
comparison_type: nil)
|
36
40
|
# In most cases, Rails is pretty nice and the default value is safe
|
37
41
|
return !safe_default unless original_args && original_args.length > 1
|
38
42
|
|
@@ -49,7 +53,8 @@ module Contrast
|
|
49
53
|
|
50
54
|
def apply_session_timeout *args
|
51
55
|
return if ASSESS.rule_disabled? CS__SESSION_TIMEOUT_NAME
|
52
|
-
return unless vulnerable_setting?(:expire_after, SAFE_SESSION_TIMEOUT, args,
|
56
|
+
return unless vulnerable_setting?(:expire_after, SAFE_SESSION_TIMEOUT, args,
|
57
|
+
comparison_type: :greater_than, safe_default: false)
|
53
58
|
|
54
59
|
rails_session_settings = args[1]
|
55
60
|
cs__report_finding(CS__SESSION_TIMEOUT_NAME, rails_session_settings, caller_locations(3, 2)[0])
|
@@ -44,11 +44,13 @@ module Contrast
|
|
44
44
|
'ActionController::Railties::Helper::ClassMethods',
|
45
45
|
'contrast/framework/rails/rewrite/action_controller_railties_helper_inherited',
|
46
46
|
method_to_instrument: :inherited,
|
47
|
-
instrumenting_module:
|
47
|
+
instrumenting_module:
|
48
|
+
'Contrast::Framework::Rails::Rewrite::ActionControllerRailtiesHelperInherited'),
|
48
49
|
Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
|
49
50
|
'ActiveRecord::AttributeMethods::Read::ClassMethods',
|
50
51
|
'contrast/framework/rails/rewrite/active_record_attribute_methods_read',
|
51
|
-
instrumenting_module:
|
52
|
+
instrumenting_module:
|
53
|
+
'Contrast::Framework::Rails::Rewrite::ActiveRecordAttributeMethodsRead'),
|
52
54
|
Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
|
53
55
|
'ActiveRecord::Scoping::Named::ClassMethods',
|
54
56
|
'contrast/framework/rails/rewrite/active_record_named',
|
@@ -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,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
|
require 'contrast/components/interface'
|
5
7
|
|
6
8
|
module Contrast
|
@@ -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.
|
@@ -12,11 +12,7 @@ module Funchook
|
|
12
12
|
ACCEPTABLE_FILES = %w[libfunchook.dylib libfunchook.so].cs__freeze
|
13
13
|
|
14
14
|
# 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
|
15
|
+
SEARCH_DIRS = [File.join('ext'), File.join('shared_libraries'), File.join('funchook', 'src')].cs__freeze
|
20
16
|
|
21
17
|
AGENT_ROOT = File.join(__dir__, '..', '..', '..')
|
22
18
|
|
@@ -16,10 +16,8 @@ module Contrast
|
|
16
16
|
def application_environment
|
17
17
|
return unless info?
|
18
18
|
|
19
|
-
info('Process environment information',
|
20
|
-
|
21
|
-
pp_id: Process.ppid,
|
22
|
-
agent_version: Contrast::Agent::VERSION)
|
19
|
+
info('Process environment information', p_id: Process.pid, pp_id: Process.ppid,
|
20
|
+
agent_version: Contrast::Agent::VERSION)
|
23
21
|
ENV.each do |env_key, env_value|
|
24
22
|
env_key = env_key.to_s
|
25
23
|
next unless ENV_KEYS.include?(env_key) ||
|
@@ -35,7 +33,9 @@ module Contrast
|
|
35
33
|
|
36
34
|
loggable = CONFIG.loggable
|
37
35
|
info('Current configuration', configuration: loggable)
|
38
|
-
env_keys = ENV.keys.select
|
36
|
+
env_keys = ENV.keys.select do |env_key|
|
37
|
+
env_key&.to_s&.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER)
|
38
|
+
end
|
39
39
|
env_items = env_keys.map { |env_key| Contrast::Utils::EnvConfigurationItem.new(env_key, nil) }
|
40
40
|
env_translations = env_items.each_with_object({}) do |conversion, hash|
|
41
41
|
hash[conversion.key] = conversion.dot_path_array.join('.')
|
@@ -52,7 +52,10 @@ module Contrast
|
|
52
52
|
end
|
53
53
|
|
54
54
|
FRAMEWORKS = %w[rails sinatra grape].cs__freeze
|
55
|
-
WEB_SERVERS = %w[
|
55
|
+
WEB_SERVERS = %w[
|
56
|
+
agoo falcon hoof iodine mongrel mongrel2 passenger puma rack skinny thin trinidad unicorn
|
57
|
+
webrick yarn
|
58
|
+
].cs__freeze
|
56
59
|
LIBRARIES = %w[excon json mongo moped mysql nokogiri oga ox pg psych sqlite3 typhoeus yaml].cs__freeze
|
57
60
|
def log_specific_libraries
|
58
61
|
FRAMEWORKS.each(&cs__method(:log_gem_data))
|
@@ -67,6 +70,7 @@ module Contrast
|
|
67
70
|
|
68
71
|
Gem.loaded_specs.each_pair do |_name, gem_spec|
|
69
72
|
debug('Gem loaded',
|
73
|
+
# rubocop:disable Security/Module/Name -- gems builtin.
|
70
74
|
gem_name: gem_spec.name,
|
71
75
|
gem_version: gem_spec.version.to_s)
|
72
76
|
end
|
@@ -76,9 +80,8 @@ module Contrast
|
|
76
80
|
gem_spec = Gem.loaded_specs[gem_name]
|
77
81
|
return unless gem_spec
|
78
82
|
|
79
|
-
info('Gem loaded',
|
80
|
-
|
81
|
-
gem_version: gem_spec.version.to_s)
|
83
|
+
info('Gem loaded', gem_name: gem_spec.name, gem_version: gem_spec.version.to_s)
|
84
|
+
# rubocop:enable Security/Module/Name
|
82
85
|
end
|
83
86
|
end
|
84
87
|
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
@@ -27,8 +27,7 @@ module Contrast
|
|
27
27
|
STDOUT_STR = 'STDOUT'
|
28
28
|
STDERR_STR = 'STDERR'
|
29
29
|
|
30
|
-
attr_reader :previous_path,
|
31
|
-
:previous_level
|
30
|
+
attr_reader :previous_path, :previous_level
|
32
31
|
|
33
32
|
def initialize
|
34
33
|
update
|
@@ -124,7 +123,9 @@ module Contrast
|
|
124
123
|
elsif write_permission?(DEFAULT_NAME)
|
125
124
|
# Log once when the path is invalid. We'll change to this path, so no
|
126
125
|
# need to log again.
|
127
|
-
|
126
|
+
if previous_path != DEFAULT_NAME
|
127
|
+
puts "[!] Unable to write to '#{ path }'. Writing to default log '#{ DEFAULT_NAME }' instead."
|
128
|
+
end
|
128
129
|
DEFAULT_NAME
|
129
130
|
else
|
130
131
|
# Log once when the path is invalid. We'll change to this path, so no
|
@@ -22,8 +22,7 @@ module Contrast
|
|
22
22
|
def request_end
|
23
23
|
context = Contrast::Agent::REQUEST_TRACKER.current
|
24
24
|
elapsed_time = context ? (Contrast::Utils::Timer.now_ms - context.timer.start_ms) : -1
|
25
|
-
debug('Ending request analysis',
|
26
|
-
elapsed_time_ms: elapsed_time)
|
25
|
+
debug('Ending request analysis', elapsed_time_ms: elapsed_time)
|
27
26
|
end
|
28
27
|
end
|
29
28
|
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
|
@@ -74,7 +74,11 @@ module Contrast
|
|
74
74
|
sleep(0.05) while Contrast::Utils::OS.running?
|
75
75
|
end
|
76
76
|
watcher.join(1)
|
77
|
-
|
77
|
+
if Contrast::Utils::OS.running?
|
78
|
+
puts 'Contrast Service did not stop.'
|
79
|
+
else
|
80
|
+
puts 'Contrast Service stopped successfully.'
|
81
|
+
end
|
78
82
|
else
|
79
83
|
puts 'Contrast Service is not already running. No need to stop.'
|
80
84
|
end
|
@@ -53,8 +53,7 @@ module Contrast
|
|
53
53
|
idx += 1
|
54
54
|
if Contrast::Utils::DuckUtils.iterable_hash?(obj)
|
55
55
|
obj.each_pair do |k, v|
|
56
|
-
return true if _tracked?(k, idx)
|
57
|
-
return true if _tracked?(v, idx)
|
56
|
+
return true if _tracked?(k, idx) || _tracked?(v, idx)
|
58
57
|
end
|
59
58
|
false
|
60
59
|
elsif Contrast::Utils::DuckUtils.iterable_enumerable?(obj)
|
@@ -9,14 +9,6 @@ module Contrast
|
|
9
9
|
# Utility methods for exploring the complete space of Objects
|
10
10
|
class ClassUtil
|
11
11
|
class << self
|
12
|
-
# Given a module, return all of its descendants
|
13
|
-
#
|
14
|
-
# @param mod [Module] the module whose descendants you want to find.
|
15
|
-
# @return [Array<Module>] those Modules that inherit from the given.
|
16
|
-
def descendants mod
|
17
|
-
ObjectSpace.each_object(mod).to_a
|
18
|
-
end
|
19
|
-
|
20
12
|
# some classes have had things prepended to them, like Marshal in Rails
|
21
13
|
# 5 and higher. Their ActiveSupport::MarshalWithAutoloading will break
|
22
14
|
# our alias patching approach, as will any other prepend on something
|
@@ -15,10 +15,7 @@ module Contrast
|
|
15
15
|
include Digest::Instance
|
16
16
|
|
17
17
|
CONTENT_LENGTH_HEADER = 'Content-Length'
|
18
|
-
CRYPTO_RULES = %w[
|
19
|
-
crypto-bad-ciphers
|
20
|
-
crypto-bad-mac
|
21
|
-
].cs__freeze
|
18
|
+
CRYPTO_RULES = %w[crypto-bad-ciphers crypto-bad-mac].cs__freeze
|
22
19
|
CONFIG_PATH_KEY = 'path'
|
23
20
|
CONFIG_SESSION_ID_KEY = 'sessionId'
|
24
21
|
CLASS_SOURCE_KEY = 'source'
|
@@ -111,7 +108,7 @@ module Contrast
|
|
111
108
|
events.each do |event|
|
112
109
|
event.event_sources.each do |source|
|
113
110
|
update(source.type)
|
114
|
-
update(source.name)
|
111
|
+
update(source.name) # rubocop:disable Security/Module/Name -- API attribute.
|
115
112
|
end
|
116
113
|
end
|
117
114
|
end
|