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
|
require 'contrast/agent/deadzone/policy/deadzone_node'
|
|
@@ -8,8 +8,8 @@ module Contrast
|
|
|
8
8
|
module Agent
|
|
9
9
|
module Deadzone
|
|
10
10
|
module Policy
|
|
11
|
-
# This is just a holder for our policy. Takes the policy JSON and
|
|
12
|
-
#
|
|
11
|
+
# This is just a holder for our policy. Takes the policy JSON and converts it into hashes that we can access
|
|
12
|
+
# nicely.
|
|
13
13
|
class Policy < Contrast::Agent::Patching::Policy::Policy
|
|
14
14
|
def self.policy_folder
|
|
15
15
|
'deadzone'
|
|
@@ -35,6 +35,10 @@ module Contrast
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
def module_names
|
|
39
|
+
@_module_names ||= Set.new(deadzones.map(&:class_name))
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
def add_node node, _node_type = :deadzones
|
|
39
43
|
unless node
|
|
40
44
|
logger.error('Node was nil when adding node to policy')
|
|
@@ -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'
|
|
@@ -13,9 +13,7 @@ module Contrast
|
|
|
13
13
|
access_component :agent, :logging
|
|
14
14
|
|
|
15
15
|
def self.run _reaction, level
|
|
16
|
-
logger.with_level(
|
|
17
|
-
level,
|
|
18
|
-
'Contrast received instructions to disable itself - Disabling now')
|
|
16
|
+
logger.with_level(level, 'Contrast received instructions to disable itself - Disabling now')
|
|
19
17
|
AGENT.disable!
|
|
20
18
|
end
|
|
21
19
|
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'
|
|
@@ -47,7 +47,7 @@ module Contrast
|
|
|
47
47
|
return if @wildcard_url
|
|
48
48
|
return unless @exclusion.urls&.any?
|
|
49
49
|
|
|
50
|
-
@wildcard_url ||= @exclusion.urls.any?
|
|
50
|
+
@wildcard_url ||= @exclusion.urls.any?('/.*')
|
|
51
51
|
return if @wildcard_url
|
|
52
52
|
|
|
53
53
|
@urls = []
|
|
@@ -95,8 +95,8 @@ module Contrast
|
|
|
95
95
|
@exclusion.type == Contrast::Api::Settings::Exclusion::ExclusionType::CODE
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def
|
|
99
|
-
@exclusion.name
|
|
98
|
+
def exc_name
|
|
99
|
+
@exclusion.name # rubocop:disable Security/Module/Name -- part of the API.
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
def match_all?
|
|
@@ -109,10 +109,7 @@ module Contrast
|
|
|
109
109
|
#
|
|
110
110
|
# @param rule - the id of the rule which we're checking for exclusion
|
|
111
111
|
def protection_rule? rule
|
|
112
|
-
protect? &&
|
|
113
|
-
(@exclusion.protection_rules.empty? ||
|
|
114
|
-
@exclusion.protection_rules.include?(rule)
|
|
115
|
-
)
|
|
112
|
+
protect? && (@exclusion.protection_rules.empty? || @exclusion.protection_rules.include?(rule))
|
|
116
113
|
end
|
|
117
114
|
|
|
118
115
|
# Determine if the given rule is excluded by this exclusion.
|
|
@@ -121,10 +118,7 @@ module Contrast
|
|
|
121
118
|
#
|
|
122
119
|
# @param rule - the id of the rule which we're checking for exclusion
|
|
123
120
|
def assess_rule? rule
|
|
124
|
-
assess? &&
|
|
125
|
-
(@exclusion.assessment_rules.empty? ||
|
|
126
|
-
@exclusion.assessment_rules.include?(rule)
|
|
127
|
-
)
|
|
121
|
+
assess? && (@exclusion.assessment_rules.empty? || @exclusion.assessment_rules.include?(rule))
|
|
128
122
|
end
|
|
129
123
|
|
|
130
124
|
def match_code? stack_trace
|
|
@@ -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
|
|
@@ -10,6 +10,5 @@ module Contrast
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
require 'contrast/agent/inventory/dependencies'
|
|
13
|
-
require 'contrast/agent/inventory/gemfile_digest_cache'
|
|
14
13
|
require 'contrast/agent/inventory/dependency_usage_analysis'
|
|
15
14
|
require 'contrast/agent/inventory/dependency_analysis'
|
|
@@ -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,6 +33,7 @@ module Contrast
|
|
|
33
33
|
# then contrast depends on it. If its array of dependents is 1, then contrast is the
|
|
34
34
|
# only dependency in that list. Since only contrast depends on it, we should ignore it.
|
|
35
35
|
def find_contrast_gems
|
|
36
|
+
# rubocop:disable Security/Module/Name -- here name is part of Ruby Gems.
|
|
36
37
|
ignore = Set.new([CONTRAST_AGENT])
|
|
37
38
|
contrast_specs = Gem::DependencyList.from_specs.specs.find do |dependency|
|
|
38
39
|
dependency.name == CONTRAST_AGENT
|
|
@@ -43,6 +44,7 @@ module Contrast
|
|
|
43
44
|
ignore.add(dependency.name) if contrast_dep_set.include?(dependency.name) && dependents.length == 1
|
|
44
45
|
end
|
|
45
46
|
ignore
|
|
47
|
+
# rubocop:enable Security/Module/Name
|
|
46
48
|
end
|
|
47
49
|
end
|
|
48
50
|
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/inventory/dependencies'
|
|
@@ -1,10 +1,10 @@
|
|
|
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
|
-
require 'contrast/agent/inventory/gemfile_digest_cache'
|
|
5
4
|
require 'contrast/agent/inventory/dependencies'
|
|
6
5
|
require 'contrast/components/interface'
|
|
7
6
|
require 'contrast/utils/object_share'
|
|
7
|
+
require 'set'
|
|
8
8
|
|
|
9
9
|
module Contrast
|
|
10
10
|
module Agent
|
|
@@ -20,33 +20,35 @@ module Contrast
|
|
|
20
20
|
def initialize
|
|
21
21
|
return unless enabled?
|
|
22
22
|
|
|
23
|
-
@
|
|
23
|
+
@lock = Mutex.new
|
|
24
|
+
@lock.synchronize { @gemdigest_cache = Hash.new { |hash, key| hash[key] = Set.new } }
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
# This method is invoked once, along with the rest of our catchup code
|
|
27
|
-
#
|
|
27
|
+
# This method is invoked once, along with the rest of our catchup code to report libraries and their associated
|
|
28
|
+
# files that have already been loaded pre-contrast.
|
|
28
29
|
def catchup
|
|
29
30
|
return unless enabled?
|
|
30
31
|
|
|
31
32
|
loaded_specs.each do |_name, spec|
|
|
32
|
-
# Get a digest of the Gem file itself
|
|
33
|
+
# Get a digest of the Gem file itself.
|
|
33
34
|
next unless (digest = Contrast::Utils::Sha256Builder.instance.build_from_spec(spec))
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
36
|
+
loaded_files_from_gem = $LOADED_FEATURES.select { |f| f.start_with?(spec.full_gem_path) }
|
|
37
|
+
|
|
38
|
+
new_files = loaded_files_from_gem.each_with_object(Set.new) do |file_path, set|
|
|
39
|
+
set << adjust_path_for_reporting(file_path, spec)
|
|
40
|
+
logger.trace('Recording loaded file for inventory analysis', line: file_path)
|
|
41
41
|
end
|
|
42
|
+
|
|
43
|
+
# Even if new_files is empty, still need to add digest key for library discovery.
|
|
44
|
+
@lock.synchronize { @gemdigest_cache[digest].merge(new_files) }
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
47
|
|
|
45
|
-
# This method is invoked once per TracePoint :end - to map a specific
|
|
46
|
-
#
|
|
48
|
+
# This method is invoked once per TracePoint :end - to map a specific file being required to the gem to which
|
|
49
|
+
# it belongs.
|
|
47
50
|
#
|
|
48
|
-
# @param path [String] the result of TracePoint#path from the :end
|
|
49
|
-
# event in which the Module was defined
|
|
51
|
+
# @param path [String] the result of TracePoint#path from the :end event in which the Module was defined.
|
|
50
52
|
def associate_file path
|
|
51
53
|
return unless enabled?
|
|
52
54
|
|
|
@@ -64,21 +66,31 @@ module Contrast
|
|
|
64
66
|
return
|
|
65
67
|
end
|
|
66
68
|
report_path = adjust_path_for_reporting(path, spec)
|
|
67
|
-
@gemdigest_cache
|
|
69
|
+
@lock.synchronize { @gemdigest_cache[digest] << report_path }
|
|
68
70
|
rescue StandardError => e
|
|
69
71
|
logger.error('Unable to inventory file path', e, path: path)
|
|
70
72
|
end
|
|
71
73
|
|
|
72
|
-
# Populate the library_usages
|
|
73
|
-
# data stored in the @gemdigest_cache
|
|
74
|
+
# Populate the library_usages field of the Activity message using the data stored in the @gemdigest_cache.
|
|
74
75
|
#
|
|
75
|
-
# @param activity [Contrast::Api::Dtm::Activity] the message to which
|
|
76
|
-
# to append the usage data
|
|
76
|
+
# @param activity [Contrast::Api::Dtm::Activity] the message to which to append the usage data
|
|
77
77
|
def generate_library_usage activity
|
|
78
78
|
return unless enabled?
|
|
79
|
-
return
|
|
79
|
+
return unless activity
|
|
80
|
+
|
|
81
|
+
# Copy gemdigest_cache and clear it in sync.
|
|
82
|
+
gem_spec_digest_to_files = @lock.synchronize do
|
|
83
|
+
copy = @gemdigest_cache.dup
|
|
84
|
+
@gemdigest_cache.clear
|
|
85
|
+
copy
|
|
86
|
+
end
|
|
80
87
|
|
|
81
|
-
|
|
88
|
+
gem_spec_digest_to_files.each_pair do |digest, files|
|
|
89
|
+
usage = Contrast::Api::Dtm::LibraryUsageUpdate.build(digest, files)
|
|
90
|
+
activity.library_usages[usage.hash_code] = usage
|
|
91
|
+
end
|
|
92
|
+
rescue StandardError => e
|
|
93
|
+
logger.error('Unable to generate library usage.', e)
|
|
82
94
|
end
|
|
83
95
|
|
|
84
96
|
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/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/inventory/policy/trigger_node'
|
|
@@ -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/trigger_node'
|
|
@@ -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 'ipaddr'
|
|
@@ -16,18 +16,17 @@ require 'contrast/utils/timer'
|
|
|
16
16
|
|
|
17
17
|
module Contrast
|
|
18
18
|
module Agent
|
|
19
|
-
# This class allows the Agent to plug into the Rack middleware stack. When the
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# as it goes through the middleware stack inside of #call.
|
|
19
|
+
# This class allows the Agent to plug into the Rack middleware stack. When the application is first started, we
|
|
20
|
+
# initialize ourselves as a rack middleware inside of #initialize. Afterwards, we process each http request and
|
|
21
|
+
# response as it goes through the middleware stack inside of #call.
|
|
23
22
|
class Middleware
|
|
24
23
|
include Contrast::Components::Interface
|
|
25
24
|
access_component :agent, :config, :logging, :scope, :settings
|
|
26
25
|
|
|
27
26
|
attr_reader :app
|
|
28
27
|
|
|
29
|
-
# Allows the Agent to function as a middleware. We perform all our one-time whole-app routines in here
|
|
30
|
-
#
|
|
28
|
+
# Allows the Agent to function as a middleware. We perform all our one-time whole-app routines in here since
|
|
29
|
+
# we're only going to be initialized a single time. Our initialization order is:
|
|
31
30
|
# - capture the application
|
|
32
31
|
# - setup the Agent
|
|
33
32
|
# - startup the Agent
|
|
@@ -38,52 +37,27 @@ module Contrast
|
|
|
38
37
|
@app = app # THIS MUST BE FIRST AND ALWAYS SET!
|
|
39
38
|
setup_agent # THIS MUST BE SECOND AND ALWAYS CALLED!
|
|
40
39
|
unless AGENT.enabled?
|
|
41
|
-
logger.error(
|
|
42
|
-
|
|
40
|
+
logger.error('The Agent was unable to initialize before the application middleware was initialized. '\
|
|
41
|
+
'Disabling permanently.')
|
|
43
42
|
AGENT.disable! # ensure the agent is disabled (probably redundant)
|
|
44
43
|
return
|
|
45
44
|
end
|
|
46
45
|
agent_startup_routine
|
|
47
46
|
end
|
|
48
47
|
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# processing messages
|
|
52
|
-
# - start the heartbeat thread, which triggers service startup
|
|
53
|
-
# - start instrumenting libraries and do a 'catchup' patch for everything
|
|
54
|
-
# we didn't see get loaded
|
|
55
|
-
# - enable TracePoint, which handles all class loads and required
|
|
56
|
-
# instrumentation going forward
|
|
57
|
-
def agent_startup_routine
|
|
58
|
-
logger.debug_with_time('middleware: starting service') do
|
|
59
|
-
Contrast::Agent.thread_watcher.ensure_running?
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
logger.debug_with_time('middleware: instrument shared libraries and patch') do
|
|
63
|
-
Contrast::Agent::Patching::Policy::Patcher.patch
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
AGENT.enable_tracepoint
|
|
67
|
-
Contrast::Agent::AtExitHook.exit_hook
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# This is where we're hooked into the middleware stack. If the agent is enabled, we're ready
|
|
71
|
-
# to do some processing on a per request basis. If not, we just pass the request along to the
|
|
72
|
-
# next middleware in the stack.
|
|
48
|
+
# This is where we're hooked into the middleware stack. If the agent is enabled, we're ready to do some
|
|
49
|
+
# processing on a per request basis. If not, we just pass the request along to the next middleware in the stack.
|
|
73
50
|
#
|
|
74
|
-
# @param env [Hash] the various variables stored by this and other Middlewares to know the state
|
|
75
|
-
#
|
|
76
|
-
# @return [Array,Rack::Response] the Response of this and subsequent Middlewares to be passed back
|
|
77
|
-
#
|
|
51
|
+
# @param env [Hash] the various variables stored by this and other Middlewares to know the state and values of
|
|
52
|
+
# this Request
|
|
53
|
+
# @return [Array,Rack::Response] the Response of this and subsequent Middlewares to be passed back to the user up
|
|
54
|
+
# the Rack framework.
|
|
78
55
|
def call env
|
|
79
|
-
|
|
56
|
+
return app.call(env) unless AGENT.enabled?
|
|
80
57
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
else
|
|
85
|
-
app.call(env)
|
|
86
|
-
end
|
|
58
|
+
Contrast::Agent.heapdump_util.start_thread!
|
|
59
|
+
handle_first_request
|
|
60
|
+
call_with_agent(env)
|
|
87
61
|
end
|
|
88
62
|
|
|
89
63
|
private
|
|
@@ -103,73 +77,56 @@ module Contrast
|
|
|
103
77
|
end
|
|
104
78
|
end
|
|
105
79
|
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
80
|
+
# Startup the Agent as part of the initialization process:
|
|
81
|
+
# - start the service sending thread, responsible for sending and processing messages
|
|
82
|
+
# - start the heartbeat thread, which triggers service startup
|
|
83
|
+
# - start instrumenting libraries and do a 'catchup' patch for everything we didn't see get loaded
|
|
84
|
+
# - enable TracePoint, which handles all class loads and required instrumentation going forward
|
|
85
|
+
def agent_startup_routine
|
|
86
|
+
logger.debug_with_time('middleware: starting service') do
|
|
87
|
+
Contrast::Agent.thread_watcher.ensure_running?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
logger.debug_with_time('middleware: instrument shared libraries and patch') do
|
|
91
|
+
Contrast::Agent::Patching::Policy::Patcher.patch
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
logger.debug_with_time('middleware: enabling tracepoint') do
|
|
95
|
+
AGENT.enable_tracepoint
|
|
96
|
+
end
|
|
97
|
+
Contrast::Agent::AtExitHook.exit_hook
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Some things have to wait until first request to happen, either because resolution is not complete or because
|
|
101
|
+
# the framework will preload classes, which confuses some of our instrumentation.
|
|
109
102
|
def handle_first_request
|
|
110
103
|
@_handle_first_request ||= begin
|
|
111
104
|
Contrast::Agent::StaticAnalysis.catchup
|
|
112
|
-
force_patching
|
|
113
105
|
true
|
|
114
106
|
end
|
|
115
107
|
end
|
|
116
108
|
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
def force_patching
|
|
125
|
-
force_patch(ActionDispatch::FileHandler) if defined?(ActionDispatch::FileHandler)
|
|
126
|
-
force_patch(ActionDispatch::Http::MimeNegotiation) if defined?(ActionDispatch::Http::MimeNegotiation)
|
|
127
|
-
force_patch(ActionView::Template) if defined?(ActionView::Template)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def force_patch mod
|
|
131
|
-
data = Contrast::Agent::ModuleData.new(mod)
|
|
132
|
-
Contrast::Agent::Patching::Policy::Patcher.send(:patch_into_module, data, true)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# This is where we process each request we intercept as a middleware. We make the request context
|
|
136
|
-
# available globally so that it can be accessed from anywhere. A RequestHandler object is made
|
|
137
|
-
# for each request, which handles prefilter and postfilter operations.
|
|
109
|
+
# This is where we process each request we intercept as a middleware. We make the request context available
|
|
110
|
+
# globally so that it can be accessed from anywhere. A RequestHandler object is made for each request, which
|
|
111
|
+
# handles prefilter and postfilter operations.
|
|
112
|
+
# @param env [Hash] the various variables stored by this and other Middlewares to know the state and values of
|
|
113
|
+
# this Request
|
|
114
|
+
# @return [Array,Rack::Response] the Response of this and subsequent Middlewares to be passed back to the user
|
|
115
|
+
# up the Rack framework.
|
|
138
116
|
def call_with_agent env
|
|
139
117
|
Contrast::Agent.thread_watcher.ensure_running?
|
|
140
|
-
return unless AGENT.enabled?
|
|
141
|
-
|
|
142
118
|
framework_request = Contrast::Agent.framework_manager.retrieve_request(env)
|
|
143
119
|
context = Contrast::Agent::RequestContext.new(framework_request)
|
|
144
120
|
response = nil
|
|
145
121
|
|
|
146
|
-
#
|
|
122
|
+
# Make the context available for the lifecycle of this request.
|
|
147
123
|
Contrast::Agent::REQUEST_TRACKER.lifespan(context) do
|
|
148
124
|
logger.request_start
|
|
149
125
|
request_handler = Contrast::Agent::RequestHandler.new(context)
|
|
150
126
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
request_handler.ruleset.prefilter
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
response = application_code(env) # pass request down the Rack chain with original env
|
|
158
|
-
|
|
159
|
-
# postfilter sequence
|
|
160
|
-
with_contrast_scope do
|
|
161
|
-
context.extract_after(response) # update context with final response information
|
|
162
|
-
|
|
163
|
-
if Contrast::Agent.framework_manager.streaming?(env)
|
|
164
|
-
context.reset_activity
|
|
165
|
-
request_handler.stream_safe_postfilter
|
|
166
|
-
else
|
|
167
|
-
request_handler.ruleset.postfilter
|
|
168
|
-
# return response stored in the context in case any postfilter rules updated the response data
|
|
169
|
-
response = context.response&.rack_response || response
|
|
170
|
-
request_handler.send_activity_messages
|
|
171
|
-
end
|
|
172
|
-
end
|
|
127
|
+
pre_call_with_agent(context, request_handler)
|
|
128
|
+
response = application_code(env)
|
|
129
|
+
post_call_with_agent(context, env, request_handler, response)
|
|
173
130
|
ensure
|
|
174
131
|
logger.request_end
|
|
175
132
|
end
|
|
@@ -179,6 +136,47 @@ module Contrast
|
|
|
179
136
|
handle_exception(e)
|
|
180
137
|
end
|
|
181
138
|
|
|
139
|
+
# Handle the operations the Agent needs to accomplish prior to the Application code executing during this
|
|
140
|
+
# request.
|
|
141
|
+
#
|
|
142
|
+
# @param context [Contrast::Agent::RequestContext]
|
|
143
|
+
# @param request_handler [Contrast::Agent::RequestHandler]
|
|
144
|
+
def pre_call_with_agent context, request_handler
|
|
145
|
+
with_contrast_scope do
|
|
146
|
+
context.service_extract_request
|
|
147
|
+
request_handler.ruleset.prefilter
|
|
148
|
+
end
|
|
149
|
+
rescue StandardError => e
|
|
150
|
+
raise e if security_exception?(e)
|
|
151
|
+
|
|
152
|
+
logger.error('Unable to execute agent pre_call', e)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Handle the operations the Agent needs to accomplish after the Application code executes during this request.
|
|
156
|
+
#
|
|
157
|
+
# @param context [Contrast::Agent::RequestContext]
|
|
158
|
+
# @param env [Hash] the various variables stored by this and other Middlewares to know the state and values of
|
|
159
|
+
# this Request
|
|
160
|
+
# @param request_handler [Contrast::Agent::RequestHandler]
|
|
161
|
+
# @param response [Array,Rack::Response]
|
|
162
|
+
def post_call_with_agent context, env, request_handler, response
|
|
163
|
+
with_contrast_scope do
|
|
164
|
+
context.extract_after(response) # update context with final response information
|
|
165
|
+
|
|
166
|
+
if Contrast::Agent.framework_manager.streaming?(env)
|
|
167
|
+
context.reset_activity
|
|
168
|
+
request_handler.stream_safe_postfilter
|
|
169
|
+
else
|
|
170
|
+
request_handler.ruleset.postfilter
|
|
171
|
+
request_handler.send_activity_messages
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
rescue StandardError => e
|
|
175
|
+
raise e if security_exception?(e)
|
|
176
|
+
|
|
177
|
+
logger.error('Unable to execute agent post_call', e)
|
|
178
|
+
end
|
|
179
|
+
|
|
182
180
|
def application_code env
|
|
183
181
|
logger.trace_with_time('application') do
|
|
184
182
|
app.call(env)
|
|
@@ -189,12 +187,10 @@ module Contrast
|
|
|
189
187
|
end
|
|
190
188
|
|
|
191
189
|
SECURITY_EXCEPTION_MARKER = 'Contrast::SecurityException'
|
|
192
|
-
# We're only going to suppress SecurityExceptions indicating a blocked attack.
|
|
193
|
-
#
|
|
190
|
+
# We're only going to suppress SecurityExceptions indicating a blocked attack. And, only if the
|
|
191
|
+
# config.agent.ruby.exceptions.capture? is set
|
|
194
192
|
def handle_exception exception
|
|
195
|
-
if
|
|
196
|
-
exception.message&.include?(SECURITY_EXCEPTION_MARKER)
|
|
197
|
-
|
|
193
|
+
if security_exception?(exception)
|
|
198
194
|
exception_control = AGENT.exception_control
|
|
199
195
|
raise exception unless exception_control[:enable]
|
|
200
196
|
|
|
@@ -205,18 +201,23 @@ module Contrast
|
|
|
205
201
|
end
|
|
206
202
|
end
|
|
207
203
|
|
|
208
|
-
#
|
|
209
|
-
#
|
|
210
|
-
#
|
|
211
|
-
#
|
|
204
|
+
# Is the given exception one raised by our Protect code?
|
|
205
|
+
#
|
|
206
|
+
# @param exception [Exception]
|
|
207
|
+
# @return [Boolean]
|
|
208
|
+
def security_exception? exception
|
|
209
|
+
exception.is_a?(Contrast::SecurityException) || exception.message&.include?(SECURITY_EXCEPTION_MARKER)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# As we deprecate support to prepare to remove dead code, we need to inform our users still relying on the now
|
|
213
|
+
# deprecated and soon to be removed functionality. This method handles doing that by leveraging the standard
|
|
214
|
+
# Kernel#warn approach
|
|
212
215
|
def inform_deprecations
|
|
213
|
-
# Ruby 2.5 is currently in security maintenance, meaning int is only
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
# the
|
|
217
|
-
#
|
|
218
|
-
# TODO: RUBY-715 remove this part of the method, leaving it empty if
|
|
219
|
-
# there are no other deprecations, when we drop 2.5 support.
|
|
216
|
+
# Ruby 2.5 is currently in security maintenance, meaning int is only receiving updates for security issues. It
|
|
217
|
+
# will move to eol on 31 March 2021. As such, we can remove support for it in Q3. We'll begin the deprecation
|
|
218
|
+
# warnings now so that customers have time to reach out if they'll be impacted.
|
|
219
|
+
# TODO: RUBY-715 remove this part of the method, leaving it empty if there are no other deprecations, when we
|
|
220
|
+
# drop 2.5 support.
|
|
220
221
|
return unless RUBY_VERSION < '2.6.0'
|
|
221
222
|
|
|
222
223
|
Kernel.warn('[Contrast Security] [DEPRECATION] Support for Ruby 2.5 will be removed in April 2021. '\
|