contrast-agent 3.8.5 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/cs__assess_array/cs__assess_array.c +1 -1
- data/ext/cs__assess_module/cs__assess_module.c +0 -1
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +34 -0
- data/ext/cs__assess_yield_track/cs__assess_yield_track.h +12 -0
- data/ext/{cs__scope → cs__assess_yield_track}/extconf.rb +0 -0
- data/ext/cs__common/cs__common.c +6 -6
- data/ext/cs__common/cs__common.h +3 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.c +142 -119
- data/ext/cs__contrast_patch/cs__contrast_patch.h +3 -0
- data/funchook/autom4te.cache/requests +48 -48
- data/funchook/config.log +2 -2
- data/lib/contrast/agent.rb +15 -5
- data/lib/contrast/agent/assess.rb +0 -1
- data/lib/contrast/agent/assess/contrast_event.rb +9 -8
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +68 -18
- data/lib/contrast/agent/assess/policy/policy.rb +0 -14
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
- data/lib/contrast/agent/assess/policy/preshift.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagation_method.rb +4 -2
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator/split.rb +166 -1
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +1 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +199 -140
- data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +30 -0
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +36 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +238 -153
- data/lib/contrast/agent/assess/policy/trigger_node.rb +54 -9
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +13 -0
- data/lib/contrast/agent/assess/properties.rb +29 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +35 -31
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +1 -1
- data/lib/contrast/agent/class_reopener.rb +98 -55
- data/lib/contrast/agent/feature_state.rb +1 -1
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/logger_manager.rb +2 -2
- data/lib/contrast/agent/middleware.rb +1 -3
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +40 -4
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +33 -8
- data/lib/contrast/agent/patching/policy/method_policy.rb +20 -7
- data/lib/contrast/agent/patching/policy/patch.rb +54 -23
- data/lib/contrast/agent/patching/policy/patch_status.rb +0 -2
- data/lib/contrast/agent/patching/policy/patcher.rb +10 -11
- data/lib/contrast/agent/patching/policy/policy.rb +4 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +14 -1
- data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -1
- data/lib/contrast/agent/protect/policy/policy.rb +6 -6
- data/lib/contrast/agent/protect/rule/base.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +3 -25
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/railtie.rb +11 -5
- data/lib/contrast/agent/request.rb +1 -19
- data/lib/contrast/agent/request_context.rb +1 -1
- data/lib/contrast/agent/rewriter.rb +4 -3
- data/lib/contrast/agent/scope.rb +116 -19
- data/lib/contrast/agent/service_heartbeat.rb +5 -2
- data/lib/contrast/agent/settings_state.rb +12 -8
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api.rb +1 -0
- data/lib/contrast/api/speedracer.rb +2 -2
- data/lib/contrast/components/agent.rb +26 -7
- data/lib/contrast/components/app_context.rb +8 -45
- data/lib/contrast/components/contrast_service.rb +3 -4
- data/lib/contrast/components/interface.rb +1 -1
- data/lib/contrast/components/scope.rb +56 -26
- data/lib/contrast/config/ruby_configuration.rb +8 -3
- data/lib/contrast/delegators.rb +9 -0
- data/lib/contrast/delegators/application_update.rb +32 -0
- data/lib/contrast/extensions/framework/rack/cookie.rb +24 -0
- data/lib/contrast/extensions/framework/rack/request.rb +24 -0
- data/lib/contrast/extensions/framework/rack/response.rb +23 -0
- data/lib/contrast/extensions/framework/rails/action_controller_railties_helper_inherited.rb +20 -0
- data/lib/contrast/extensions/framework/rails/active_record.rb +26 -0
- data/lib/contrast/extensions/framework/rails/active_record_named.rb +53 -0
- data/lib/contrast/extensions/framework/rails/active_record_time_zone_inherited.rb +21 -0
- data/lib/contrast/extensions/framework/rails/buffer.rb +28 -0
- data/lib/contrast/extensions/framework/rails/configuration.rb +27 -0
- data/lib/contrast/extensions/framework/sinatra/base.rb +59 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess.rb +12 -11
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/array.rb +4 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/assess_extension.rb +0 -2
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/basic_object.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/erb.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/exec_trigger.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/fiber.rb +3 -4
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/hash.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/kernel.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/module.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/regexp.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/string.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/tilt_template_trigger.rb +0 -0
- data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +40 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/delegator.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/eval_trigger.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory/datastores.rb +1 -1
- data/lib/contrast/extensions/ruby_core/module.rb +17 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_command_injection_rule.rb +8 -6
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_deserialization_rule.rb +7 -5
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_no_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_path_traversal_rule.rb +31 -27
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_xxe_rule.rb +9 -7
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/kernel.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/psych.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/thread.rb +0 -0
- data/lib/contrast/framework/base_support.rb +63 -0
- data/lib/contrast/framework/manager.rb +109 -0
- data/lib/contrast/framework/platform_version.rb +21 -0
- data/lib/contrast/framework/rails_support.rb +88 -0
- data/lib/contrast/framework/sinatra_application_helper.rb +49 -0
- data/lib/contrast/framework/sinatra_support.rb +94 -0
- data/lib/contrast/framework/view_technologies_descriptor.rb +20 -0
- data/lib/contrast/utils/assess/tracking_util.rb +2 -4
- data/lib/contrast/utils/class_util.rb +92 -37
- data/lib/contrast/utils/duck_utils.rb +59 -39
- data/lib/contrast/utils/environment_util.rb +5 -75
- data/lib/contrast/utils/freeze_util.rb +3 -7
- data/lib/contrast/utils/invalid_configuration_util.rb +5 -5
- data/lib/contrast/utils/job_servers_running.rb +39 -0
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -2
- data/lib/contrast/utils/service_response_util.rb +0 -6
- data/lib/contrast/utils/sinatra_helper.rb +6 -0
- data/lib/contrast/utils/stack_trace_utils.rb +1 -1
- data/resources/assess/policy.json +74 -23
- data/resources/inventory/policy.json +1 -1
- data/resources/protect/policy.json +11 -9
- data/resources/rubocops/object/frozen_cop.rb +1 -1
- data/ruby-agent.gemspec +2 -0
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +94 -57
- data/ext/cs__scope/cs__scope.c +0 -96
- data/ext/cs__scope/cs__scope.h +0 -33
- data/lib/contrast/agent/assess/class_reverter.rb +0 -82
- data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +0 -28
- data/lib/contrast/core_extensions/module.rb +0 -42
- data/lib/contrast/core_extensions/object.rb +0 -27
- data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +0 -48
- data/lib/contrast/rails_extensions/assess/active_record.rb +0 -32
- data/lib/contrast/rails_extensions/assess/active_record_named.rb +0 -61
- data/lib/contrast/rails_extensions/assess/configuration.rb +0 -26
- data/lib/contrast/rails_extensions/buffer.rb +0 -30
- data/lib/contrast/rails_extensions/rack.rb +0 -45
- data/lib/contrast/sinatra_extensions/assess/cookie.rb +0 -26
- data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +0 -59
- data/lib/contrast/utils/operating_environment.rb +0 -38
- data/lib/contrast/utils/path_util.rb +0 -151
- data/lib/contrast/utils/scope_util.rb +0 -99
data/lib/contrast/api.rb
CHANGED
@@ -12,6 +12,7 @@ end
|
|
12
12
|
|
13
13
|
cs__scoped_require 'contrast/api/dtm_pb'
|
14
14
|
cs__scoped_require 'contrast/api/settings_pb'
|
15
|
+
cs__scoped_require 'contrast/delegators'
|
15
16
|
cs__scoped_require 'contrast/api/unix_socket'
|
16
17
|
cs__scoped_require 'contrast/api/tcp_socket'
|
17
18
|
cs__scoped_require 'contrast/api/speedracer'
|
@@ -133,8 +133,8 @@ module Contrast
|
|
133
133
|
message.prefilter = event
|
134
134
|
when Contrast::Api::Dtm::HttpResponse
|
135
135
|
message.postfilter = event
|
136
|
-
when Contrast::Api::Dtm::
|
137
|
-
message.
|
136
|
+
when Contrast::Api::Dtm::Poll
|
137
|
+
message.poll = event
|
138
138
|
when Contrast::Api::Dtm::ObservedRoute
|
139
139
|
message.observed_route = event
|
140
140
|
else
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
cs__scoped_require 'rubygems/version'
|
5
|
+
|
4
6
|
module Contrast
|
5
7
|
module Components
|
6
8
|
module Agent
|
@@ -46,6 +48,10 @@ module Contrast
|
|
46
48
|
!interpolation_patch_possible?
|
47
49
|
end
|
48
50
|
|
51
|
+
def patch_yield?
|
52
|
+
!Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.propagate_yield)
|
53
|
+
end
|
54
|
+
|
49
55
|
def interpolation_enabled?
|
50
56
|
!Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.interpolate)
|
51
57
|
end
|
@@ -54,12 +60,15 @@ module Contrast
|
|
54
60
|
Contrast::Agent::FeatureState.instance.report_custom_code_sysfile_access?
|
55
61
|
end
|
56
62
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
def skip_instrumentation? loaded_module_name
|
64
|
+
return true unless loaded_module_name
|
65
|
+
|
66
|
+
loaded_module_name.start_with?(*CONFIG.root.agent.ruby.uninstrument_namespace)
|
67
|
+
end
|
68
|
+
|
69
|
+
# All this method chain does anymore is load the Thread patch that
|
70
|
+
# propagates request contexts. That can go away RUBY-700.
|
71
|
+
SHARED_LIBRARIES = %w[contrast/extensions/ruby_core/thread].cs__freeze
|
63
72
|
def run_instrumentation
|
64
73
|
Contrast::Agent::FeatureState.instance.tap do |settings|
|
65
74
|
SHARED_LIBRARIES.each { |lib| settings.instrument lib }
|
@@ -68,14 +77,24 @@ module Contrast
|
|
68
77
|
enable_tracepoint # This handles all class loads & required instrumentation going forward
|
69
78
|
end
|
70
79
|
|
80
|
+
# TODO: RUBY-564: This responsibility should be extracted out of this agent component and moved to
|
81
|
+
# the new component that handles one-time-whole-app initialization procedures.
|
82
|
+
def insert_middleware app
|
83
|
+
app.middleware.insert_before 0, Contrast::Agent::Middleware # Keep our middleware at the outermost layer of the onion
|
84
|
+
end
|
85
|
+
|
71
86
|
def enable_tracepoint
|
72
87
|
Contrast::Agent::TracePointHook.enable!
|
73
88
|
end
|
74
89
|
|
75
90
|
protected
|
76
91
|
|
92
|
+
INTERPOLATION_HOOKABLE_VERSION = Gem::Version.new('2.6.0')
|
93
|
+
# Ruby exposed the C method for interpolation in version 2.6.0, meaning
|
94
|
+
# we can attempt to patch using Funchook for that version and later.
|
77
95
|
def interpolation_patch_possible?
|
78
|
-
Gem::Version.new(RUBY_VERSION) >=
|
96
|
+
@_interpolation_patch_possible = Gem::Version.new(RUBY_VERSION) >= INTERPOLATION_HOOKABLE_VERSION if @_interpolation_patch_possible.nil?
|
97
|
+
@_interpolation_patch_possible
|
79
98
|
end
|
80
99
|
end
|
81
100
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
cs__scoped_require 'contrast/core_extensions/object'
|
5
4
|
cs__scoped_require 'contrast/utils/sinatra_helper'
|
5
|
+
cs__scoped_require 'rubygems/version'
|
6
6
|
|
7
7
|
module Contrast
|
8
8
|
module Components
|
@@ -23,12 +23,6 @@ module Contrast
|
|
23
23
|
DEFAULT_SERVER_NAME = 'localhost'
|
24
24
|
DEFAULT_SERVER_PATH = '/'
|
25
25
|
|
26
|
-
RAILS_TYPE = 'rails'
|
27
|
-
SINATRA_TYPE = 'sinatra'
|
28
|
-
RACK_TYPE = 'rack'
|
29
|
-
|
30
|
-
RAILS_MODULE_NAME_VERSION = Gem::Version.new('6.0.0')
|
31
|
-
|
32
26
|
def present? str
|
33
27
|
Contrast::Utils::EnvironmentUtil.present?(str)
|
34
28
|
end
|
@@ -36,29 +30,17 @@ module Contrast
|
|
36
30
|
def server_type
|
37
31
|
@_server_type ||= begin
|
38
32
|
tmp = CONFIG.root.server.type
|
39
|
-
tmp =
|
33
|
+
tmp = Contrast::Agent.framework_manager.server_type unless present?(tmp)
|
40
34
|
tmp
|
41
35
|
rescue StandardError
|
42
36
|
RACK_TYPE
|
43
37
|
end
|
44
38
|
end
|
45
39
|
|
46
|
-
def framework_server_name
|
47
|
-
@_framework_server_name ||= begin
|
48
|
-
if defined?(Rails)
|
49
|
-
RAILS_TYPE
|
50
|
-
elsif defined?(Sinatra)
|
51
|
-
SINATRA_TYPE
|
52
|
-
else
|
53
|
-
RACK_TYPE
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
40
|
def name
|
59
41
|
@_name ||= begin
|
60
42
|
tmp = CONFIG.root.application.name
|
61
|
-
tmp =
|
43
|
+
tmp = Contrast::Agent.framework_manager.app_name unless present?(tmp)
|
62
44
|
tmp = File.basename(Dir.pwd) unless present?(tmp)
|
63
45
|
Contrast::Utils::StringUtils.truncate(tmp, DEFAULT_APP_NAME)
|
64
46
|
rescue StandardError
|
@@ -66,14 +48,6 @@ module Contrast
|
|
66
48
|
end
|
67
49
|
end
|
68
50
|
|
69
|
-
def framework_app_name
|
70
|
-
@_framework_app_name ||= begin
|
71
|
-
name = find_rails_app_name
|
72
|
-
name ||= find_sinatra_app_name
|
73
|
-
name
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
51
|
def path
|
78
52
|
@_path ||= begin
|
79
53
|
tmp = CONFIG.root.application.path
|
@@ -154,24 +128,13 @@ module Contrast
|
|
154
128
|
@_client_id ||= [name, pgid].join('-')
|
155
129
|
end
|
156
130
|
|
157
|
-
|
158
|
-
|
159
|
-
def
|
160
|
-
|
161
|
-
return unless sinatra_app
|
162
|
-
|
163
|
-
sinatra_app.cs__class.cs__name
|
131
|
+
# TODO: RUBY-564: This responsibility should be extracted out of app_context and moved to
|
132
|
+
# the new component that handles one-time-whole-app initialization procedures.
|
133
|
+
def instrument_middleware_stack?
|
134
|
+
!Contrast::Utils::JobServersRunning.job_servers_running?
|
164
135
|
end
|
165
136
|
|
166
|
-
|
167
|
-
return nil unless defined?(Rails)
|
168
|
-
|
169
|
-
# Rails version 6.0.0 deprecated Rails::Application#parent_name, in Rails 6.1.0 that method will be removed entirely
|
170
|
-
# and instead we need to use parent_module_name
|
171
|
-
return Rails.application.cs__class.parent_module_name if Gem::Version.new(Rails.version) >= RAILS_MODULE_NAME_VERSION
|
172
|
-
|
173
|
-
Rails.application.cs__class.parent_name
|
174
|
-
end
|
137
|
+
private
|
175
138
|
|
176
139
|
# TODO: RUBY-120, move this responsibility toward the protobuf object
|
177
140
|
def protobuf_format param, truncate: true
|
@@ -65,12 +65,11 @@ module Contrast
|
|
65
65
|
# should be "must not be false" -- oops.
|
66
66
|
!false?(CONFIG.root.agent.start_bundled_service) &&
|
67
67
|
# Either a valid host or a valid socket
|
68
|
-
(CONFIG.root.agent.service.host.nil? ||
|
68
|
+
((CONFIG.root.agent.service.host.nil? ||
|
69
69
|
CONFIG.root.agent.service.host == 'localhost' ||
|
70
|
-
CONFIG.root.agent.service.host == '127.0.0.1' ||
|
71
|
-
CONFIG.root.agent.service.host.empty?) ||
|
70
|
+
CONFIG.root.agent.service.host == '127.0.0.1') ||
|
72
71
|
# Path validity is the service's problem
|
73
|
-
|
72
|
+
!!CONFIG.root.agent.service.socket)
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
@@ -39,33 +39,13 @@ module Contrast
|
|
39
39
|
end
|
40
40
|
|
41
41
|
module InstanceMethods # :nodoc:
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# [:my_cool_scope, :another_good_one].each do |scope|
|
45
|
-
# define_method "in_#{scope}_scope?" do
|
46
|
-
# abc
|
47
|
-
# end
|
48
|
-
# end
|
49
|
-
|
50
|
-
def in_contrast_scope?
|
51
|
-
scope_for_current_ec.in_contrast_scope?
|
52
|
-
end
|
53
|
-
|
54
|
-
def enter_contrast_scope!
|
55
|
-
scope_for_current_ec.enter_scope_for Contrast::Agent::Scope::CONTRAST_SCOPE
|
56
|
-
scope_for_current_ec
|
57
|
-
end
|
42
|
+
# For each instance method on a scope, define a forwarder
|
43
|
+
# to the scope on the current execution context's scope.
|
58
44
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def with_contrast_scope
|
65
|
-
enter_contrast_scope!
|
66
|
-
yield
|
67
|
-
ensure
|
68
|
-
exit_contrast_scope!
|
45
|
+
Contrast::Agent::Scope.public_instance_methods(false).each do |method_sym|
|
46
|
+
define_method(method_sym) do |*args, &block|
|
47
|
+
scope_for_current_ec.send(method_sym, *args, &block)
|
48
|
+
end
|
69
49
|
end
|
70
50
|
|
71
51
|
def scope_for_current_ec
|
@@ -104,3 +84,53 @@ module Contrast
|
|
104
84
|
end
|
105
85
|
end
|
106
86
|
end
|
87
|
+
|
88
|
+
# This is a reasonable place for the Kernel#catch hook to live.
|
89
|
+
# No current plans for component re-design, but if we had some kind of
|
90
|
+
# "do this when a component is hooked in" thing, this would live there.
|
91
|
+
# For now, it's over-engineering to live anywhere else. -ajm
|
92
|
+
module Kernel # :nodoc:
|
93
|
+
alias_method :cs__catch, :catch
|
94
|
+
|
95
|
+
# In the event of a `throw`, we need to override `catch`
|
96
|
+
# to save & restore scope state:
|
97
|
+
#
|
98
|
+
# scope_level == 0
|
99
|
+
#
|
100
|
+
# catch(:abc) do
|
101
|
+
# with_contrast_scope do
|
102
|
+
# throw :abc # will leak
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# scope_level == 1
|
107
|
+
#
|
108
|
+
# Frankly, this isn't how scope should be used. This is in place of
|
109
|
+
# proper `ensure` blocks within the instrumentation call stack.
|
110
|
+
# This will actually /create/ scope leaks if you're doing something like:
|
111
|
+
#
|
112
|
+
# catch(:ohno) do
|
113
|
+
# enter scope
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# abc()
|
117
|
+
#
|
118
|
+
# exit scope
|
119
|
+
#
|
120
|
+
# i.e. if you intend to change net scope across a catch block boundary.
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def catch *args, &block
|
125
|
+
# Save current scope level
|
126
|
+
scope_level = Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
|
127
|
+
|
128
|
+
# Run original catch with block.
|
129
|
+
retval = cs__catch(*args, &block)
|
130
|
+
|
131
|
+
# Restore scope.
|
132
|
+
Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_set(:@contrast_scope, scope_level)
|
133
|
+
|
134
|
+
retval
|
135
|
+
end
|
136
|
+
end
|
@@ -25,9 +25,14 @@ module Contrast
|
|
25
25
|
KEYS = {
|
26
26
|
disabled_agent_rake_tasks: Contrast::Config::DefaultValue.new(DISABLED_RAKE_TASK_LIST),
|
27
27
|
exceptions: Contrast::Config::ExceptionConfiguration,
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
# controls whether or not we patch interpolation, either by rewrite or by funchook
|
29
|
+
interpolate: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
|
30
|
+
# controls whether or not we patch the rb_yield block to track split propagation
|
31
|
+
propagate_yield: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
|
32
|
+
# control whether or not we run file scanning rules on require
|
33
|
+
require_scan: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
|
34
|
+
# controls whether or not we track frozen Strings by replacing them
|
35
|
+
track_frozen_sources: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
|
31
36
|
uninstrument_namespace: Contrast::Config::DefaultValue.new(DEFAULT_UNINSTRUMENTED_NAMESPACES)
|
32
37
|
}.cs__freeze
|
33
38
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
# Used to define decorators for objects to add behavior without polluting the namespace
|
6
|
+
module Delegators
|
7
|
+
end
|
8
|
+
end
|
9
|
+
cs__scoped_require 'contrast/delegators/application_update'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
module Delegators
|
6
|
+
# Used to decorate the ApplicationUpdate protobuf model so it can own some of the data massaging required for
|
7
|
+
# AppUpdate dtm
|
8
|
+
class ApplicationUpdate < SimpleDelegator
|
9
|
+
def append_view_technology_descriptor_data view_technology_descriptors
|
10
|
+
view_technology_descriptors.each do |vtd|
|
11
|
+
vtd.technology_names.each do |tech_name|
|
12
|
+
@delegate_sd_obj.technologies[tech_name] = true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TS only allows you to report 500 routes per application
|
18
|
+
def append_route_coverage_data route_coverage_dtms
|
19
|
+
route_coverage_dtms.take(500).each do |route_coverage_dtm|
|
20
|
+
@delegate_sd_obj.routes << route_coverage_dtm
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def append_platform_version platform_version
|
25
|
+
@delegate_sd_obj.platform = Contrast::Api::Dtm::Platform.new if @delegate_sd_obj.platform.nil?
|
26
|
+
@delegate_sd_obj.platform.major = platform_version.major
|
27
|
+
@delegate_sd_obj.platform.minor = platform_version.minor
|
28
|
+
@delegate_sd_obj.platform.build = platform_version.patch
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
cs__scoped_require 'contrast/components/interface'
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module Session
|
8
|
+
# Our patch into the Rack::Session::Cookie Class, allowing for the
|
9
|
+
# runtime detection of insecure configurations on individual cookies
|
10
|
+
# within the application
|
11
|
+
class Cookie
|
12
|
+
include Contrast::Utils::InvalidConfigurationUtil
|
13
|
+
include Contrast::Components::Interface
|
14
|
+
|
15
|
+
access_component :scope
|
16
|
+
|
17
|
+
alias_method :cs__patched_initialize, :initialize
|
18
|
+
def initialize app, options = {}
|
19
|
+
Contrast::Utils::RackAssessSessionCookie.analyze_cookie_initialization(options)
|
20
|
+
cs__patched_initialize(app, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# In earlier versions of rack < 2.0.0 the Rack::Response and Rack::Request do
|
5
|
+
# not have get_header or set_header methods. This is our way of working
|
6
|
+
# around that.
|
7
|
+
module Rack
|
8
|
+
# Our patch into the Rack::Request class, allowing us to call set_header
|
9
|
+
# and get_header in our code without worrying about older versions of
|
10
|
+
# Rack not implementing these methods.
|
11
|
+
class Request
|
12
|
+
unless Rack::Request.instance_methods(true).include?(:set_header)
|
13
|
+
def set_header name, value
|
14
|
+
@env[name] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
unless Rack::Request.instance_methods(true).include?(:get_header)
|
19
|
+
def get_header name
|
20
|
+
@env[name]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# In earlier versions of rack < 2.0.0 the Rack::Response and Rack::Request do
|
5
|
+
# not have get_header or set_header methods. This is our way of working
|
6
|
+
# around that.
|
7
|
+
module Rack
|
8
|
+
# Our patch into the Rack::Response Class, allowing us to call set_header
|
9
|
+
# and get_header in our code without worrying about older versions of
|
10
|
+
# Rack not implementing these methods.
|
11
|
+
class Response
|
12
|
+
unless Rack::Response.instance_methods(true).include?(:set_header)
|
13
|
+
def set_header key, value
|
14
|
+
headers[key] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
unless Rack::Response.instance_methods(true).include?(:get_header)
|
18
|
+
def get_header key
|
19
|
+
headers[key]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|