contrast-agent 4.7.0 → 4.10.0
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/.rspec +0 -1
- data/.rspec_parallel +6 -0
- data/.simplecov +1 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.c +0 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.h +0 -2
- data/lib/contrast/agent/assess/contrast_event.rb +1 -5
- data/lib/contrast/agent/assess/finalizers/hash.rb +2 -5
- data/lib/contrast/agent/assess/policy/patcher.rb +5 -4
- data/lib/contrast/agent/assess/policy/policy.rb +1 -1
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +2 -6
- data/lib/contrast/agent/assess/policy/preshift.rb +11 -8
- data/lib/contrast/agent/assess/policy/propagation_method.rb +102 -59
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +2 -7
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +31 -11
- data/lib/contrast/agent/assess/policy/propagator/rack_protection.rb +73 -0
- data/lib/contrast/agent/assess/policy/propagator/split.rb +10 -6
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +3 -3
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +6 -7
- data/lib/contrast/agent/assess/policy/source_method.rb +18 -22
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +0 -4
- data/lib/contrast/agent/assess/policy/trigger_method.rb +61 -86
- data/lib/contrast/agent/assess/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/assess/property/evented.rb +2 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +3 -4
- data/lib/contrast/agent/at_exit_hook.rb +3 -3
- data/lib/contrast/agent/class_reopener.rb +6 -5
- data/lib/contrast/agent/disable_reaction.rb +4 -5
- data/lib/contrast/agent/exclusion_matcher.rb +2 -7
- data/lib/contrast/agent/inventory/database_config.rb +117 -0
- data/lib/contrast/agent/inventory/dependency_analysis.rb +2 -6
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +8 -9
- data/lib/contrast/agent/inventory/policy/datastores.rb +5 -6
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/middleware.rb +15 -13
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +6 -3
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +21 -16
- data/lib/contrast/agent/patching/policy/module_policy.rb +2 -4
- data/lib/contrast/agent/patching/policy/patch.rb +13 -8
- data/lib/contrast/agent/patching/policy/patch_status.rb +3 -7
- data/lib/contrast/agent/patching/policy/patcher.rb +14 -14
- data/lib/contrast/agent/patching/policy/policy.rb +2 -4
- data/lib/contrast/agent/patching/policy/policy_node.rb +2 -3
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/policy.rb +1 -1
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +3 -5
- data/lib/contrast/agent/protect/rule/base.rb +10 -10
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +4 -5
- data/lib/contrast/agent/protect/rule/no_sqli.rb +7 -53
- data/lib/contrast/agent/protect/rule/path_traversal.rb +1 -5
- data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +137 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +7 -70
- data/lib/contrast/agent/reaction_processor.rb +3 -4
- data/lib/contrast/agent/request.rb +9 -5
- data/lib/contrast/agent/request_context.rb +28 -31
- data/lib/contrast/agent/request_handler.rb +5 -3
- data/lib/contrast/agent/response.rb +2 -3
- data/lib/contrast/agent/rewriter.rb +4 -3
- data/lib/contrast/agent/rule_set.rb +5 -4
- data/lib/contrast/agent/service_heartbeat.rb +2 -3
- data/lib/contrast/agent/static_analysis.rb +7 -6
- data/lib/contrast/agent/thread.rb +2 -4
- data/lib/contrast/agent/thread_watcher.rb +3 -4
- data/lib/contrast/agent/tracepoint_hook.rb +10 -5
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +16 -11
- data/lib/contrast/api/communication/response_processor.rb +11 -11
- data/lib/contrast/api/communication/service_lifecycle.rb +9 -5
- data/lib/contrast/api/communication/socket_client.rb +18 -14
- data/lib/contrast/api/communication/speedracer.rb +5 -6
- 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 +9 -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/message.rb +7 -7
- data/lib/contrast/api/decorators/route_coverage.rb +24 -1
- data/lib/contrast/api/decorators/trace_event_object.rb +2 -3
- data/lib/contrast/components/agent.rb +13 -15
- data/lib/contrast/components/app_context.rb +7 -11
- data/lib/contrast/components/assess.rb +19 -16
- data/lib/contrast/components/base.rb +40 -0
- data/lib/contrast/components/config.rb +1 -2
- data/lib/contrast/components/contrast_service.rb +8 -11
- data/lib/contrast/components/heap_dump.rb +5 -4
- data/lib/contrast/components/inventory.rb +2 -7
- data/lib/contrast/components/logger.rb +14 -10
- data/lib/contrast/components/protect.rb +10 -13
- data/lib/contrast/components/sampling.rb +5 -5
- data/lib/contrast/components/scope.rb +9 -32
- data/lib/contrast/components/settings.rb +1 -5
- data/lib/contrast/config/base_configuration.rb +14 -6
- data/lib/contrast/configuration.rb +22 -19
- data/lib/contrast/extension/assess/array.rb +3 -15
- data/lib/contrast/extension/assess/eval_trigger.rb +2 -23
- data/lib/contrast/extension/assess/fiber.rb +6 -16
- data/lib/contrast/extension/assess/hash.rb +3 -13
- data/lib/contrast/extension/assess/kernel.rb +3 -14
- data/lib/contrast/extension/assess/marshal.rb +6 -14
- data/lib/contrast/extension/assess/regexp.rb +5 -15
- data/lib/contrast/extension/assess/string.rb +6 -31
- data/lib/contrast/extension/extension.rb +61 -0
- data/lib/contrast/extension/kernel.rb +2 -4
- data/lib/contrast/extension/protect/kernel.rb +0 -15
- data/lib/contrast/framework/grape/support.rb +174 -0
- data/lib/contrast/framework/manager.rb +44 -9
- data/lib/contrast/framework/rack/patch/session_cookie.rb +6 -6
- data/lib/contrast/framework/rack/support.rb +1 -1
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +5 -8
- data/lib/contrast/framework/rails/patch/support.rb +44 -37
- data/lib/contrast/framework/rails/railtie.rb +34 -0
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +4 -4
- data/lib/contrast/framework/rails/support.rb +60 -13
- data/lib/contrast/framework/sinatra/support.rb +1 -1
- data/lib/contrast/funchook/funchook.rb +4 -3
- data/lib/contrast/logger/application.rb +1 -6
- data/lib/contrast/logger/log.rb +103 -13
- data/lib/contrast/logger/request.rb +0 -4
- data/lib/contrast/tasks/config.rb +0 -1
- data/lib/contrast/tasks/service.rb +1 -6
- data/lib/contrast/utils/assess/sampling_util.rb +2 -3
- data/lib/contrast/utils/assess/tracking_util.rb +2 -4
- data/lib/contrast/utils/heap_dump_util.rb +5 -3
- data/lib/contrast/utils/invalid_configuration_util.rb +4 -3
- data/lib/contrast/utils/io_util.rb +3 -5
- data/lib/contrast/utils/job_servers_running.rb +4 -3
- data/lib/contrast/utils/os.rb +2 -3
- data/lib/contrast/utils/ruby_ast_rewriter.rb +16 -13
- data/lib/contrast/utils/string_utils.rb +2 -3
- data/lib/contrast/utils/tag_util.rb +26 -19
- data/lib/contrast.rb +24 -14
- data/resources/assess/policy.json +252 -2
- data/resources/deadzone/policy.json +10 -0
- data/ruby-agent.gemspec +14 -3
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +104 -24
- data/lib/contrast/agent/railtie.rb +0 -31
- data/lib/contrast/components/interface.rb +0 -196
- data/lib/contrast/delegators/input_analysis.rb +0 -12
- data/lib/contrast/utils/inventory_util.rb +0 -114
@@ -1,7 +1,7 @@
|
|
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/scope'
|
5
5
|
require 'contrast/extension/module'
|
6
6
|
require 'contrast/utils/class_util'
|
7
7
|
|
@@ -11,8 +11,8 @@ module Contrast
|
|
11
11
|
module Policy
|
12
12
|
# Used to handle tracking patches that need to apply special instrumentation when a module is loaded
|
13
13
|
class AfterLoadPatch
|
14
|
-
include Contrast::Components::
|
15
|
-
|
14
|
+
include Contrast::Components::Scope::InstanceMethods
|
15
|
+
|
16
16
|
attr_reader :applied, :module_name, :instrumentation_file_path, :method_to_instrument, :instrumenting_module
|
17
17
|
|
18
18
|
def initialize module_name, instrumentation_file_path, method_to_instrument: nil, instrumenting_module: nil
|
@@ -59,7 +59,10 @@ module Contrast
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def instrument!
|
62
|
+
return if instrumenting_module == :'Contrast::Framework::Rails::Rewrite' && RAILS_VER >= '2.6.0'
|
63
|
+
|
62
64
|
require instrumentation_file_path
|
65
|
+
|
63
66
|
if instrumenting_module
|
64
67
|
mod = Module.cs__const_get(instrumenting_module)
|
65
68
|
with_contrast_scope { mod.instrument } if mod
|
@@ -2,8 +2,9 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/patching/policy/after_load_patch'
|
5
|
-
require 'contrast/components/
|
5
|
+
require 'contrast/components/logger'
|
6
6
|
require 'contrast/framework/manager'
|
7
|
+
require 'contrast/extension/extension'
|
7
8
|
|
8
9
|
module Contrast
|
9
10
|
module Agent
|
@@ -12,8 +13,7 @@ module Contrast
|
|
12
13
|
# Some modules diverge from our generic instrumentation and require custom instrumentation
|
13
14
|
# after they've been loaded
|
14
15
|
module AfterLoadPatcher
|
15
|
-
include Contrast::Components::
|
16
|
-
access_component :agent, :logging
|
16
|
+
include Contrast::Components::Logger::InstanceMethods
|
17
17
|
|
18
18
|
# After initialization run a catchup check to instrument any already loaded modules we care about
|
19
19
|
def catchup_after_load_patches
|
@@ -30,18 +30,23 @@ module Contrast
|
|
30
30
|
# extensions.
|
31
31
|
def apply_direct_patches!
|
32
32
|
@_apply_direct_patches ||= begin
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
33
|
+
paths = %w[
|
34
|
+
array
|
35
|
+
basic_object
|
36
|
+
module
|
37
|
+
fiber_track
|
38
|
+
hash
|
39
|
+
kernel
|
40
|
+
marshal_module
|
41
|
+
regexp
|
42
|
+
string
|
43
|
+
string_interpolation26
|
44
|
+
].cs__freeze
|
45
|
+
paths.each do |p|
|
46
|
+
path_part = "cs__assess_#{ p }"
|
47
|
+
Contrast::Extension::Assess::InstrumentHelper.instrument "#{ path_part }/#{ path_part }"
|
48
|
+
end
|
49
|
+
Contrast::Extension::Assess::InstrumentHelper.instrument 'cs__protect_kernel/cs__protect_kernel'
|
45
50
|
true
|
46
51
|
end
|
47
52
|
end
|
@@ -49,7 +54,7 @@ module Contrast
|
|
49
54
|
def apply_load_patches!
|
50
55
|
after_load_patches.each do |after_load_patch|
|
51
56
|
next unless after_load_patch.target_defined?
|
52
|
-
next if AGENT.skip_instrumentation?(after_load_patch.module_name)
|
57
|
+
next if ::Contrast::AGENT.skip_instrumentation?(after_load_patch.module_name)
|
53
58
|
|
54
59
|
logger.trace('Catching up on already loaded afterload patch - applying instrumentation',
|
55
60
|
module: after_load_patch.module_name)
|
@@ -12,11 +12,9 @@ module Contrast
|
|
12
12
|
# rather than new.
|
13
13
|
class ModulePolicy
|
14
14
|
class << self
|
15
|
-
# Given the name of a module, create a :ModulePolicy for it using
|
16
|
-
# the Policy of each supported feature
|
15
|
+
# Given the name of a module, create a :ModulePolicy for it using the Policy of each supported feature.
|
17
16
|
#
|
18
|
-
# @param module_name [String] the name of the module to which the
|
19
|
-
# policy applies
|
17
|
+
# @param module_name [String] the name of the module to which the policy applies.
|
20
18
|
# @return [Contrast::Agent::Patching::Policy::ModulePolicy]
|
21
19
|
def create_module_policy module_name
|
22
20
|
module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.new
|
@@ -2,7 +2,8 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'monitor'
|
5
|
-
require 'contrast/components/
|
5
|
+
require 'contrast/components/logger'
|
6
|
+
require 'contrast/components/scope'
|
6
7
|
|
7
8
|
require 'contrast/agent'
|
8
9
|
require 'contrast/logger/log'
|
@@ -35,9 +36,8 @@ module Contrast
|
|
35
36
|
include Contrast::Agent::Assess::Policy::SourceMethod
|
36
37
|
include Contrast::Agent::Assess::Policy::PropagationMethod
|
37
38
|
include Contrast::Agent::Assess::Policy::TriggerMethod
|
38
|
-
|
39
|
-
include Contrast::Components::
|
40
|
-
access_component :agent, :analysis, :logging, :scope
|
39
|
+
include Contrast::Components::Logger::InstanceMethods
|
40
|
+
include Contrast::Components::Scope::InstanceMethods
|
41
41
|
|
42
42
|
POLICIES = [
|
43
43
|
Contrast::Agent::Assess::Policy::Policy,
|
@@ -127,8 +127,8 @@ module Contrast
|
|
127
127
|
# @param args [Array<Object>] The arguments passed to the method
|
128
128
|
# being invoked.
|
129
129
|
def apply_protect method_policy, method, exception, object, args
|
130
|
-
return unless AGENT.enabled?
|
131
|
-
return unless PROTECT.enabled?
|
130
|
+
return unless ::Contrast::AGENT.enabled?
|
131
|
+
return unless ::Contrast::PROTECT.enabled?
|
132
132
|
|
133
133
|
apply_trigger_only(method_policy&.protect_node, method, exception, object, args)
|
134
134
|
end
|
@@ -145,7 +145,7 @@ module Contrast
|
|
145
145
|
# @param args [Array<Object>] The arguments passed to the method
|
146
146
|
# being invoked.
|
147
147
|
def apply_inventory method_policy, method, exception, object, args
|
148
|
-
return unless INVENTORY.enabled?
|
148
|
+
return unless ::Contrast::INVENTORY.enabled?
|
149
149
|
|
150
150
|
apply_trigger_only(method_policy&.inventory_node, method, exception, object, args)
|
151
151
|
end
|
@@ -167,7 +167,7 @@ module Contrast
|
|
167
167
|
def apply_assess method_policy, preshift, object, ret, args, block
|
168
168
|
source_ret = nil
|
169
169
|
propagated_ret = nil
|
170
|
-
return ret unless method_policy && ASSESS.enabled?
|
170
|
+
return ret unless method_policy && ::Contrast::ASSESS.enabled?
|
171
171
|
|
172
172
|
current_context = Contrast::Agent::REQUEST_TRACKER.current
|
173
173
|
return ret if current_context && !current_context.analyze_request?
|
@@ -290,6 +290,11 @@ module Contrast
|
|
290
290
|
# we've already patched this class, don't do it again
|
291
291
|
return true if methods.include?(cs_method_name)
|
292
292
|
|
293
|
+
# that method is within Contrast definition so it should be skipped
|
294
|
+
method = mod.instance_method(method_policy.method_name) if method_policy.instance_method
|
295
|
+
method = mod.singleton_method(method_policy.method_name) unless method_policy.instance_method
|
296
|
+
return true if method.owner <= Contrast
|
297
|
+
|
293
298
|
begin
|
294
299
|
contrast_define_method(mod, method_policy, cs_method_name)
|
295
300
|
rescue NameError => e
|
@@ -15,13 +15,9 @@ module Contrast
|
|
15
15
|
# @param mod [Module] the Module for which the status is asked
|
16
16
|
# @return [Contrast::Agent::Patching::Policy::PatchStatus]
|
17
17
|
def get_status mod
|
18
|
-
if mod.cs__const_defined?(status_key, false)
|
19
|
-
|
20
|
-
|
21
|
-
s = new
|
22
|
-
mod.cs__const_set(status_key, s)
|
23
|
-
s
|
24
|
-
end
|
18
|
+
return mod.cs__const_get(status_key) if mod.cs__const_defined?(status_key, false)
|
19
|
+
|
20
|
+
mod.cs__const_set(status_key, new)
|
25
21
|
end
|
26
22
|
|
27
23
|
# Allows our C patches to look up the :MethodPolicy for a given
|
@@ -7,7 +7,8 @@ require 'monitor'
|
|
7
7
|
require 'contrast/agent/patching/policy/patch_status'
|
8
8
|
require 'contrast/agent/patching/policy/method_policy'
|
9
9
|
require 'contrast/agent/patching/policy/module_policy'
|
10
|
-
require 'contrast/components/
|
10
|
+
require 'contrast/components/logger'
|
11
|
+
require 'contrast/components/scope'
|
11
12
|
require 'contrast/utils/class_util'
|
12
13
|
|
13
14
|
# assess
|
@@ -43,9 +44,8 @@ module Contrast
|
|
43
44
|
# and how.
|
44
45
|
module Patcher
|
45
46
|
extend Contrast::Agent::Patching::Policy::AfterLoadPatcher
|
46
|
-
|
47
|
-
|
48
|
-
access_component :agent, :analysis, :logging, :scope
|
47
|
+
extend Contrast::Components::Logger::InstanceMethods
|
48
|
+
extend Contrast::Components::Scope::InstanceMethods
|
49
49
|
|
50
50
|
class << self
|
51
51
|
# Hook to install the Contrast changes needed to allow for the
|
@@ -54,7 +54,8 @@ module Contrast
|
|
54
54
|
def patch
|
55
55
|
catchup_after_load_patches
|
56
56
|
catchup_loaded_methods
|
57
|
-
|
57
|
+
# TODO: RUBY-714 remove guard w/ EOL of 2.5
|
58
|
+
Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolations if RUBY_VERSION < '2.6.0'
|
58
59
|
end
|
59
60
|
|
60
61
|
# Hook to only monkeypatch Contrast. This will not trigger any
|
@@ -82,11 +83,11 @@ module Contrast
|
|
82
83
|
with_contrast_scope do
|
83
84
|
mod_name = mod.cs__name
|
84
85
|
return unless Contrast::Utils::ClassUtil.truly_defined?(mod_name)
|
85
|
-
return if AGENT.skip_instrumentation?(mod_name)
|
86
|
+
return if ::Contrast::AGENT.skip_instrumentation?(mod_name)
|
86
87
|
|
87
88
|
load_patches_for_module(mod_name)
|
88
89
|
|
89
|
-
return
|
90
|
+
return if all_module_names.none?(mod_name)
|
90
91
|
|
91
92
|
module_data = Contrast::Agent::ModuleData.new(mod, mod_name)
|
92
93
|
patch_into_module(module_data)
|
@@ -156,7 +157,7 @@ module Contrast
|
|
156
157
|
logger.trace_with_time('Running patching') do
|
157
158
|
patched = []
|
158
159
|
all_module_names.each do |patchable_name|
|
159
|
-
next if AGENT.skip_instrumentation?(patchable_name)
|
160
|
+
next if ::Contrast::AGENT.skip_instrumentation?(patchable_name)
|
160
161
|
|
161
162
|
patchable_mod = patchable(patchable_name)
|
162
163
|
next unless patchable_mod
|
@@ -176,12 +177,13 @@ module Contrast
|
|
176
177
|
# @param redo_patch [Boolean] a trigger to force patching regardless of the state of the
|
177
178
|
# Contrast::Agent::Patching::Policy::PatchStatus status on the Module
|
178
179
|
def patch_into_module module_data, redo_patch = false
|
179
|
-
status =
|
180
|
+
status = Contrast::Agent::Patching::Policy::PatchStatus.get_status(module_data.mod)
|
180
181
|
return if (status&.patched? || status&.patching?) && !redo_patch
|
181
182
|
|
182
183
|
# Begin patching our sources into the given module. Any patcher that has the name of the module will be
|
183
184
|
# evaluated for patching. Find all the patchers that apply to this class, sorted by type.
|
184
185
|
module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.create_module_policy(module_data.mod_name)
|
186
|
+
|
185
187
|
# If there's nothing to match, then set that status and exit
|
186
188
|
if module_policy.empty?
|
187
189
|
status.no_patch!
|
@@ -191,8 +193,8 @@ module Contrast
|
|
191
193
|
status.patching!
|
192
194
|
num_applied_patches = patch_into_instance_methods(module_data, module_policy)
|
193
195
|
num_applied_patches += patch_into_singleton_methods(module_data, module_policy)
|
194
|
-
if adjust_for_prepend(module_data) || module_policy.num_expected_patches == num_applied_patches
|
195
196
|
|
197
|
+
if adjust_for_prepend(module_data) || module_policy.num_expected_patches == num_applied_patches
|
196
198
|
status.patched!
|
197
199
|
else
|
198
200
|
status.partial_patch!
|
@@ -258,8 +260,7 @@ module Contrast
|
|
258
260
|
patch_into_methods(mod, methods, module_policy, false)
|
259
261
|
end
|
260
262
|
|
261
|
-
# We've found the patchers that apply to this class (or module). Now we'll
|
262
|
-
# filter on the given method.
|
263
|
+
# We've found the patchers that apply to this class (or module). Now we'll filter on the given method.
|
263
264
|
#
|
264
265
|
# @param mod [Module] The module from which to retrieve instance methods.
|
265
266
|
# @param methods [Array<Symbol>] The names of all the methods in in this module
|
@@ -276,8 +277,7 @@ module Contrast
|
|
276
277
|
is_instance_method)
|
277
278
|
next if method_policy.empty?
|
278
279
|
|
279
|
-
|
280
|
-
count += 1 if patched
|
280
|
+
count += 1 if patch_method(mod, methods, method_policy)
|
281
281
|
end
|
282
282
|
count
|
283
283
|
end
|
@@ -5,7 +5,7 @@ require 'json'
|
|
5
5
|
require 'singleton'
|
6
6
|
|
7
7
|
require 'contrast'
|
8
|
-
require 'contrast/components/
|
8
|
+
require 'contrast/components/logger'
|
9
9
|
require 'contrast/agent/patching/policy/module_policy'
|
10
10
|
require 'contrast/agent/patching/policy/method_policy'
|
11
11
|
|
@@ -19,7 +19,7 @@ module Contrast
|
|
19
19
|
# @abstract
|
20
20
|
class Policy
|
21
21
|
include Singleton
|
22
|
-
include Contrast::Components::
|
22
|
+
include Contrast::Components::Logger::InstanceMethods
|
23
23
|
|
24
24
|
# Indicates the folder in `resources` where this policy lives.
|
25
25
|
def self.policy_folder
|
@@ -36,8 +36,6 @@ module Contrast
|
|
36
36
|
raise(NoMethodError, 'specify the concrete node type for this poilcy')
|
37
37
|
end
|
38
38
|
|
39
|
-
access_component :analysis, :logging
|
40
|
-
|
41
39
|
attr_reader :sources, :propagators, :triggers, :providers
|
42
40
|
|
43
41
|
SOURCES_KEY = 'sources'
|
@@ -1,7 +1,7 @@
|
|
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/scope'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -12,8 +12,7 @@ module Contrast
|
|
12
12
|
#
|
13
13
|
# @abstract
|
14
14
|
class PolicyNode
|
15
|
-
include Contrast::Components::
|
16
|
-
access_component :analysis, :scope
|
15
|
+
include Contrast::Components::Scope::InstanceMethods
|
17
16
|
|
18
17
|
attr_accessor :class_name, :instance_method, :method_name, :method_visibility
|
19
18
|
attr_reader :properties, :method_scope
|
@@ -14,7 +14,7 @@ module Contrast
|
|
14
14
|
# infilter methods of the rule should be invoked.
|
15
15
|
module AppliesNoSqliRule
|
16
16
|
extend Contrast::Agent::Protect::Policy::RuleApplicator
|
17
|
-
|
17
|
+
DATABASE_NOSQL = 'MongoDB'
|
18
18
|
class << self
|
19
19
|
def invoke method, _exception, properties, _object, args
|
20
20
|
return unless valid_input?(args)
|
@@ -1,7 +1,7 @@
|
|
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
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -11,9 +11,7 @@ module Contrast
|
|
11
11
|
# form of the Applicator, which will override specific implementations
|
12
12
|
# in order to properly invoke its Rule.
|
13
13
|
module RuleApplicator
|
14
|
-
include Contrast::Components::
|
15
|
-
|
16
|
-
access_component :analysis, :logging
|
14
|
+
include Contrast::Components::Logger::InstanceMethods
|
17
15
|
|
18
16
|
# Calls the actual invocation for this applicator, if required. Will
|
19
17
|
# attempt to transform the data as required prior to invocation and
|
@@ -82,7 +80,7 @@ module Contrast
|
|
82
80
|
#
|
83
81
|
# @return [Contrast::Agent::Protect::Rule::Base]
|
84
82
|
def rule
|
85
|
-
PROTECT.rule rule_name
|
83
|
+
::Contrast::PROTECT.rule rule_name
|
86
84
|
end
|
87
85
|
|
88
86
|
# Should we skip analysis for this rule for this method invocation?
|
@@ -1,7 +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
|
-
require 'contrast/components/
|
4
|
+
require 'contrast/components/logger'
|
5
|
+
require 'contrast/components/scope'
|
5
6
|
|
6
7
|
module Contrast
|
7
8
|
module Agent
|
@@ -12,9 +13,8 @@ module Contrast
|
|
12
13
|
#
|
13
14
|
# @abstract Subclass and override {#prefilter}, {#infilter}, {#find_attacker}, {#postfilter} to implement
|
14
15
|
class Base
|
15
|
-
include Contrast::Components::
|
16
|
-
|
17
|
-
access_component :agent, :analysis, :logging, :scope, :settings
|
16
|
+
include Contrast::Components::Logger::InstanceMethods
|
17
|
+
include Contrast::Components::Scope::InstanceMethods
|
18
18
|
|
19
19
|
UNKNOWN_USER_INPUT = Contrast::Api::Dtm::UserInput.new.tap do |user_input|
|
20
20
|
user_input.input_type = :UNKNOWN
|
@@ -37,7 +37,7 @@ module Contrast
|
|
37
37
|
attr_reader :mode
|
38
38
|
|
39
39
|
def initialize
|
40
|
-
PROTECT.rules[rule_name] = self
|
40
|
+
::Contrast::PROTECT.rules[rule_name] = self
|
41
41
|
@mode = mode_from_settings
|
42
42
|
end
|
43
43
|
|
@@ -48,11 +48,11 @@ module Contrast
|
|
48
48
|
|
49
49
|
def enabled?
|
50
50
|
# 1. it is not enabled because protect is not enabled
|
51
|
-
return false unless AGENT.enabled?
|
52
|
-
return false unless PROTECT.enabled?
|
51
|
+
return false unless ::Contrast::AGENT.enabled?
|
52
|
+
return false unless ::Contrast::PROTECT.enabled?
|
53
53
|
|
54
54
|
# 2. it is not enabled because it is in the list of disabled protect rules
|
55
|
-
return false if PROTECT.rule_config&.disabled_rules&.include?(rule_name)
|
55
|
+
return false if ::Contrast::PROTECT.rule_config&.disabled_rules&.include?(rule_name)
|
56
56
|
|
57
57
|
# 3. it is enabled so long as its mode is not NO_ACTION
|
58
58
|
@mode != Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION
|
@@ -176,7 +176,7 @@ module Contrast
|
|
176
176
|
protected
|
177
177
|
|
178
178
|
def mode_from_settings
|
179
|
-
PROTECT.rule_mode(rule_name).tap do |mode|
|
179
|
+
::Contrast::PROTECT.rule_mode(rule_name).tap do |mode|
|
180
180
|
logger.trace('Retrieving rule mode', rule: rule_name, mode: mode)
|
181
181
|
end
|
182
182
|
end
|
@@ -191,7 +191,7 @@ module Contrast
|
|
191
191
|
# @return [Boolean] if an exclusion was applicable to this request
|
192
192
|
# for this rule
|
193
193
|
def protect_excluded_by_code?
|
194
|
-
exclusions = SETTINGS.code_exclusions
|
194
|
+
exclusions = ::Contrast::SETTINGS.code_exclusions
|
195
195
|
return false unless exclusions
|
196
196
|
|
197
197
|
for_rule = exclusions.select { |ex| ex.protection_rule?(rule_name) }
|
@@ -4,7 +4,7 @@
|
|
4
4
|
require 'contrast/agent/protect/rule/base_service'
|
5
5
|
require 'contrast/utils/stack_trace_utils'
|
6
6
|
require 'contrast/utils/object_share'
|
7
|
-
require 'contrast/components/
|
7
|
+
require 'contrast/components/logger'
|
8
8
|
|
9
9
|
module Contrast
|
10
10
|
module Agent
|
@@ -12,8 +12,7 @@ module Contrast
|
|
12
12
|
module Rule
|
13
13
|
# The Ruby implementation of the Protect Command Injection rule.
|
14
14
|
class CmdInjection < Contrast::Agent::Protect::Rule::BaseService
|
15
|
-
include Contrast::Components::
|
16
|
-
access_component :app_context, :logging
|
15
|
+
include Contrast::Components::Logger::InstanceMethods
|
17
16
|
|
18
17
|
NAME = 'cmd-injection'
|
19
18
|
CHAINED_COMMAND_CHARS = /[;&|<>]/.cs__freeze
|
@@ -28,7 +27,7 @@ module Contrast
|
|
28
27
|
ia_results = gather_ia_results(context)
|
29
28
|
return if ia_results.empty?
|
30
29
|
|
31
|
-
if APP_CONTEXT.in_new_process?
|
30
|
+
if ::Contrast::APP_CONTEXT.in_new_process?
|
32
31
|
logger.trace('Running cmd-injection infilter within new process - creating new context')
|
33
32
|
context = Contrast::Agent::RequestContext.new(context.request.rack_request)
|
34
33
|
Contrast::Agent::REQUEST_TRACKER.update_current_context(context)
|
@@ -124,7 +123,7 @@ module Contrast
|
|
124
123
|
# @return [Boolean] if the agent should report all command
|
125
124
|
# executions.
|
126
125
|
def report_any_command_execution?
|
127
|
-
PROTECT.report_any_command_execution?
|
126
|
+
::Contrast::PROTECT.report_any_command_execution?
|
128
127
|
end
|
129
128
|
end
|
130
129
|
end
|