contrast-agent 3.10.2 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +5 -2
- data/ext/build_funchook.rb +13 -17
- data/ext/cs__assess_active_record_named/cs__active_record_named.c +5 -12
- data/ext/cs__assess_active_record_named/extconf.rb +3 -0
- data/ext/cs__assess_array/cs__assess_array.c +3 -5
- data/ext/cs__assess_array/extconf.rb +3 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +10 -4
- data/ext/cs__assess_basic_object/extconf.rb +3 -0
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +4 -3
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +3 -3
- data/ext/cs__assess_fiber_track/extconf.rb +3 -0
- data/ext/cs__assess_hash/cs__assess_hash.c +40 -17
- data/ext/cs__assess_hash/cs__assess_hash.h +4 -6
- data/ext/cs__assess_hash/extconf.rb +3 -0
- data/ext/cs__assess_kernel/cs__assess_kernel.c +10 -8
- data/ext/cs__assess_kernel/cs__assess_kernel.h +1 -0
- data/ext/cs__assess_kernel/extconf.rb +3 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +3 -6
- data/ext/cs__assess_marshal_module/extconf.rb +3 -0
- data/ext/cs__assess_module/cs__assess_module.c +13 -9
- data/ext/cs__assess_module/extconf.rb +3 -0
- data/ext/cs__assess_regexp/cs__assess_regexp.c +13 -9
- data/ext/cs__assess_regexp/cs__assess_regexp.h +1 -0
- data/ext/cs__assess_regexp/extconf.rb +3 -0
- data/ext/cs__assess_string/cs__assess_string.c +5 -8
- data/ext/cs__assess_string/cs__assess_string.h +2 -1
- data/ext/cs__assess_string/extconf.rb +3 -0
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +2 -2
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.h +3 -3
- data/ext/cs__assess_string_interpolation26/extconf.rb +3 -0
- data/ext/cs__assess_yield_track/cs__assess_yield_track.h +1 -1
- data/ext/cs__assess_yield_track/extconf.rb +3 -0
- data/ext/cs__common/cs__common.c +79 -0
- data/ext/cs__common/cs__common.h +34 -0
- data/ext/cs__common/extconf.rb +9 -8
- data/ext/cs__contrast_patch/cs__contrast_patch.h +1 -6
- data/ext/cs__contrast_patch/extconf.rb +3 -0
- data/ext/cs__protect_kernel/cs__protect_kernel.c +20 -11
- data/ext/cs__protect_kernel/extconf.rb +3 -0
- data/ext/extconf_common.rb +10 -8
- data/funchook/autom4te.cache/output.0 +1 -13
- data/funchook/autom4te.cache/requests +44 -45
- data/funchook/autom4te.cache/traces.0 +0 -3
- data/funchook/config.log +378 -217
- data/funchook/config.status +23 -24
- data/funchook/configure +1 -13
- data/funchook/src/Makefile +7 -7
- data/funchook/src/config.h +2 -2
- data/funchook/src/decoder.o +0 -0
- data/funchook/src/distorm.o +0 -0
- data/funchook/src/funchook.o +0 -0
- data/funchook/src/funchook_io.o +0 -0
- data/funchook/src/funchook_syscall.o +0 -0
- data/funchook/src/funchook_unix.o +0 -0
- data/funchook/src/funchook_x86.o +0 -0
- data/funchook/src/instructions.o +0 -0
- data/funchook/src/insts.o +0 -0
- data/funchook/src/libfunchook.dylib +0 -0
- data/funchook/src/mnemonics.o +0 -0
- data/funchook/src/operands.o +0 -0
- data/funchook/src/os_func.o +0 -0
- data/funchook/src/os_func_unix.o +0 -0
- data/funchook/src/prefix.o +0 -0
- data/funchook/src/printf_base.o +0 -0
- data/funchook/src/textdefs.o +0 -0
- data/funchook/src/wstring.o +0 -0
- data/funchook/test/Makefile +2 -2
- data/funchook/test/funchook_test +0 -0
- data/funchook/test/libfunchook_test.so +0 -0
- data/funchook/test/libfunchook_test.so.dSYM/Contents/Info.plist +20 -0
- data/funchook/test/libfunchook_test.so.dSYM/Contents/Resources/DWARF/libfunchook_test.so +0 -0
- data/funchook/test/test_main.o +0 -0
- data/funchook/test/x86_64_test.o +0 -0
- data/lib/contrast.rb +1 -0
- data/lib/contrast/agent.rb +21 -15
- data/lib/contrast/agent/assess.rb +1 -2
- data/lib/contrast/agent/assess/adjusted_span.rb +3 -1
- data/lib/contrast/agent/assess/contrast_event.rb +16 -62
- data/lib/contrast/agent/assess/events/event_factory.rb +25 -0
- data/lib/contrast/agent/assess/events/source_event.rb +83 -0
- data/lib/contrast/agent/assess/insulator.rb +0 -4
- data/lib/contrast/agent/assess/policy/patcher.rb +5 -2
- data/lib/contrast/agent/assess/policy/policy_node.rb +0 -7
- 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 +65 -33
- data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -1
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +80 -0
- data/lib/contrast/agent/assess/policy/propagator/select.rb +35 -22
- data/lib/contrast/agent/assess/policy/propagator/split.rb +26 -6
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +2 -0
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +37 -26
- data/lib/contrast/agent/assess/policy/source_method.rb +20 -20
- data/lib/contrast/agent/assess/policy/source_node.rb +0 -15
- data/lib/contrast/agent/assess/policy/trigger_method.rb +29 -40
- data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -6
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -31
- data/lib/contrast/agent/assess/properties.rb +5 -3
- data/lib/contrast/agent/assess/rule/base.rb +1 -5
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +2 -22
- data/lib/contrast/agent/assess/rule/csrf/csrf_watcher.rb +5 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +2 -2
- data/lib/contrast/agent/assess/rule/redos.rb +4 -4
- data/lib/contrast/agent/assess/tag.rb +24 -14
- data/lib/contrast/agent/at_exit_hook.rb +16 -13
- data/lib/contrast/agent/class_reopener.rb +14 -4
- data/lib/contrast/agent/deadzone/policy/policy.rb +2 -2
- data/lib/contrast/agent/disable_reaction.rb +3 -4
- data/lib/contrast/agent/exclusion_matcher.rb +8 -48
- data/lib/contrast/agent/feature_state.rb +45 -75
- data/lib/contrast/agent/logger.rb +173 -0
- data/lib/contrast/agent/middleware.rb +87 -250
- data/lib/contrast/agent/module_data.rb +2 -1
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +2 -1
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +21 -4
- data/lib/contrast/agent/patching/policy/method_policy.rb +3 -3
- data/lib/contrast/agent/patching/policy/module_policy.rb +0 -25
- data/lib/contrast/agent/patching/policy/patch.rb +96 -23
- data/lib/contrast/agent/patching/policy/patcher.rb +19 -19
- data/lib/contrast/agent/patching/policy/policy.rb +7 -7
- data/lib/contrast/agent/patching/policy/policy_node.rb +2 -10
- data/lib/contrast/agent/patching/policy/trigger_node.rb +1 -4
- data/lib/contrast/agent/protect/rule/base.rb +14 -33
- data/lib/contrast/agent/protect/rule/base_service.rb +3 -1
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +10 -13
- data/lib/contrast/agent/protect/rule/csrf.rb +2 -1
- data/lib/contrast/agent/protect/rule/csrf/csrf_evaluator.rb +11 -14
- data/lib/contrast/agent/protect/rule/default_scanner.rb +0 -13
- data/lib/contrast/agent/protect/rule/deserialization.rb +2 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +2 -2
- data/lib/contrast/agent/protect/rule/no_sqli.rb +4 -4
- data/lib/contrast/agent/protect/rule/path_traversal.rb +5 -4
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +2 -0
- data/lib/contrast/agent/protect/rule/xss.rb +2 -0
- data/lib/contrast/agent/protect/rule/xxe.rb +10 -4
- data/lib/contrast/agent/railtie.rb +2 -8
- data/lib/contrast/agent/reaction_processor.rb +5 -5
- data/lib/contrast/agent/request.rb +9 -12
- data/lib/contrast/agent/request_context.rb +12 -14
- data/lib/contrast/agent/request_handler.rb +35 -0
- data/lib/contrast/agent/response.rb +33 -30
- data/lib/contrast/agent/rewriter.rb +22 -10
- data/lib/contrast/agent/rule_set.rb +49 -0
- data/lib/contrast/agent/scope.rb +0 -6
- data/lib/contrast/agent/service_heartbeat.rb +1 -2
- data/lib/contrast/agent/settings_state.rb +10 -74
- data/lib/contrast/agent/socket_client.rb +17 -11
- data/lib/contrast/agent/static_analysis.rb +42 -0
- data/lib/contrast/agent/thread.rb +1 -1
- data/lib/contrast/agent/tracepoint_hook.rb +1 -5
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api.rb +1 -1
- data/lib/contrast/api/decorators.rb +14 -0
- data/lib/contrast/api/decorators/application_settings.rb +37 -0
- data/lib/contrast/api/decorators/application_update.rb +66 -0
- data/lib/contrast/api/decorators/exclusion.rb +20 -0
- data/lib/contrast/api/decorators/input_analysis.rb +17 -0
- data/lib/contrast/api/decorators/server_features.rb +24 -0
- data/lib/contrast/api/speedracer.rb +27 -23
- data/lib/contrast/api/tcp_socket.rb +0 -2
- data/lib/contrast/components/agent.rb +27 -22
- data/lib/contrast/components/app_context.rb +18 -43
- data/lib/contrast/components/config.rb +7 -5
- data/lib/contrast/components/contrast_service.rb +0 -4
- data/lib/contrast/components/heap_dump.rb +12 -8
- data/lib/contrast/components/interface.rb +11 -10
- data/lib/contrast/components/logger.rb +3 -68
- data/lib/contrast/components/sampling.rb +22 -11
- data/lib/contrast/components/settings.rb +18 -5
- data/lib/contrast/config/base_configuration.rb +1 -0
- data/lib/contrast/config/default_value.rb +1 -0
- data/lib/contrast/config/protect_rule_configuration.rb +0 -14
- data/lib/contrast/extensions/framework/rails/action_controller_inheritance.rb +39 -0
- data/lib/contrast/extensions/framework/rails/active_record_named.rb +13 -8
- data/lib/contrast/extensions/ruby_core/assess.rb +1 -2
- data/lib/contrast/extensions/ruby_core/assess/assess_extension.rb +27 -22
- data/lib/contrast/extensions/ruby_core/assess/erb.rb +0 -8
- data/lib/contrast/extensions/ruby_core/assess/exec_trigger.rb +6 -8
- data/lib/contrast/extensions/ruby_core/assess/fiber.rb +88 -100
- data/lib/contrast/extensions/ruby_core/assess/hash.rb +32 -15
- data/lib/contrast/extensions/ruby_core/assess/kernel.rb +28 -27
- data/lib/contrast/extensions/ruby_core/assess/regexp.rb +74 -196
- data/lib/contrast/extensions/ruby_core/assess/string.rb +15 -7
- data/lib/contrast/extensions/ruby_core/assess/tilt_template_trigger.rb +29 -24
- data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +2 -2
- data/lib/contrast/extensions/ruby_core/eval_trigger.rb +0 -1
- data/lib/contrast/extensions/ruby_core/inventory/datastores.rb +2 -2
- data/lib/contrast/extensions/ruby_core/protect/applies_command_injection_rule.rb +9 -20
- data/lib/contrast/extensions/ruby_core/protect/applies_deserialization_rule.rb +9 -19
- data/lib/contrast/extensions/ruby_core/protect/applies_no_sqli_rule.rb +10 -27
- data/lib/contrast/extensions/ruby_core/protect/applies_path_traversal_rule.rb +13 -21
- data/lib/contrast/extensions/ruby_core/protect/applies_sqli_rule.rb +11 -23
- data/lib/contrast/extensions/ruby_core/protect/applies_xxe_rule.rb +62 -78
- data/lib/contrast/extensions/ruby_core/protect/rule_applicator.rb +50 -0
- data/lib/contrast/framework/base_support.rb +10 -0
- data/lib/contrast/framework/manager.rb +28 -2
- data/lib/contrast/framework/platform_version.rb +1 -0
- data/lib/contrast/framework/rails_support.rb +16 -0
- data/lib/contrast/framework/sinatra_support.rb +12 -2
- data/lib/contrast/framework/view_technologies_descriptor.rb +1 -0
- data/lib/contrast/tasks/service.rb +2 -8
- data/lib/contrast/utils/assess/sampling_util.rb +4 -9
- data/lib/contrast/utils/assess/tracking_util.rb +7 -1
- data/lib/contrast/utils/boolean_util.rb +2 -2
- data/lib/contrast/utils/cache.rb +0 -11
- data/lib/contrast/utils/class_util.rb +20 -1
- data/lib/contrast/utils/gemfile_reader.rb +5 -3
- data/lib/contrast/utils/hash_digest.rb +0 -4
- data/lib/contrast/utils/heap_dump_util.rb +12 -11
- data/lib/contrast/utils/invalid_configuration_util.rb +1 -1
- data/lib/contrast/utils/inventory_util.rb +2 -2
- data/lib/contrast/utils/io_util.rb +1 -11
- data/lib/contrast/utils/job_servers_running.rb +2 -2
- data/lib/contrast/utils/object_share.rb +1 -27
- data/lib/contrast/utils/os.rb +1 -25
- data/lib/contrast/utils/rack_assess_session_cookie.rb +3 -3
- data/lib/contrast/utils/rails_assess_configuration.rb +3 -3
- data/lib/contrast/utils/service_response_util.rb +27 -53
- data/lib/contrast/utils/service_sender_util.rb +9 -5
- data/lib/contrast/utils/sinatra_helper.rb +0 -6
- data/lib/contrast/utils/stack_trace_utils.rb +86 -182
- data/lib/contrast/utils/string_utils.rb +18 -2
- data/lib/contrast/utils/tag_util.rb +11 -1
- data/lib/contrast/utils/thread_tracker.rb +2 -2
- data/lib/contrast/utils/timer.rb +0 -40
- data/resources/assess/policy.json +33 -21
- data/resources/protect/policy.json +9 -9
- data/ruby-agent.gemspec +6 -3
- metadata +76 -51
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.c +0 -63
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.h +0 -29
- data/ext/cs__assess_regexp_track/extconf.rb +0 -2
- data/funchook/src/libfunchook.so +0 -0
- data/lib/contrast/agent/assess/frozen_properties.rb +0 -41
- data/lib/contrast/agent/logger_manager.rb +0 -116
- data/lib/contrast/delegators.rb +0 -9
- data/lib/contrast/delegators/application_update.rb +0 -32
- data/lib/contrast/utils/comment_range.rb +0 -19
- data/lib/contrast/utils/environment_util.rb +0 -81
- data/lib/contrast/utils/performs_logging.rb +0 -152
- data/resources/factory-bot-spec/spec_helper.rb +0 -30
- data/resources/rubocops/kernel/catch_cop.rb +0 -37
- data/resources/rubocops/kernel/require_cop.rb +0 -37
- data/resources/rubocops/kernel/require_relative_cop.rb +0 -33
- data/resources/rubocops/module/autoload_cop.rb +0 -37
- data/resources/rubocops/module/const_defined_cop.rb +0 -37
- data/resources/rubocops/module/const_get_cop.rb +0 -37
- data/resources/rubocops/module/const_set_cop.rb +0 -37
- data/resources/rubocops/module/constants_cop.rb +0 -37
- data/resources/rubocops/module/name_cop.rb +0 -37
- data/resources/rubocops/object/class_cop.rb +0 -37
- data/resources/rubocops/object/freeze_cop.rb +0 -37
- data/resources/rubocops/object/frozen_cop.rb +0 -37
- data/resources/rubocops/object/is_a_cop.rb +0 -37
- data/resources/rubocops/object/method_cop.rb +0 -37
- data/resources/rubocops/object/respond_to_cop.rb +0 -37
- data/resources/rubocops/object/singleton_class_cop.rb +0 -37
- data/resources/rubocops/regexp/spelling_cop.rb +0 -44
- data/resources/rubocops/thread/new_cop.rb +0 -39
- data/resources/ruby-spec/ancestors_spec.rb +0 -70
- data/resources/ruby-spec/modulo_spec.rb +0 -831
- data/resources/ruby-spec/parameters_spec.rb +0 -261
- data/resources/ruby-spec/ruby_spec_spec_helper.rb +0 -35
@@ -1,10 +1,12 @@
|
|
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/agent/assess/policy/propagation_node'
|
4
5
|
cs__scoped_require 'contrast/components/interface'
|
6
|
+
cs__scoped_require 'contrast/extensions/ruby_core/assess/assess_extension'
|
5
7
|
|
6
8
|
# This patch installs our extension as early as possible. The alternative is to
|
7
|
-
# litter our code with
|
9
|
+
# litter our code with Contrast::Utils::DuckUtils.trackable? checks.
|
8
10
|
class String
|
9
11
|
include Contrast::CoreExtensions::Assess::AssessExtension
|
10
12
|
end
|
@@ -19,7 +21,7 @@ module Contrast
|
|
19
21
|
class StringPropagator
|
20
22
|
include Contrast::Components::Interface
|
21
23
|
|
22
|
-
access_component :
|
24
|
+
access_component :agent, :analysis, :logging, :scope
|
23
25
|
|
24
26
|
NODE_HASH = {
|
25
27
|
'class_name' => 'String',
|
@@ -50,6 +52,16 @@ module Contrast
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
55
|
+
def instrument_string
|
56
|
+
@_instrument_string ||= begin
|
57
|
+
cs__scoped_require 'cs__assess_string/cs__assess_string'
|
58
|
+
true
|
59
|
+
end
|
60
|
+
rescue StandardError => e
|
61
|
+
logger.error('Error loading hash track patch', e)
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
53
65
|
def instrument_string_interpolation
|
54
66
|
if @_instrument_string_interpolation.nil?
|
55
67
|
@_instrument_string_interpolation = begin
|
@@ -58,7 +70,7 @@ module Contrast
|
|
58
70
|
end
|
59
71
|
true
|
60
72
|
rescue StandardError => e
|
61
|
-
logger.error(
|
73
|
+
logger.error('Error loading interpolation patch', e)
|
62
74
|
false
|
63
75
|
end
|
64
76
|
end
|
@@ -69,7 +81,3 @@ module Contrast
|
|
69
81
|
end
|
70
82
|
end
|
71
83
|
end
|
72
|
-
|
73
|
-
cs__scoped_require 'cs__assess_string/cs__assess_string'
|
74
|
-
|
75
|
-
Contrast::CoreExtensions::Assess::StringPropagator.instrument_string_interpolation
|
@@ -1,11 +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/components/interface'
|
5
4
|
# This module acts a trigger & propagator for Tilt::Template evaluation
|
6
5
|
module TiltTemplateTrigger
|
7
|
-
include Contrast::Components::Interface
|
8
|
-
access_component :logging
|
9
6
|
class << self
|
10
7
|
NODE_HASH = {
|
11
8
|
'class_name' => 'Tilt::Template',
|
@@ -20,13 +17,36 @@ module TiltTemplateTrigger
|
|
20
17
|
}.cs__freeze
|
21
18
|
TEMPLATE_PROPAGATION_NODE = Contrast::Agent::Assess::Policy::PropagationNode.new(NODE_HASH)
|
22
19
|
|
23
|
-
def render_trigger_check context, trigger_node, _source, object, ret,
|
24
|
-
logger.debug { 'Tilt::Template Trigger - running propagation' }
|
25
|
-
|
20
|
+
def render_trigger_check context, trigger_node, _source, object, ret, *args
|
26
21
|
scope = args[0]
|
27
|
-
|
22
|
+
|
28
23
|
erb_template_prerender = object.instance_variable_get(:@data)
|
29
24
|
interpolated_inputs = []
|
25
|
+
handle_binding_variables(scope, erb_template_prerender, ret, interpolated_inputs)
|
26
|
+
|
27
|
+
handle_local_variables(args, erb_template_prerender, ret, interpolated_inputs)
|
28
|
+
|
29
|
+
unless interpolated_inputs.empty?
|
30
|
+
interpolated_inputs.each do |input|
|
31
|
+
input.cs__properties.events.each do |event|
|
32
|
+
ret.cs__properties.events << event
|
33
|
+
end
|
34
|
+
end
|
35
|
+
ret.cs__properties.build_event(TEMPLATE_PROPAGATION_NODE, ret, erb_template_prerender, ret, interpolated_inputs)
|
36
|
+
end
|
37
|
+
|
38
|
+
if ret.cs__tracked?
|
39
|
+
Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(context, trigger_node, ret, erb_template_prerender, ret, interpolated_inputs)
|
40
|
+
end
|
41
|
+
|
42
|
+
ret
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def handle_binding_variables scope, erb_template_prerender, ret, interpolated_inputs
|
48
|
+
binding_variables = scope.instance_variables
|
49
|
+
|
30
50
|
binding_variables.each do |bound_variable_sym|
|
31
51
|
bound_variable_value = scope.instance_variable_get(bound_variable_sym)
|
32
52
|
|
@@ -36,11 +56,12 @@ module TiltTemplateTrigger
|
|
36
56
|
start_index = ret.index(bound_variable_value)
|
37
57
|
next if start_index.nil?
|
38
58
|
|
39
|
-
logger.debug('Tilt::Template Trigger - found bound_variable in erb template result')
|
40
59
|
ret.cs__copy_from(bound_variable_value, start_index)
|
41
60
|
interpolated_inputs << bound_variable_sym
|
42
61
|
end
|
62
|
+
end
|
43
63
|
|
64
|
+
def handle_local_variables args, erb_template_prerender, ret, interpolated_inputs
|
44
65
|
locals = args[1]
|
45
66
|
locals.each do |local_name, local_value|
|
46
67
|
next unless local_value.cs__respond_to?(:cs__tracked?) && local_value.cs__tracked?
|
@@ -49,25 +70,9 @@ module TiltTemplateTrigger
|
|
49
70
|
start_index = ret.index(local_value)
|
50
71
|
next if start_index.nil?
|
51
72
|
|
52
|
-
logger.debug('Tilt:Template Trigger - found local_value in erb template result')
|
53
73
|
ret.cs__copy_from(local_value, start_index)
|
54
74
|
interpolated_inputs << local_name
|
55
75
|
end
|
56
|
-
|
57
|
-
unless interpolated_inputs.empty?
|
58
|
-
interpolated_inputs.each do |input|
|
59
|
-
input.cs__properties.events.each do |event|
|
60
|
-
ret.cs__properties.events << event
|
61
|
-
end
|
62
|
-
end
|
63
|
-
ret.cs__properties.build_event(TEMPLATE_PROPAGATION_NODE, ret, erb_template_prerender, ret, interpolated_inputs, invoked + 1)
|
64
|
-
end
|
65
|
-
|
66
|
-
if ret.cs__tracked?
|
67
|
-
Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(context, trigger_node, ret, erb_template_prerender, ret, invoked + 1, interpolated_inputs)
|
68
|
-
end
|
69
|
-
|
70
|
-
ret
|
71
76
|
end
|
72
77
|
end
|
73
78
|
end
|
@@ -12,7 +12,7 @@ module XPathLibraryTrigger
|
|
12
12
|
include Contrast::Components::Interface
|
13
13
|
|
14
14
|
class << self
|
15
|
-
def xpath_trigger_check context, trigger_node, _source, object, ret,
|
15
|
+
def xpath_trigger_check context, trigger_node, _source, object, ret, *args
|
16
16
|
return ret unless args
|
17
17
|
|
18
18
|
# convert the options arg in Oga::XML::CharacterNode#initialize into an
|
@@ -25,7 +25,7 @@ module XPathLibraryTrigger
|
|
25
25
|
next unless trigger_node.violated?(arg)
|
26
26
|
|
27
27
|
Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(
|
28
|
-
context, trigger_node, arg, object, ret,
|
28
|
+
context, trigger_node, arg, object, ret, args)
|
29
29
|
end
|
30
30
|
|
31
31
|
ret
|
@@ -15,7 +15,7 @@ module Contrast
|
|
15
15
|
class << self
|
16
16
|
include Contrast::Components::Interface
|
17
17
|
|
18
|
-
access_component :
|
18
|
+
access_component :analysis, :logging
|
19
19
|
# The key used in policy.json to indicate the database type to
|
20
20
|
# report.
|
21
21
|
DATA_STORE_MARKER = 'data_store'
|
@@ -28,7 +28,7 @@ module Contrast
|
|
28
28
|
|
29
29
|
Contrast::Utils::DataStoreUtil.report_data_store(marker)
|
30
30
|
rescue StandardError => e
|
31
|
-
logger.error(
|
31
|
+
logger.error('Error reporting database call', e, object: object)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -1,8 +1,9 @@
|
|
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/
|
4
|
+
cs__scoped_require 'contrast/agent/protect/rule/cmd_injection'
|
5
5
|
cs__scoped_require 'contrast/extensions/ruby_core/protect/applies_deserialization_rule'
|
6
|
+
cs__scoped_require 'contrast/extensions/ruby_core/protect/rule_applicator'
|
6
7
|
|
7
8
|
module Contrast
|
8
9
|
module CoreExtensions
|
@@ -16,13 +17,12 @@ module Contrast
|
|
16
17
|
# {#apply_deserialization_command_check} method of the
|
17
18
|
# Deserialization applicator.
|
18
19
|
module AppliesCommandInjectionRule
|
20
|
+
extend Contrast::CoreExtensions::Protect::RuleApplicator
|
21
|
+
|
19
22
|
CS__SEMICOLON = '; '
|
20
23
|
|
21
24
|
class << self
|
22
|
-
|
23
|
-
access_component :logging, :analysis
|
24
|
-
|
25
|
-
def apply_command_injection_rule method, _exception, _properties, object, args
|
25
|
+
def invoke method, _exception, _properties, object, args
|
26
26
|
return unless valid_command?(args)
|
27
27
|
|
28
28
|
command = build_command(args)
|
@@ -34,26 +34,15 @@ module Contrast
|
|
34
34
|
class_name = clazz.cs__name
|
35
35
|
rule.infilter(Contrast::Agent::REQUEST_TRACKER.current, class_name, method, command)
|
36
36
|
end
|
37
|
-
rescue Contrast::SecurityException => e
|
38
|
-
raise e
|
39
|
-
rescue StandardError => e
|
40
|
-
msg = "command injection: class=#{ object }.#{ method }"
|
41
|
-
logger.error(e, msg)
|
42
37
|
end
|
43
38
|
|
44
|
-
|
39
|
+
protected
|
45
40
|
|
46
|
-
def
|
47
|
-
|
41
|
+
def name
|
42
|
+
Contrast::Agent::Protect::Rule::CmdInjection::NAME
|
48
43
|
end
|
49
44
|
|
50
|
-
|
51
|
-
context = Contrast::Agent::REQUEST_TRACKER.current
|
52
|
-
return true unless context&.app_loaded?
|
53
|
-
return true unless rule&.enabled?
|
54
|
-
|
55
|
-
false
|
56
|
-
end
|
45
|
+
private
|
57
46
|
|
58
47
|
def valid_command? command
|
59
48
|
command && (command.is_a?(String) || command.is_a?(Array))
|
@@ -1,7 +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/
|
4
|
+
cs__scoped_require 'contrast/agent/protect/rule/deserialization'
|
5
|
+
cs__scoped_require 'contrast/extensions/ruby_core/protect/rule_applicator'
|
5
6
|
|
6
7
|
module Contrast
|
7
8
|
module CoreExtensions
|
@@ -11,19 +12,14 @@ module Contrast
|
|
11
12
|
# It is responsible for deciding if the infilter methods of the rule
|
12
13
|
# should be invoked.
|
13
14
|
module AppliesDeserializationRule
|
14
|
-
|
15
|
-
access_component :logging, :analysis
|
15
|
+
extend Contrast::CoreExtensions::Protect::RuleApplicator
|
16
16
|
|
17
17
|
class << self
|
18
|
-
def
|
18
|
+
def invoke _method, _exception, _properties, _object, args
|
19
19
|
return unless valid_input?(args)
|
20
20
|
return if skip_analysis?
|
21
21
|
|
22
22
|
rule.infilter(Contrast::Agent::REQUEST_TRACKER.current, args[0])
|
23
|
-
rescue Contrast::SecurityException => e
|
24
|
-
raise e
|
25
|
-
rescue StandardError => e
|
26
|
-
logger.error(e, "Error running untrusted-deserialization rule in #{ object }.#{ method }")
|
27
23
|
end
|
28
24
|
|
29
25
|
def apply_deserialization_command_check command
|
@@ -33,26 +29,20 @@ module Contrast
|
|
33
29
|
rule.check_command_scope(command)
|
34
30
|
end
|
35
31
|
|
36
|
-
|
32
|
+
protected
|
37
33
|
|
38
|
-
def
|
39
|
-
|
34
|
+
def name
|
35
|
+
Contrast::Agent::Protect::Rule::Deserialization::NAME
|
40
36
|
end
|
41
37
|
|
38
|
+
private
|
39
|
+
|
42
40
|
def valid_input? args
|
43
41
|
return false unless args&.any?
|
44
42
|
|
45
43
|
input = args[0]
|
46
44
|
input.is_a?(String)
|
47
45
|
end
|
48
|
-
|
49
|
-
def skip_analysis?
|
50
|
-
context = Contrast::Agent::REQUEST_TRACKER.current
|
51
|
-
return true unless context&.app_loaded?
|
52
|
-
return true unless rule&.enabled?
|
53
|
-
|
54
|
-
false
|
55
|
-
end
|
56
46
|
end
|
57
47
|
end
|
58
48
|
end
|
@@ -1,7 +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/
|
4
|
+
cs__scoped_require 'contrast/agent/protect/rule/no_sqli'
|
5
|
+
cs__scoped_require 'contrast/extensions/ruby_core/protect/rule_applicator'
|
5
6
|
|
6
7
|
module Contrast
|
7
8
|
module CoreExtensions
|
@@ -11,17 +12,10 @@ module Contrast
|
|
11
12
|
# based NoSQL queries occur. It is responsible for deciding if the
|
12
13
|
# infilter methods of the rule should be invoked.
|
13
14
|
module AppliesNoSqliRule
|
14
|
-
|
15
|
-
ACTION_DISPATCH = 'dispatch'
|
16
|
-
ACTION_READ = 'read'
|
17
|
-
ACTION_WRITE = 'write'
|
18
|
-
ACTION_PROCESS = 'process'
|
15
|
+
extend Contrast::CoreExtensions::Protect::RuleApplicator
|
19
16
|
|
20
17
|
class << self
|
21
|
-
|
22
|
-
access_component :logging, :analysis
|
23
|
-
|
24
|
-
def apply_nosql_rule method, _exception, properties, _object, args
|
18
|
+
def invoke method, _exception, properties, _object, args
|
25
19
|
return unless valid_input?(args)
|
26
20
|
return if skip_analysis?
|
27
21
|
|
@@ -35,37 +29,26 @@ module Contrast
|
|
35
29
|
else
|
36
30
|
handle_operation(context, database, method, operations)
|
37
31
|
end
|
38
|
-
rescue Contrast::SecurityException => e
|
39
|
-
raise e
|
40
|
-
rescue StandardError => e
|
41
|
-
logger.error(e, "Error running NoSQLi rule in #{ properties['database'] }")
|
42
32
|
end
|
43
33
|
|
44
|
-
|
34
|
+
protected
|
45
35
|
|
46
|
-
def
|
47
|
-
|
36
|
+
def name
|
37
|
+
Contrast::Agent::Protect::Rule::NoSqli::NAME
|
48
38
|
end
|
49
39
|
|
40
|
+
private
|
41
|
+
|
50
42
|
def valid_input? args
|
51
43
|
return false unless args&.any?
|
52
44
|
|
53
45
|
args[0]
|
54
46
|
end
|
55
47
|
|
56
|
-
def
|
57
|
-
context = Contrast::Agent::REQUEST_TRACKER.current
|
58
|
-
return true unless context&.app_loaded?
|
59
|
-
return true unless rule&.enabled?
|
60
|
-
|
61
|
-
false
|
62
|
-
end
|
63
|
-
|
64
|
-
def handle_operation context, database, action, operation
|
48
|
+
def handle_operation context, database, _action, operation
|
65
49
|
data = extract_mongo_data(operation)
|
66
50
|
return unless data && !data.empty?
|
67
51
|
|
68
|
-
logger.debug(nil, "applying nosqli rule #{ database }##{ action }")
|
69
52
|
rule.infilter(context, database, data)
|
70
53
|
end
|
71
54
|
|
@@ -1,8 +1,9 @@
|
|
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/agent/protect/rule/path_traversal'
|
5
|
+
cs__scoped_require 'contrast/extensions/ruby_core/protect/rule_applicator'
|
4
6
|
cs__scoped_require 'contrast/utils/object_share'
|
5
|
-
cs__scoped_require 'contrast/components/interface'
|
6
7
|
|
7
8
|
module Contrast
|
8
9
|
module CoreExtensions
|
@@ -12,12 +13,10 @@ module Contrast
|
|
12
13
|
# It is responsible for deciding if the infilter methods of the rule
|
13
14
|
# should be invoked.
|
14
15
|
module AppliesPathTraversalRule
|
15
|
-
|
16
|
-
|
17
|
-
access_component :logging, :analysis
|
16
|
+
extend Contrast::CoreExtensions::Protect::RuleApplicator
|
18
17
|
|
19
18
|
class << self
|
20
|
-
def
|
19
|
+
def invoke method, _exception, properties, object, args
|
21
20
|
return unless args&.any?
|
22
21
|
|
23
22
|
path = args[0]
|
@@ -27,7 +26,7 @@ module Contrast
|
|
27
26
|
action = properties['action']
|
28
27
|
write_marker = write?(action, *args)
|
29
28
|
possible_write = write_marker && possible_write(write_marker)
|
30
|
-
path_traversal_rule(path, possible_write, method)
|
29
|
+
path_traversal_rule(path, possible_write, object, method)
|
31
30
|
|
32
31
|
# If the action was copy, we need to handle the write half of it.
|
33
32
|
# We handled read in line above.
|
@@ -37,28 +36,22 @@ module Contrast
|
|
37
36
|
dst = args[1]
|
38
37
|
return unless dst.is_a?(String)
|
39
38
|
|
40
|
-
path_traversal_rule(dst, true, method)
|
39
|
+
path_traversal_rule(dst, true, object, method)
|
41
40
|
end
|
42
41
|
|
43
|
-
|
42
|
+
protected
|
44
43
|
|
45
|
-
def
|
46
|
-
|
44
|
+
def name
|
45
|
+
Contrast::Agent::Protect::Rule::PathTraversal::NAME
|
47
46
|
end
|
48
47
|
|
48
|
+
private
|
49
|
+
|
49
50
|
def possible_write input
|
50
51
|
input.cs__respond_to?(:to_s) &&
|
51
52
|
input.to_s.include?(Contrast::Utils::ObjectShare::WRITE_FLAG)
|
52
53
|
end
|
53
54
|
|
54
|
-
def skip_analysis?
|
55
|
-
context = Contrast::Agent::REQUEST_TRACKER.current
|
56
|
-
return true unless context&.app_loaded?
|
57
|
-
return true unless rule&.enabled?
|
58
|
-
|
59
|
-
false
|
60
|
-
end
|
61
|
-
|
62
55
|
READ = 'read'
|
63
56
|
WRITE = 'write'
|
64
57
|
COPY = 'copy'
|
@@ -71,15 +64,14 @@ module Contrast
|
|
71
64
|
write_marker && possible_write(write_marker)
|
72
65
|
end
|
73
66
|
|
74
|
-
def path_traversal_rule path, possible_write, method
|
67
|
+
def path_traversal_rule path, possible_write, object, method
|
75
68
|
return unless applies_to?(path, possible_write)
|
76
69
|
|
77
|
-
logger.debug(nil, "checking path traversal: write=true path=#{ path }")
|
78
70
|
rule.infilter(Contrast::Agent::REQUEST_TRACKER.current, method, path)
|
79
71
|
rescue Contrast::SecurityException => e
|
80
72
|
raise e
|
81
73
|
rescue StandardError => e
|
82
|
-
logger.error(
|
74
|
+
logger.error('Error applying path traversal', e, module: object.cs__class.cs__name, method: method)
|
83
75
|
end
|
84
76
|
|
85
77
|
CS__SAFER_REL_PATHS = %w[public app log tmp].cs__freeze
|