contrast-agent 4.3.2 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitmodules +1 -1
- data/.simplecov +1 -1
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/Rakefile +2 -3
- data/exe/contrast_service +1 -1
- data/ext/build_funchook.rb +4 -4
- data/ext/cs__assess_active_record_named/cs__active_record_named.c +1 -1
- data/ext/cs__assess_active_record_named/extconf.rb +1 -1
- data/ext/cs__assess_array/cs__assess_array.c +1 -1
- data/ext/cs__assess_array/extconf.rb +1 -1
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +1 -1
- data/ext/cs__assess_basic_object/extconf.rb +1 -1
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
- data/ext/cs__assess_fiber_track/extconf.rb +1 -1
- data/ext/cs__assess_hash/cs__assess_hash.c +4 -2
- data/ext/cs__assess_hash/extconf.rb +1 -1
- data/ext/cs__assess_kernel/cs__assess_kernel.c +1 -1
- data/ext/cs__assess_kernel/extconf.rb +1 -1
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +1 -1
- data/ext/cs__assess_marshal_module/extconf.rb +1 -1
- data/ext/cs__assess_module/cs__assess_module.c +1 -1
- data/ext/cs__assess_module/extconf.rb +1 -1
- data/ext/cs__assess_regexp/cs__assess_regexp.c +1 -1
- data/ext/cs__assess_regexp/extconf.rb +1 -1
- data/ext/cs__assess_string/cs__assess_string.c +1 -1
- data/ext/cs__assess_string/extconf.rb +1 -1
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +1 -1
- data/ext/cs__assess_string_interpolation26/extconf.rb +1 -1
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +1 -1
- data/ext/cs__assess_yield_track/extconf.rb +1 -1
- data/ext/cs__common/cs__common.c +5 -5
- data/ext/cs__common/cs__common.h +4 -4
- data/ext/cs__common/extconf.rb +1 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.c +22 -25
- data/ext/cs__contrast_patch/extconf.rb +1 -1
- data/ext/cs__protect_kernel/cs__protect_kernel.c +1 -1
- data/ext/cs__protect_kernel/extconf.rb +1 -1
- data/ext/extconf_common.rb +2 -6
- data/lib/contrast-agent.rb +1 -1
- data/lib/contrast.rb +20 -1
- data/lib/contrast/agent.rb +6 -4
- data/lib/contrast/agent/assess.rb +2 -11
- data/lib/contrast/agent/assess/contrast_event.rb +54 -71
- data/lib/contrast/agent/assess/contrast_object.rb +7 -4
- data/lib/contrast/agent/assess/events/event_factory.rb +3 -2
- data/lib/contrast/agent/assess/events/source_event.rb +7 -2
- data/lib/contrast/agent/assess/finalizers/freeze.rb +1 -1
- data/lib/contrast/agent/assess/finalizers/hash.rb +33 -34
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +34 -16
- data/lib/contrast/agent/assess/policy/patcher.rb +11 -18
- data/lib/contrast/agent/assess/policy/policy.rb +1 -1
- data/lib/contrast/agent/assess/policy/policy_node.rb +26 -34
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
- data/lib/contrast/agent/assess/policy/preshift.rb +4 -2
- data/lib/contrast/agent/assess/policy/propagation_method.rb +32 -30
- data/lib/contrast/agent/assess/policy/propagation_node.rb +20 -9
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/append.rb +29 -14
- data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/center.rb +3 -2
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +22 -17
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +4 -2
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +3 -2
- data/lib/contrast/agent/assess/policy/propagator/next.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/prepend.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +23 -19
- data/lib/contrast/agent/assess/policy/propagator/replace.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/reverse.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/select.rb +3 -13
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +24 -14
- data/lib/contrast/agent/assess/policy/propagator/split.rb +18 -15
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +32 -22
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +64 -45
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +7 -4
- data/lib/contrast/agent/assess/policy/source_method.rb +92 -81
- data/lib/contrast/agent/assess/policy/source_node.rb +1 -1
- data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +8 -6
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +2 -4
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +7 -3
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +7 -8
- data/lib/contrast/agent/assess/policy/trigger_method.rb +109 -76
- data/lib/contrast/agent/assess/policy/trigger_node.rb +33 -11
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +60 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +3 -5
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +7 -5
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +4 -13
- data/lib/contrast/agent/assess/properties.rb +1 -3
- data/lib/contrast/agent/assess/property/evented.rb +9 -6
- data/lib/contrast/agent/assess/property/tagged.rb +38 -20
- data/lib/contrast/agent/assess/property/updated.rb +1 -1
- data/lib/contrast/agent/assess/rule/provider.rb +1 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +12 -6
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +5 -2
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +4 -6
- data/lib/contrast/agent/assess/tag.rb +1 -1
- data/lib/contrast/agent/assess/tracker.rb +2 -2
- data/lib/contrast/agent/at_exit_hook.rb +1 -1
- data/lib/contrast/agent/class_reopener.rb +4 -2
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +1 -1
- data/lib/contrast/agent/deadzone/policy/policy.rb +7 -3
- data/lib/contrast/agent/disable_reaction.rb +2 -4
- data/lib/contrast/agent/exclusion_matcher.rb +6 -12
- data/lib/contrast/agent/inventory.rb +1 -2
- data/lib/contrast/agent/inventory/dependencies.rb +3 -1
- data/lib/contrast/agent/inventory/dependency_analysis.rb +1 -1
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +35 -23
- data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/inventory/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/middleware.rb +111 -110
- data/lib/contrast/agent/module_data.rb +4 -4
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +1 -1
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +9 -4
- data/lib/contrast/agent/patching/policy/method_policy.rb +7 -3
- data/lib/contrast/agent/patching/policy/module_policy.rb +15 -8
- data/lib/contrast/agent/patching/policy/patch.rb +23 -29
- data/lib/contrast/agent/patching/policy/patch_status.rb +8 -9
- data/lib/contrast/agent/patching/policy/patcher.rb +72 -64
- data/lib/contrast/agent/patching/policy/policy.rb +14 -21
- data/lib/contrast/agent/patching/policy/policy_node.rb +15 -5
- data/lib/contrast/agent/patching/policy/trigger_node.rb +26 -10
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +3 -4
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +6 -10
- data/lib/contrast/agent/protect/policy/policy.rb +1 -1
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +6 -6
- data/lib/contrast/agent/protect/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/protect/rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/base.rb +19 -33
- data/lib/contrast/agent/protect/rule/base_service.rb +10 -6
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +15 -19
- data/lib/contrast/agent/protect/rule/default_scanner.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +7 -14
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +4 -15
- data/lib/contrast/agent/protect/rule/no_sqli.rb +7 -3
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +2 -4
- data/lib/contrast/agent/protect/rule/path_traversal.rb +6 -6
- data/lib/contrast/agent/protect/rule/sqli.rb +19 -13
- data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +1 -1
- data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +1 -1
- data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +2 -2
- data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +1 -1
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +2 -2
- data/lib/contrast/agent/protect/rule/xss.rb +2 -2
- data/lib/contrast/agent/protect/rule/xxe.rb +6 -13
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +2 -3
- data/lib/contrast/agent/railtie.rb +1 -1
- data/lib/contrast/agent/reaction_processor.rb +12 -11
- data/lib/contrast/agent/request.rb +25 -24
- data/lib/contrast/agent/request_context.rb +25 -23
- data/lib/contrast/agent/request_handler.rb +1 -1
- data/lib/contrast/agent/response.rb +1 -1
- data/lib/contrast/agent/rewriter.rb +6 -4
- data/lib/contrast/agent/rule_set.rb +3 -3
- data/lib/contrast/agent/scope.rb +1 -1
- data/lib/contrast/agent/service_heartbeat.rb +3 -4
- data/lib/contrast/agent/static_analysis.rb +1 -1
- data/lib/contrast/agent/thread.rb +2 -2
- data/lib/contrast/agent/thread_watcher.rb +21 -6
- data/lib/contrast/agent/tracepoint_hook.rb +2 -2
- data/lib/contrast/agent/version.rb +2 -2
- data/lib/contrast/agent/worker_thread.rb +1 -1
- data/lib/contrast/api.rb +1 -1
- data/lib/contrast/api/communication.rb +1 -1
- data/lib/contrast/api/communication/connection_status.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +19 -22
- data/lib/contrast/api/communication/response_processor.rb +13 -8
- data/lib/contrast/api/communication/service_lifecycle.rb +5 -3
- data/lib/contrast/api/communication/socket.rb +1 -1
- data/lib/contrast/api/communication/socket_client.rb +30 -35
- data/lib/contrast/api/communication/speedracer.rb +6 -10
- data/lib/contrast/api/communication/tcp_socket.rb +1 -1
- data/lib/contrast/api/communication/unix_socket.rb +1 -1
- data/lib/contrast/api/decorators.rb +3 -1
- data/lib/contrast/api/decorators/address.rb +1 -1
- data/lib/contrast/api/decorators/agent_startup.rb +58 -0
- data/lib/contrast/api/decorators/application_settings.rb +1 -1
- data/lib/contrast/api/decorators/application_startup.rb +57 -0
- data/lib/contrast/api/decorators/application_update.rb +1 -1
- data/lib/contrast/api/decorators/http_request.rb +1 -1
- data/lib/contrast/api/decorators/input_analysis.rb +1 -1
- data/lib/contrast/api/decorators/instrumentation_mode.rb +37 -0
- data/lib/contrast/api/decorators/library.rb +9 -7
- data/lib/contrast/api/decorators/library_usage_update.rb +1 -1
- data/lib/contrast/api/decorators/message.rb +4 -4
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +1 -1
- data/lib/contrast/api/decorators/route_coverage.rb +16 -6
- data/lib/contrast/api/decorators/server_features.rb +1 -1
- data/lib/contrast/api/decorators/trace_event.rb +46 -16
- data/lib/contrast/api/decorators/trace_event_object.rb +2 -4
- data/lib/contrast/api/decorators/trace_event_signature.rb +1 -1
- data/lib/contrast/api/decorators/trace_taint_range.rb +1 -1
- data/lib/contrast/api/decorators/trace_taint_range_tags.rb +2 -7
- data/lib/contrast/api/decorators/user_input.rb +1 -1
- data/lib/contrast/components/agent.rb +16 -15
- data/lib/contrast/components/app_context.rb +11 -29
- data/lib/contrast/components/assess.rb +6 -11
- data/lib/contrast/components/config.rb +3 -2
- data/lib/contrast/components/contrast_service.rb +8 -9
- data/lib/contrast/components/heap_dump.rb +1 -1
- data/lib/contrast/components/interface.rb +4 -3
- data/lib/contrast/components/inventory.rb +1 -1
- data/lib/contrast/components/logger.rb +1 -1
- data/lib/contrast/components/protect.rb +11 -14
- data/lib/contrast/components/sampling.rb +55 -7
- data/lib/contrast/components/scope.rb +2 -1
- data/lib/contrast/components/settings.rb +29 -99
- data/lib/contrast/config.rb +1 -1
- data/lib/contrast/config/agent_configuration.rb +1 -1
- data/lib/contrast/config/application_configuration.rb +1 -1
- data/lib/contrast/config/assess_configuration.rb +1 -1
- data/lib/contrast/config/assess_rules_configuration.rb +2 -4
- data/lib/contrast/config/base_configuration.rb +5 -6
- data/lib/contrast/config/default_value.rb +1 -1
- data/lib/contrast/config/exception_configuration.rb +2 -6
- data/lib/contrast/config/heap_dump_configuration.rb +13 -7
- data/lib/contrast/config/inventory_configuration.rb +1 -1
- data/lib/contrast/config/logger_configuration.rb +2 -6
- data/lib/contrast/config/protect_configuration.rb +1 -1
- data/lib/contrast/config/protect_rule_configuration.rb +23 -1
- data/lib/contrast/config/protect_rules_configuration.rb +1 -1
- data/lib/contrast/config/root_configuration.rb +1 -1
- data/lib/contrast/config/ruby_configuration.rb +1 -1
- data/lib/contrast/config/sampling_configuration.rb +1 -1
- data/lib/contrast/config/server_configuration.rb +1 -1
- data/lib/contrast/config/service_configuration.rb +1 -1
- data/lib/contrast/configuration.rb +4 -15
- data/lib/contrast/delegators/input_analysis.rb +12 -0
- data/lib/contrast/extension/assess.rb +1 -1
- data/lib/contrast/extension/assess/array.rb +2 -7
- data/lib/contrast/extension/assess/erb.rb +2 -8
- data/lib/contrast/extension/assess/eval_trigger.rb +3 -11
- data/lib/contrast/extension/assess/exec_trigger.rb +4 -14
- data/lib/contrast/extension/assess/fiber.rb +3 -13
- data/lib/contrast/extension/assess/hash.rb +1 -1
- data/lib/contrast/extension/assess/kernel.rb +3 -10
- data/lib/contrast/extension/assess/marshal.rb +3 -11
- data/lib/contrast/extension/assess/regexp.rb +2 -7
- data/lib/contrast/extension/assess/string.rb +4 -2
- data/lib/contrast/extension/delegator.rb +1 -1
- data/lib/contrast/extension/inventory.rb +1 -1
- data/lib/contrast/extension/kernel.rb +5 -3
- data/lib/contrast/extension/module.rb +1 -1
- data/lib/contrast/extension/protect.rb +1 -1
- data/lib/contrast/extension/protect/kernel.rb +1 -1
- data/lib/contrast/extension/protect/psych.rb +1 -1
- data/lib/contrast/extension/thread.rb +1 -1
- data/lib/contrast/framework/base_support.rb +1 -1
- data/lib/contrast/framework/manager.rb +14 -17
- data/lib/contrast/framework/platform_version.rb +1 -1
- data/lib/contrast/framework/rack/patch/session_cookie.rb +6 -19
- data/lib/contrast/framework/rack/patch/support.rb +7 -5
- data/lib/contrast/framework/rack/support.rb +1 -1
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -1
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +8 -3
- data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +4 -4
- data/lib/contrast/framework/rails/patch/support.rb +5 -3
- data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +5 -2
- data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +3 -1
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +3 -1
- data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +3 -1
- data/lib/contrast/framework/rails/support.rb +45 -46
- data/lib/contrast/framework/sinatra/support.rb +103 -42
- data/lib/contrast/funchook/funchook.rb +2 -6
- data/lib/contrast/logger/application.rb +13 -10
- data/lib/contrast/logger/format.rb +3 -6
- data/lib/contrast/logger/log.rb +36 -19
- data/lib/contrast/logger/request.rb +2 -3
- data/lib/contrast/logger/time.rb +1 -1
- data/lib/contrast/security_exception.rb +2 -2
- data/lib/contrast/tasks/config.rb +1 -1
- data/lib/contrast/tasks/service.rb +6 -2
- data/lib/contrast/utils/assess/sampling_util.rb +1 -1
- data/lib/contrast/utils/assess/tracking_util.rb +2 -3
- data/lib/contrast/utils/class_util.rb +18 -12
- data/lib/contrast/utils/duck_utils.rb +1 -1
- data/lib/contrast/utils/env_configuration_item.rb +1 -1
- data/lib/contrast/utils/hash_digest.rb +16 -24
- data/lib/contrast/utils/heap_dump_util.rb +104 -88
- data/lib/contrast/utils/invalid_configuration_util.rb +22 -13
- data/lib/contrast/utils/inventory_util.rb +1 -1
- data/lib/contrast/utils/io_util.rb +2 -2
- data/lib/contrast/utils/job_servers_running.rb +10 -5
- data/lib/contrast/utils/object_share.rb +1 -1
- data/lib/contrast/utils/os.rb +3 -2
- data/lib/contrast/utils/preflight_util.rb +1 -1
- data/lib/contrast/utils/resource_loader.rb +1 -1
- data/lib/contrast/utils/ruby_ast_rewriter.rb +3 -2
- data/lib/contrast/utils/sha256_builder.rb +1 -1
- data/lib/contrast/utils/stack_trace_utils.rb +1 -1
- data/lib/contrast/utils/string_utils.rb +1 -1
- data/lib/contrast/utils/tag_util.rb +1 -1
- data/lib/contrast/utils/thread_tracker.rb +1 -1
- data/lib/contrast/utils/timer.rb +1 -1
- data/resources/assess/policy.json +8 -11
- data/resources/deadzone/policy.json +7 -17
- data/ruby-agent.gemspec +66 -27
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- data/sonar-project.properties +9 -0
- metadata +154 -156
- data/lib/contrast/agent/assess/rule.rb +0 -18
- data/lib/contrast/agent/assess/rule/base.rb +0 -52
- data/lib/contrast/agent/assess/rule/redos.rb +0 -67
- data/lib/contrast/agent/inventory/gemfile_digest_cache.rb +0 -38
- data/lib/contrast/common_agent_configuration.rb +0 -87
- data/lib/contrast/framework/sinatra/patch/base.rb +0 -83
- data/lib/contrast/framework/sinatra/patch/support.rb +0 -27
- data/lib/contrast/utils/prevent_serialization.rb +0 -52
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -29,23 +29,38 @@ module Contrast
|
|
|
29
29
|
if source1.length == target.length
|
|
30
30
|
properties.copy_from(source1, target, 0, propagation_node.untags)
|
|
31
31
|
else
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
handle_append(propagation_node, source1, source2, target, properties)
|
|
33
|
+
end
|
|
34
|
+
properties.cleanup_tags
|
|
35
|
+
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
while start < target.length
|
|
39
|
-
properties.copy_from(source2, target, start, propagation_node.untags)
|
|
40
|
-
start += source2.length
|
|
41
|
-
next unless start > target.length
|
|
37
|
+
private
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
# Given the append operation on source 1 added source 2 to it, changing the target output, modify the
|
|
40
|
+
# tags on the target to account for the change.
|
|
41
|
+
#
|
|
42
|
+
# @param propagation_node [Contrast::Agent::Assess::Policy::PropagationNode] the node responsible for the
|
|
43
|
+
# propagation action required by this method
|
|
44
|
+
# @param source1 [Object] the thing being appended to
|
|
45
|
+
# @param source2 [Object] the thing being appended
|
|
46
|
+
# @param target [Object] the result of the append operation
|
|
47
|
+
# @param properties [Contrast::Agent::Assess::Properties] the properties of the target
|
|
48
|
+
def handle_append propagation_node, source1, source2, target, properties
|
|
49
|
+
# find original in the target, copy tags to the new position in
|
|
50
|
+
# target
|
|
51
|
+
original_start_index = target.index(source1)
|
|
52
|
+
properties.copy_from(source1, target, original_start_index, propagation_node.untags)
|
|
53
|
+
|
|
54
|
+
start = original_start_index + source1.length
|
|
55
|
+
while start < target.length
|
|
56
|
+
properties.copy_from(source2, target, start, propagation_node.untags)
|
|
57
|
+
start += source2.length
|
|
58
|
+
next unless start > target.length
|
|
59
|
+
|
|
60
|
+
properties.tags_at(start - source2.length).each do |tag|
|
|
61
|
+
tag.update_end(target.length)
|
|
46
62
|
end
|
|
47
63
|
end
|
|
48
|
-
properties.cleanup_tags
|
|
49
64
|
end
|
|
50
65
|
end
|
|
51
66
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -31,7 +31,8 @@ module Contrast
|
|
|
31
31
|
return unless sources[1]
|
|
32
32
|
|
|
33
33
|
original_end_index = original_start_index + source1.length - 1
|
|
34
|
-
handle_incoming_tags(target, propagation_node, sources[1], preshift, original_start_index,
|
|
34
|
+
handle_incoming_tags(target, propagation_node, sources[1], preshift, original_start_index,
|
|
35
|
+
original_end_index)
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
private
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'contrast/extension/module'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'contrast/components/interface'
|
|
@@ -24,23 +24,8 @@ module Contrast
|
|
|
24
24
|
|
|
25
25
|
known_tainted = ASSESS.tainted_columns[class_name]
|
|
26
26
|
propagation_node.sources.each do |source|
|
|
27
|
-
|
|
28
|
-
next unless arg.cs__respond_to?(:each_pair)
|
|
29
|
-
|
|
30
|
-
arg.each_pair do |key, value|
|
|
31
|
-
next unless value
|
|
32
|
-
next if known_tainted&.include?(key)
|
|
33
|
-
next unless (properties = Contrast::Agent::Assess::Tracker.properties!(value))
|
|
34
|
-
|
|
35
|
-
# TODO: RUBY-540 handle sanitization, handle nested objects
|
|
36
|
-
Contrast::Agent::Assess::Policy::PropagationMethod.apply_tags(propagation_node, value)
|
|
37
|
-
properties.build_event(propagation_node, value, preshift.object, target, preshift.args)
|
|
38
|
-
next unless tracked_value?(value)
|
|
39
|
-
|
|
40
|
-
tainted_columns[key] = properties
|
|
41
|
-
end
|
|
27
|
+
handle_write(propagation_node, source, preshift, target, known_tainted, tainted_columns)
|
|
42
28
|
end
|
|
43
|
-
|
|
44
29
|
return if tainted_columns.empty?
|
|
45
30
|
|
|
46
31
|
if known_tainted
|
|
@@ -51,6 +36,26 @@ module Contrast
|
|
|
51
36
|
|
|
52
37
|
Contrast::Agent::Assess::Policy::DynamicSourceFactory.create_sources class_type, tainted_columns
|
|
53
38
|
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def handle_write propagation_node, source, preshift, target, known_tainted, tainted_columns
|
|
43
|
+
arg = preshift.args[source]
|
|
44
|
+
return unless arg.cs__respond_to?(:each_pair)
|
|
45
|
+
|
|
46
|
+
arg.each_pair do |key, value|
|
|
47
|
+
next unless value
|
|
48
|
+
next if known_tainted&.include?(key)
|
|
49
|
+
next unless (properties = Contrast::Agent::Assess::Tracker.properties!(value))
|
|
50
|
+
|
|
51
|
+
# TODO: RUBY-540 handle sanitization, handle nested objects
|
|
52
|
+
Contrast::Agent::Assess::Policy::PropagationMethod.apply_tags(propagation_node, value)
|
|
53
|
+
properties.build_event(propagation_node, value, preshift.object, target, preshift.args)
|
|
54
|
+
next unless tracked_value?(value)
|
|
55
|
+
|
|
56
|
+
tainted_columns[key] = properties
|
|
57
|
+
end
|
|
58
|
+
end
|
|
54
59
|
end
|
|
55
60
|
end
|
|
56
61
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -33,7 +33,9 @@ module Contrast
|
|
|
33
33
|
# point on which all tags need to be adjusted
|
|
34
34
|
# If the insertion point is the end of the string, preshift length is returned
|
|
35
35
|
# https://stackoverflow.com/questions/31714522/find-the-first-differing-character-between-two-strings-in-ruby
|
|
36
|
-
insert_point = (0...preshift_target.length).find
|
|
36
|
+
insert_point = (0...preshift_target.length).find do |i|
|
|
37
|
+
preshift_target[i] != target[i]
|
|
38
|
+
end || preshift_target.length
|
|
37
39
|
# Depending what's inserted, we might be wrong. For instance, inserting 'foo'
|
|
38
40
|
# into 'asdfasdf' could result in 'asdfoofasdf'. we'd be off by one b/c of the 'f'
|
|
39
41
|
insert_point = target.rindex(source, insert_point)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -76,7 +76,8 @@ module Contrast
|
|
|
76
76
|
applicable_tags.each do |tag_name, tag_ranges|
|
|
77
77
|
return_properties.set_tags(tag_name, tag_ranges)
|
|
78
78
|
end
|
|
79
|
-
return_properties.build_event(propagation_node, return_value, preshift.object, return_value,
|
|
79
|
+
return_properties.build_event(propagation_node, return_value, preshift.object, return_value,
|
|
80
|
+
preshift.args)
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -6,28 +6,35 @@ module Contrast
|
|
|
6
6
|
module Assess
|
|
7
7
|
module Policy
|
|
8
8
|
module Propagator
|
|
9
|
-
# Propagation that results in all the tags of the source being
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# tags. The target's preexisting tags are also updated by this
|
|
13
|
-
# removal.
|
|
9
|
+
# Propagation that results in all the tags of the source being applied to the totality of the target and then
|
|
10
|
+
# those sections which have been removed from the target are removed from the tags. The target's preexisting
|
|
11
|
+
# tags are also updated by this removal.
|
|
14
12
|
class Remove < Contrast::Agent::Assess::Policy::Propagator::Base
|
|
15
13
|
class << self
|
|
16
|
-
# For the source, append its tags to the target.
|
|
17
|
-
#
|
|
18
|
-
# Unlike additive propagation, this currently only supports one source
|
|
14
|
+
# For the source, append its tags to the target. Once the tag is applied, remove the section that was
|
|
15
|
+
# removed by the delete. Unlike additive propagation, this currently only supports one source.
|
|
19
16
|
def propagate propagation_node, preshift, target
|
|
20
17
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))
|
|
21
18
|
|
|
22
19
|
source = find_source(propagation_node.sources[0], preshift)
|
|
23
20
|
properties.copy_from(source, target, 0, propagation_node.untags)
|
|
24
|
-
|
|
25
|
-
handle_removal(source_chars, target)
|
|
21
|
+
handle_removal(propagation_node, source, target)
|
|
26
22
|
end
|
|
27
23
|
|
|
28
|
-
def handle_removal
|
|
24
|
+
def handle_removal propagation_node, source, target
|
|
25
|
+
return unless source
|
|
29
26
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))
|
|
30
27
|
|
|
28
|
+
source_string = source.is_a?(String) ? source : source.to_s
|
|
29
|
+
|
|
30
|
+
# If the lengths are the same, we should just copy the tags because nothing was removed, but a new
|
|
31
|
+
# instance could have been created. copy_from will handle the case where the source is the target.
|
|
32
|
+
if source_string.length == target.length
|
|
33
|
+
properties.copy_from(source, target, 0, propagation_node.untags)
|
|
34
|
+
return
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
source_chars = source_string.chars
|
|
31
38
|
source_idx = 0
|
|
32
39
|
|
|
33
40
|
target_chars = target.chars
|
|
@@ -36,10 +43,8 @@ module Contrast
|
|
|
36
43
|
remove_ranges = []
|
|
37
44
|
start = nil
|
|
38
45
|
|
|
39
|
-
# loop over the target, the result of the delete
|
|
40
|
-
#
|
|
41
|
-
# represents a section that was deleted. these sections
|
|
42
|
-
# need to have their tags updated
|
|
46
|
+
# loop over the target, the result of the delete every range of characters that it differs from the
|
|
47
|
+
# source represents a section that was deleted. these sections need to have their tags updated
|
|
43
48
|
target_len = target_chars.length
|
|
44
49
|
while target_idx < target_len
|
|
45
50
|
target_char = target_chars[target_idx]
|
|
@@ -56,9 +61,8 @@ module Contrast
|
|
|
56
61
|
source_idx += 1
|
|
57
62
|
end
|
|
58
63
|
|
|
59
|
-
# once we're done looping over the target, anything left
|
|
60
|
-
#
|
|
61
|
-
# applying to it need to be removed.
|
|
64
|
+
# once we're done looping over the target, anything left over is extra from the source that was
|
|
65
|
+
# deleted. tags applying to it need to be removed.
|
|
62
66
|
remove_ranges << (source_idx...source_chars.length) if source_idx != source_chars.length
|
|
63
67
|
|
|
64
68
|
# handle deleting the removed ranges
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -21,22 +21,12 @@ module Contrast
|
|
|
21
21
|
# Additionally, an empty string is returned when the starting index for
|
|
22
22
|
# a character range is at the end of the string. Let's just skip that
|
|
23
23
|
# and only track a string that has length
|
|
24
|
-
unless ret &&
|
|
25
|
-
!ret.empty? &&
|
|
26
|
-
Contrast::Agent::Assess::Tracker.tracked?(source)
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
end
|
|
24
|
+
return unless ret && !ret.empty? && Contrast::Agent::Assess::Tracker.tracked?(source)
|
|
30
25
|
|
|
31
26
|
return unless (source_properties = Contrast::Agent::Assess::Tracker.properties(source))
|
|
32
27
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties!(ret))
|
|
33
28
|
|
|
34
|
-
properties.build_event(
|
|
35
|
-
patcher,
|
|
36
|
-
ret,
|
|
37
|
-
source,
|
|
38
|
-
ret,
|
|
39
|
-
args)
|
|
29
|
+
properties.build_event(patcher, ret, source, ret, args)
|
|
40
30
|
|
|
41
31
|
range = determine_select_range(source, args)
|
|
42
32
|
return unless range
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module Contrast
|
|
@@ -19,19 +19,7 @@ module Contrast
|
|
|
19
19
|
when Contrast::Utils::ObjectShare::OBJECT_KEY
|
|
20
20
|
tracked_inputs << preshift.object if Contrast::Agent::Assess::Tracker.tracked?(preshift.object)
|
|
21
21
|
else
|
|
22
|
-
|
|
23
|
-
if arg.is_a?(String)
|
|
24
|
-
tracked_inputs << arg if Contrast::Agent::Assess::Tracker.tracked?(arg)
|
|
25
|
-
elsif Contrast::Utils::DuckUtils.iterable_hash?(arg)
|
|
26
|
-
arg.each_pair do |key, value|
|
|
27
|
-
tracked_inputs << key if tracked_value?(key)
|
|
28
|
-
tracked_inputs << value if tracked_value?(value)
|
|
29
|
-
end
|
|
30
|
-
elsif Contrast::Utils::DuckUtils.iterable_enumerable?(arg)
|
|
31
|
-
arg.each do |value|
|
|
32
|
-
tracked_inputs << value if tracked_value?(value)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
22
|
+
find_argument_inputs(tracked_inputs, preshift.args[source])
|
|
35
23
|
end
|
|
36
24
|
end
|
|
37
25
|
|
|
@@ -50,6 +38,28 @@ module Contrast
|
|
|
50
38
|
properties.splat_from(input, target)
|
|
51
39
|
end
|
|
52
40
|
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
# The arguments to the splat method are complex and of multiple types. As such, we need to handle
|
|
45
|
+
# Strings and iterables to determine the tracked inputs on which to act.
|
|
46
|
+
#
|
|
47
|
+
# @param tracked_inputs [Array] storage for the inputs to act on later
|
|
48
|
+
# @param arg [Object] an input to the method which act as sources for this propagation.
|
|
49
|
+
def find_argument_inputs tracked_inputs, arg
|
|
50
|
+
if arg.is_a?(String)
|
|
51
|
+
tracked_inputs << arg if Contrast::Agent::Assess::Tracker.tracked?(arg)
|
|
52
|
+
elsif Contrast::Utils::DuckUtils.iterable_hash?(arg)
|
|
53
|
+
arg.each_pair do |key, value|
|
|
54
|
+
tracked_inputs << key if tracked_value?(key)
|
|
55
|
+
tracked_inputs << value if tracked_value?(value)
|
|
56
|
+
end
|
|
57
|
+
elsif Contrast::Utils::DuckUtils.iterable_enumerable?(arg)
|
|
58
|
+
arg.each do |value|
|
|
59
|
+
tracked_inputs << value if tracked_value?(value)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
53
63
|
end
|
|
54
64
|
end
|
|
55
65
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c)
|
|
1
|
+
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'contrast/agent/assess/policy/preshift'
|
|
@@ -31,20 +31,12 @@ module Contrast
|
|
|
31
31
|
# @return [nil] so as not to risk changing the result of the propagation.
|
|
32
32
|
|
|
33
33
|
def propagate propagation_node, preshift, target
|
|
34
|
-
logger.trace('Propagation detected',
|
|
35
|
-
node_id: propagation_node.id,
|
|
36
|
-
target_id: target.__id__)
|
|
34
|
+
logger.trace('Propagation detected', node_id: propagation_node.id, target_id: target.__id__)
|
|
37
35
|
|
|
38
36
|
source = find_source(propagation_node.sources[0], preshift)
|
|
39
37
|
return unless (source_properties = Contrast::Agent::Assess::Tracker.properties(source))
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
# Otherwise, the default for String#split is to use a single whitespace.
|
|
43
|
-
separator_length = if propagation_node.method_name == :grapheme_clusters
|
|
44
|
-
0
|
|
45
|
-
else
|
|
46
|
-
preshift&.args&.first&.to_s&.length || $FIELD_SEPARATOR&.to_s&.length || 1
|
|
47
|
-
end
|
|
39
|
+
separator_length = find_separator_length(propagation_node, preshift)
|
|
48
40
|
|
|
49
41
|
current_index = 0
|
|
50
42
|
target.each do |target_elem|
|
|
@@ -126,6 +118,19 @@ module Contrast
|
|
|
126
118
|
|
|
127
119
|
private
|
|
128
120
|
|
|
121
|
+
# grapheme_clusters break the string apart based on each "user-perceived" character. Otherwise, the
|
|
122
|
+
# default for String#split is to use a single whitespace.
|
|
123
|
+
#
|
|
124
|
+
# @param propagation_node [Contrast::Agent::Assess::Policy::PropagationNode] the node that governs this
|
|
125
|
+
# propagation event.
|
|
126
|
+
# @param preshift [Contrast::Agent::Assess::PreShift] The capture of the state of the code just prior to
|
|
127
|
+
# the invocation of the patched method.
|
|
128
|
+
def find_separator_length propagation_node, preshift
|
|
129
|
+
return 0 if propagation_node.method_name == :grapheme_clusters
|
|
130
|
+
|
|
131
|
+
preshift&.args&.first&.to_s&.length || $FIELD_SEPARATOR&.to_s&.length || 1
|
|
132
|
+
end
|
|
133
|
+
|
|
129
134
|
# Save index of the current split object.
|
|
130
135
|
# Create index tracking array as needed.
|
|
131
136
|
def save_split_index!
|
|
@@ -155,10 +160,8 @@ module Contrast
|
|
|
155
160
|
#
|
|
156
161
|
# @return [Contrast::Agent::Assess::Policy::PropagationNode] String#split node
|
|
157
162
|
def split_node
|
|
158
|
-
@_split_node ||=
|
|
159
|
-
|
|
160
|
-
node.class_name == 'String' && node.method_name == :split && node.instance_method?
|
|
161
|
-
end
|
|
163
|
+
@_split_node ||= Contrast::Agent::Assess::Policy::Policy.instance.propagators.find do |node|
|
|
164
|
+
node.class_name == 'String' && node.method_name == :split && node.instance_method?
|
|
162
165
|
end
|
|
163
166
|
end
|
|
164
167
|
end
|