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
|
|
@@ -6,11 +6,11 @@ module Contrast
|
|
|
6
6
|
# A simple wrapper around a Module and a call to its name, used to avoid
|
|
7
7
|
# calling the Module#name method and generating extra Strings
|
|
8
8
|
class ModuleData
|
|
9
|
-
attr_reader :mod, :
|
|
9
|
+
attr_reader :mod, :mod_name
|
|
10
10
|
|
|
11
|
-
def initialize mod,
|
|
11
|
+
def initialize mod, mod_name = nil
|
|
12
12
|
@mod = mod
|
|
13
|
-
@
|
|
13
|
+
@mod_name = mod_name || mod.cs__name
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
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/components/interface'
|
|
@@ -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/patching/policy/after_load_patch'
|
|
@@ -51,10 +51,15 @@ module Contrast
|
|
|
51
51
|
next unless after_load_patch.target_defined?
|
|
52
52
|
next if AGENT.skip_instrumentation?(after_load_patch.module_name)
|
|
53
53
|
|
|
54
|
-
logger.trace(
|
|
55
|
-
|
|
56
|
-
module: after_load_patch.module_name)
|
|
54
|
+
logger.trace('Catching up on already loaded afterload patch - applying instrumentation',
|
|
55
|
+
module: after_load_patch.module_name)
|
|
57
56
|
after_load_patch.instrument!
|
|
57
|
+
rescue NameError => e
|
|
58
|
+
logger.error('Method undefined in afterload patch', e, module: after_load_patch.module_name,
|
|
59
|
+
method: after_load_patch.method_to_instrument)
|
|
60
|
+
rescue StandardError => e
|
|
61
|
+
logger.error('Afterload patch failed to apply', e, module: after_load_patch.module_name,
|
|
62
|
+
method: after_load_patch.method_to_instrument)
|
|
58
63
|
end
|
|
59
64
|
after_load_patches.delete_if(&:applied?)
|
|
60
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
|
module Contrast
|
|
@@ -49,7 +49,10 @@ module Contrast
|
|
|
49
49
|
private
|
|
50
50
|
|
|
51
51
|
def nodes
|
|
52
|
-
@_nodes ||= [
|
|
52
|
+
@_nodes ||= [
|
|
53
|
+
source_node, propagation_node, trigger_node, inventory_node, protect_node,
|
|
54
|
+
deadzone_node
|
|
55
|
+
].compact
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
def method_scopes
|
|
@@ -76,7 +79,8 @@ module Contrast
|
|
|
76
79
|
protect_node = find_method_node(module_policy.protect_nodes, method_name, instance_method)
|
|
77
80
|
inventory_node = find_method_node(module_policy.inventory_nodes, method_name, instance_method)
|
|
78
81
|
deadzone_node = find_method_node(module_policy.deadzone_nodes, method_name, instance_method)
|
|
79
|
-
method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node,
|
|
82
|
+
method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node,
|
|
83
|
+
inventory_node, deadzone_node)
|
|
80
84
|
MethodPolicy.new(method_name: method_name,
|
|
81
85
|
method_visibility: method_visibility,
|
|
82
86
|
instance_method: instance_method,
|
|
@@ -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/patching/policy/method_policy'
|
|
@@ -20,12 +20,18 @@ module Contrast
|
|
|
20
20
|
# @return [Contrast::Agent::Patching::Policy::ModulePolicy]
|
|
21
21
|
def create_module_policy module_name
|
|
22
22
|
module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.new
|
|
23
|
-
module_policy.source_nodes = nodes_for_module(
|
|
24
|
-
|
|
25
|
-
module_policy.
|
|
26
|
-
|
|
27
|
-
module_policy.
|
|
28
|
-
|
|
23
|
+
module_policy.source_nodes = nodes_for_module(
|
|
24
|
+
Contrast::Agent::Assess::Policy::Policy.instance.sources, module_name)
|
|
25
|
+
module_policy.propagator_nodes = nodes_for_module(
|
|
26
|
+
Contrast::Agent::Assess::Policy::Policy.instance.propagators, module_name)
|
|
27
|
+
module_policy.trigger_nodes = nodes_for_module(
|
|
28
|
+
Contrast::Agent::Assess::Policy::Policy.instance.triggers, module_name)
|
|
29
|
+
module_policy.protect_nodes = nodes_for_module(
|
|
30
|
+
Contrast::Agent::Protect::Policy::Policy.instance.triggers, module_name)
|
|
31
|
+
module_policy.inventory_nodes = nodes_for_module(
|
|
32
|
+
Contrast::Agent::Inventory::Policy::Policy.instance.triggers, module_name)
|
|
33
|
+
module_policy.deadzone_nodes = nodes_for_module(
|
|
34
|
+
Contrast::Agent::Deadzone::Policy::Policy.instance.deadzones, module_name)
|
|
29
35
|
module_policy
|
|
30
36
|
end
|
|
31
37
|
|
|
@@ -42,7 +48,8 @@ module Contrast
|
|
|
42
48
|
end
|
|
43
49
|
end
|
|
44
50
|
|
|
45
|
-
attr_accessor :source_nodes, :propagator_nodes, :trigger_nodes, :inventory_nodes, :protect_nodes,
|
|
51
|
+
attr_accessor :source_nodes, :propagator_nodes, :trigger_nodes, :inventory_nodes, :protect_nodes,
|
|
52
|
+
:deadzone_nodes
|
|
46
53
|
|
|
47
54
|
def empty?
|
|
48
55
|
return false if source_nodes.any?
|
|
@@ -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 'monitor'
|
|
@@ -130,11 +130,7 @@ module Contrast
|
|
|
130
130
|
return unless AGENT.enabled?
|
|
131
131
|
return unless PROTECT.enabled?
|
|
132
132
|
|
|
133
|
-
apply_trigger_only(method_policy&.protect_node,
|
|
134
|
-
method,
|
|
135
|
-
exception,
|
|
136
|
-
object,
|
|
137
|
-
args)
|
|
133
|
+
apply_trigger_only(method_policy&.protect_node, method, exception, object, args)
|
|
138
134
|
end
|
|
139
135
|
|
|
140
136
|
# Apply the Inventory patch which applies to the given method.
|
|
@@ -151,11 +147,7 @@ module Contrast
|
|
|
151
147
|
def apply_inventory method_policy, method, exception, object, args
|
|
152
148
|
return unless INVENTORY.enabled?
|
|
153
149
|
|
|
154
|
-
apply_trigger_only(method_policy&.inventory_node,
|
|
155
|
-
method,
|
|
156
|
-
exception,
|
|
157
|
-
object,
|
|
158
|
-
args)
|
|
150
|
+
apply_trigger_only(method_policy&.inventory_node, method, exception, object, args)
|
|
159
151
|
end
|
|
160
152
|
|
|
161
153
|
# Apply the Assess patches which apply to the given method.
|
|
@@ -178,15 +170,18 @@ module Contrast
|
|
|
178
170
|
return ret unless method_policy && ASSESS.enabled?
|
|
179
171
|
|
|
180
172
|
current_context = Contrast::Agent::REQUEST_TRACKER.current
|
|
181
|
-
return ret
|
|
173
|
+
return ret if current_context && !current_context.analyze_request?
|
|
182
174
|
|
|
183
175
|
trigger_node = method_policy.trigger_node
|
|
184
|
-
|
|
176
|
+
if trigger_node
|
|
177
|
+
Contrast::Agent::Assess::Policy::TriggerMethod.apply_trigger_rule(trigger_node, object, ret, args)
|
|
178
|
+
end
|
|
185
179
|
if method_policy.source_node
|
|
186
180
|
# If we were given a frozen return, and it was the target of a
|
|
187
181
|
# source, and we have frozen sources enabled, we'll need to
|
|
188
182
|
# replace the return. Note, this is not the default case.
|
|
189
|
-
source_ret = Contrast::Agent::Assess::Policy::SourceMethod.source_patchers(method_policy, object, ret,
|
|
183
|
+
source_ret = Contrast::Agent::Assess::Policy::SourceMethod.source_patchers(method_policy, object, ret,
|
|
184
|
+
args)
|
|
190
185
|
end
|
|
191
186
|
if method_policy.propagation_node
|
|
192
187
|
propagated_ret = Contrast::Agent::Assess::Policy::PropagationMethod.apply_propagation(
|
|
@@ -277,9 +272,9 @@ module Contrast
|
|
|
277
272
|
# <method_start>_unbound_<method_name>
|
|
278
273
|
def build_unbound_method_name patcher_method
|
|
279
274
|
(Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START +
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
275
|
+
'unbound' +
|
|
276
|
+
Contrast::Utils::ObjectShare::UNDERSCORE +
|
|
277
|
+
patcher_method.to_s).to_sym
|
|
283
278
|
end
|
|
284
279
|
|
|
285
280
|
# @param mod [Module] the module in which the patch should be
|
|
@@ -339,7 +334,7 @@ module Contrast
|
|
|
339
334
|
# @return [Symbol] new alias for the underlying method (presumably, so the patched method can call it)
|
|
340
335
|
def register_c_patch target_module_name, unbound_method, impl = :alias_instance
|
|
341
336
|
# These could be set as AfterLoadPatches.
|
|
342
|
-
method_name = unbound_method.name.to_sym
|
|
337
|
+
method_name = unbound_method.name.to_sym # rubocop:disable Security/Module/Name -- ruby built in attribute.
|
|
343
338
|
underlying_method_name = build_unbound_method_name(method_name).to_sym
|
|
344
339
|
|
|
345
340
|
target_module = Module.cs__const_get(target_module_name)
|
|
@@ -362,29 +357,27 @@ module Contrast
|
|
|
362
357
|
|
|
363
358
|
case impl
|
|
364
359
|
when :alias_instance, :alias_singleton
|
|
360
|
+
# Core to patching. Ignore define method usage cop.
|
|
361
|
+
# rubocop:disable Performance/Kernel/DefineMethod
|
|
365
362
|
unless target_module.instance_methods(false).include? underlying_method_name
|
|
366
363
|
# alias_method may be private
|
|
367
364
|
target_module.send(:alias_method, underlying_method_name, method_name)
|
|
368
|
-
# TODO: RUBY-1052
|
|
369
|
-
# rubocop:disable Performance/Kernel/DefineMethod
|
|
370
365
|
target_module.send(:define_method, method_name, unbound_method.bind(target_module))
|
|
371
|
-
# rubocop:enable Performance/Kernel/DefineMethod
|
|
372
366
|
end
|
|
373
367
|
target_module.send(visibility, method_name) # e.g., module.private(:my_method)
|
|
374
368
|
when :prepend
|
|
375
369
|
prepending_module = Module.new
|
|
376
|
-
# TODO: RUBY-1052
|
|
377
|
-
# rubocop:disable Performance/Kernel/DefineMethod
|
|
378
370
|
prepending_module.send(:define_method, method_name, unbound_method.bind(target_module))
|
|
379
|
-
# rubocop:enable Performance/Kernel/DefineMethod
|
|
380
371
|
prepending_module.send(visibility, method_name)
|
|
381
372
|
# This prepends to the singleton class (it patches a class method)
|
|
382
373
|
target_module.prepend prepending_module
|
|
374
|
+
# rubocop:enable Performance/Kernel/DefineMethod
|
|
383
375
|
end
|
|
384
376
|
# Ougai::Logger.create_item_with_2args calls Hash#[]=, so we
|
|
385
377
|
# can't invoke this logging method or we'll seg fault as we'd
|
|
386
378
|
# change the method definition mid-call
|
|
387
|
-
# if method_name != :[]=
|
|
379
|
+
# if method_name != :[]= &&
|
|
380
|
+
# Contrast::Agent::Logger.defined!
|
|
388
381
|
# logger.trace(
|
|
389
382
|
# 'Registered C-defined patch',
|
|
390
383
|
# implementation: impl,
|
|
@@ -392,14 +385,15 @@ module Contrast
|
|
|
392
385
|
# method: method_name,
|
|
393
386
|
# visibility: visibility)
|
|
394
387
|
# end
|
|
395
|
-
underlying_method_name
|
|
388
|
+
underlying_method_name
|
|
396
389
|
end
|
|
397
390
|
|
|
398
391
|
# @return [Boolean]
|
|
399
392
|
def skip_contrast_analysis?
|
|
400
393
|
return true if in_contrast_scope?
|
|
401
|
-
return
|
|
402
|
-
return
|
|
394
|
+
return false unless defined?(Contrast::Agent::REQUEST_TRACKER)
|
|
395
|
+
return false unless Contrast::Agent::REQUEST_TRACKER.current
|
|
396
|
+
return true unless Contrast::Agent::REQUEST_TRACKER.current.analyze_request?
|
|
403
397
|
|
|
404
398
|
false
|
|
405
399
|
end
|
|
@@ -411,7 +405,7 @@ module Contrast
|
|
|
411
405
|
def skip_assess_analysis?
|
|
412
406
|
return true if skip_contrast_analysis?
|
|
413
407
|
|
|
414
|
-
!ASSESS
|
|
408
|
+
!ASSESS&.enabled?
|
|
415
409
|
end
|
|
416
410
|
end
|
|
417
411
|
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
|
|
@@ -13,7 +13,7 @@ module Contrast
|
|
|
13
13
|
# one does not exist.
|
|
14
14
|
#
|
|
15
15
|
# @param mod [Module] the Module for which the status is asked
|
|
16
|
-
# @return [Contrast::Agent::Patching::Policy::
|
|
16
|
+
# @return [Contrast::Agent::Patching::Policy::PatchStatus]
|
|
17
17
|
def get_status mod
|
|
18
18
|
if mod.cs__const_defined?(status_key, false)
|
|
19
19
|
mod.cs__const_get(status_key, false)
|
|
@@ -68,7 +68,10 @@ module Contrast
|
|
|
68
68
|
def set_info_for mod, method, method_policy, is_instance_method, cs_method
|
|
69
69
|
mod.instance_variable_set(method_info_key, {}) unless mod.instance_variable_defined?(method_info_key)
|
|
70
70
|
holder = mod.instance_variable_get(method_info_key)
|
|
71
|
-
|
|
71
|
+
# if we already have this information, then we don't need to set it as we'll update the info on access
|
|
72
|
+
return if holder.key?(method)
|
|
73
|
+
|
|
74
|
+
holder[method_name_key(method, is_instance_method)] = [method_policy, cs_method]
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
private
|
|
@@ -153,9 +156,7 @@ module Contrast
|
|
|
153
156
|
end
|
|
154
157
|
|
|
155
158
|
def patched?
|
|
156
|
-
@patch_status == :PATCHED ||
|
|
157
|
-
@patch_status == :NONE ||
|
|
158
|
-
@patch_status == :FAILED
|
|
159
|
+
@patch_status == :PATCHED || @patch_status == :NONE || @patch_status == :FAILED
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
def rewriting!
|
|
@@ -179,9 +180,7 @@ module Contrast
|
|
|
179
180
|
end
|
|
180
181
|
|
|
181
182
|
def rewritten?
|
|
182
|
-
@rewrite_status == :REWRITTEN ||
|
|
183
|
-
@rewrite_status == :NO_REWRITE ||
|
|
184
|
-
@rewrite_status == :FAILED_REWRITE
|
|
183
|
+
@rewrite_status == :REWRITTEN || @rewrite_status == :NO_REWRITE || @rewrite_status == :FAILED_REWRITE
|
|
185
184
|
end
|
|
186
185
|
end
|
|
187
186
|
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 'monitor'
|
|
@@ -13,7 +13,8 @@ require 'contrast/utils/class_util'
|
|
|
13
13
|
# assess
|
|
14
14
|
require 'contrast/agent/assess/policy/policy'
|
|
15
15
|
require 'contrast/agent/assess/policy/policy_scanner'
|
|
16
|
-
|
|
16
|
+
# TODO: RUBY-714 remove guard w/ EOL of 2.5
|
|
17
|
+
require 'contrast/agent/assess/policy/rewriter_patch' if RUBY_VERSION < '2.6.0'
|
|
17
18
|
require 'contrast/agent/assess/policy/source_method'
|
|
18
19
|
require 'contrast/agent/assess/policy/trigger_method'
|
|
19
20
|
|
|
@@ -52,8 +53,8 @@ module Contrast
|
|
|
52
53
|
# startup to catchup on everything we didn't see get loaded
|
|
53
54
|
def patch
|
|
54
55
|
catchup_after_load_patches
|
|
55
|
-
|
|
56
|
-
Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolations
|
|
56
|
+
catchup_loaded_methods
|
|
57
|
+
Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolations if RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
# Hook to only monkeypatch Contrast. This will not trigger any
|
|
@@ -62,10 +63,11 @@ module Contrast
|
|
|
62
63
|
# where only a subset of the Assess changes are needed.
|
|
63
64
|
PATCH_MONITOR = Monitor.new
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
# Iterate over and patch those Modules and Methods which were loaded before the Agent was enabled.
|
|
67
|
+
def catchup_loaded_methods
|
|
66
68
|
PATCH_MONITOR.synchronize do
|
|
67
69
|
t = Contrast::Agent::Thread.new do
|
|
68
|
-
|
|
70
|
+
synchronized_catchup_loaded_methods
|
|
69
71
|
end
|
|
70
72
|
# aborting on exception makes exceptions propagate.
|
|
71
73
|
t.abort_on_exception = true
|
|
@@ -84,7 +86,7 @@ module Contrast
|
|
|
84
86
|
|
|
85
87
|
load_patches_for_module(mod_name)
|
|
86
88
|
|
|
87
|
-
return unless all_module_names.any?
|
|
89
|
+
return unless all_module_names.any?(mod_name)
|
|
88
90
|
|
|
89
91
|
module_data = Contrast::Agent::ModuleData.new(mod, mod_name)
|
|
90
92
|
patch_into_module(module_data)
|
|
@@ -100,7 +102,7 @@ module Contrast
|
|
|
100
102
|
# @param mod [Module] the module in which the patch should be
|
|
101
103
|
# placed.
|
|
102
104
|
# @param methods [Array(Symbol)] all the instance or singleton
|
|
103
|
-
# methods in this
|
|
105
|
+
# methods in this mod.
|
|
104
106
|
# @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
|
|
105
107
|
# the policy that applies to the given method_name.
|
|
106
108
|
# @return [Boolean] if patched, either by this invocation or a
|
|
@@ -142,14 +144,15 @@ module Contrast
|
|
|
142
144
|
# @return [Array<String>] the names of all the Modules for which
|
|
143
145
|
# there patches in our policies
|
|
144
146
|
def all_module_names
|
|
145
|
-
@_all_module_names ||=
|
|
147
|
+
@_all_module_names ||=
|
|
148
|
+
POLICIES.each_with_object(Set.new) { |policy, set| set.merge(policy.instance.module_names) }
|
|
146
149
|
end
|
|
147
150
|
|
|
148
151
|
# Hook to only monkeypatch Contrast. This will not trigger any
|
|
149
152
|
# other functions, like rewriting or scanning. This method should
|
|
150
153
|
# only be invoked by the patch_methods method above in order to
|
|
151
154
|
# ensure it is wrapped in a synchronize call
|
|
152
|
-
def
|
|
155
|
+
def synchronized_catchup_loaded_methods
|
|
153
156
|
logger.trace_with_time('Running patching') do
|
|
154
157
|
patched = []
|
|
155
158
|
all_module_names.each do |patchable_name|
|
|
@@ -166,59 +169,42 @@ module Contrast
|
|
|
166
169
|
end
|
|
167
170
|
end
|
|
168
171
|
|
|
169
|
-
# Given the patchers that apply to this class that may apply, patch
|
|
170
|
-
#
|
|
172
|
+
# Given the patchers that apply to this class that may apply, patch Contrast method calls into the methods
|
|
173
|
+
# for which we have rules.
|
|
171
174
|
#
|
|
172
|
-
# @param module_data [Contrast::Agent::ModuleData] the module, and
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
# regardless of the state of the
|
|
176
|
-
# Contrast::Agent::Patching::Policy::PatchStatus status on the
|
|
177
|
-
# Module
|
|
175
|
+
# @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
|
|
176
|
+
# @param redo_patch [Boolean] a trigger to force patching regardless of the state of the
|
|
177
|
+
# Contrast::Agent::Patching::Policy::PatchStatus status on the Module
|
|
178
178
|
def patch_into_module module_data, redo_patch = false
|
|
179
179
|
status = status_type.get_status(module_data.mod)
|
|
180
180
|
return if (status&.patched? || status&.patching?) && !redo_patch
|
|
181
181
|
|
|
182
|
-
# Begin patching our sources into the given
|
|
183
|
-
#
|
|
184
|
-
|
|
185
|
-
#
|
|
186
|
-
module_policy
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
# Begin patching our sources into the given module. Any patcher that has the name of the module will be
|
|
183
|
+
# evaluated for patching. Find all the patchers that apply to this class, sorted by type.
|
|
184
|
+
module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.create_module_policy(module_data.mod_name)
|
|
185
|
+
# If there's nothing to match, then set that status and exit
|
|
186
|
+
if module_policy.empty?
|
|
187
|
+
status.no_patch!
|
|
188
|
+
return
|
|
189
|
+
end
|
|
189
190
|
|
|
190
191
|
status.patching!
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
# Monkey patch any methods in this class that have matching nodes in the policy
|
|
195
|
-
unless module_policy.empty?
|
|
196
|
-
instance_methods = all_instance_methods(clazz, true)
|
|
197
|
-
singleton_methods = clazz.singleton_methods(false)
|
|
198
|
-
counts += patch_into_methods(clazz, instance_methods, module_policy, true)
|
|
199
|
-
counts += patch_into_methods(clazz, singleton_methods, module_policy, false)
|
|
200
|
-
counts = module_policy.num_expected_patches if adjust_for_prepend(clazz)
|
|
201
|
-
patched = true
|
|
202
|
-
end
|
|
192
|
+
num_applied_patches = patch_into_instance_methods(module_data, module_policy)
|
|
193
|
+
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
|
|
203
195
|
|
|
204
|
-
|
|
205
|
-
if module_policy.num_expected_patches == counts
|
|
206
|
-
status.patched!
|
|
207
|
-
else
|
|
208
|
-
status.partial_patch!
|
|
209
|
-
end
|
|
196
|
+
status.patched!
|
|
210
197
|
else
|
|
211
|
-
status.
|
|
198
|
+
status.partial_patch!
|
|
212
199
|
end
|
|
213
200
|
rescue StandardError => e
|
|
214
|
-
status
|
|
215
|
-
|
|
216
|
-
logger.warn('Patching failed', e, module: module_data.name)
|
|
201
|
+
status&.failed_patch!
|
|
202
|
+
logger.warn('Patching failed', e, module: module_data.mod_name)
|
|
217
203
|
ensure
|
|
218
204
|
logger.trace('Patching complete',
|
|
219
|
-
module: module_data.
|
|
220
|
-
result:
|
|
221
|
-
|
|
205
|
+
module: module_data.mod_name,
|
|
206
|
+
result:
|
|
207
|
+
Contrast::Agent::Patching::Policy::PatchStatus.get_status(module_data.mod).patch_status)
|
|
222
208
|
end
|
|
223
209
|
|
|
224
210
|
# Get all of the instance methods on the given module, excluding
|
|
@@ -249,22 +235,45 @@ module Contrast
|
|
|
249
235
|
instance_methods
|
|
250
236
|
end
|
|
251
237
|
|
|
238
|
+
# Patch into the Instance Methods, including private, of the given Module that match the ModulePolicy
|
|
239
|
+
# provided.
|
|
240
|
+
#
|
|
241
|
+
# @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
|
|
242
|
+
# @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
|
|
243
|
+
# this module, sorted by type.
|
|
244
|
+
def patch_into_instance_methods module_data, module_policy
|
|
245
|
+
mod = module_data.mod
|
|
246
|
+
methods = all_instance_methods(mod, true)
|
|
247
|
+
patch_into_methods(mod, methods, module_policy, true)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Patch into the Singleton Methods of the given Module that match the ModulePolicy provided.
|
|
251
|
+
#
|
|
252
|
+
# @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
|
|
253
|
+
# @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
|
|
254
|
+
# this module, sorted by type.
|
|
255
|
+
def patch_into_singleton_methods module_data, module_policy
|
|
256
|
+
mod = module_data.mod
|
|
257
|
+
methods = mod.singleton_methods(false)
|
|
258
|
+
patch_into_methods(mod, methods, module_policy, false)
|
|
259
|
+
end
|
|
260
|
+
|
|
252
261
|
# We've found the patchers that apply to this class (or module). Now we'll
|
|
253
262
|
# filter on the given method.
|
|
254
263
|
#
|
|
255
|
-
# @param mod [Module] The module from which to retrieve instance
|
|
256
|
-
#
|
|
257
|
-
# @param
|
|
258
|
-
#
|
|
259
|
-
# @param
|
|
260
|
-
#
|
|
261
|
-
# @
|
|
262
|
-
# are the instance or singleton methods for this module.
|
|
263
|
-
# @return [Integer] number of methods patched
|
|
264
|
+
# @param mod [Module] The module from which to retrieve instance methods.
|
|
265
|
+
# @param methods [Array<Symbol>] The names of all the methods in in this module
|
|
266
|
+
# @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
|
|
267
|
+
# this class, sorted by type.
|
|
268
|
+
# @param is_instance_method [Boolean] Indicates if these methods are the instance or singleton methods for
|
|
269
|
+
# this module.
|
|
270
|
+
# @return [Integer] number of methods patched.
|
|
264
271
|
def patch_into_methods mod, methods, module_policy, is_instance_method
|
|
265
272
|
count = 0
|
|
266
273
|
methods.each do |method|
|
|
267
|
-
method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.build_method_policy(method,
|
|
274
|
+
method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.build_method_policy(method,
|
|
275
|
+
module_policy,
|
|
276
|
+
is_instance_method)
|
|
268
277
|
next if method_policy.empty?
|
|
269
278
|
|
|
270
279
|
patched = patch_method(mod, methods, method_policy)
|
|
@@ -279,11 +288,10 @@ module Contrast
|
|
|
279
288
|
# it has to be reapplied.
|
|
280
289
|
# TODO: RUBY-620 should remove the need for this
|
|
281
290
|
#
|
|
282
|
-
# @param
|
|
283
|
-
# be accounted
|
|
291
|
+
# @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
|
|
284
292
|
# @return [Boolean] if an adjustment was made or not
|
|
285
|
-
def adjust_for_prepend
|
|
286
|
-
return false unless mod.cs__name == 'CGI::Util'
|
|
293
|
+
def adjust_for_prepend module_data
|
|
294
|
+
return false unless module_data.mod.cs__name == 'CGI::Util'
|
|
287
295
|
|
|
288
296
|
CGI.include(CGI::Util)
|
|
289
297
|
CGI.extend(CGI::Util)
|