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 'json'
|
|
@@ -13,8 +13,9 @@ module Contrast
|
|
|
13
13
|
module Agent
|
|
14
14
|
module Patching
|
|
15
15
|
module Policy
|
|
16
|
-
# This is just a holder for our policy. Takes the policy JSON and
|
|
17
|
-
#
|
|
16
|
+
# This is just a holder for our policy. Takes the policy JSON and converts it into hashes that we can access
|
|
17
|
+
# nicely.
|
|
18
|
+
#
|
|
18
19
|
# @abstract
|
|
19
20
|
class Policy
|
|
20
21
|
include Singleton
|
|
@@ -25,8 +26,8 @@ module Contrast
|
|
|
25
26
|
raise(NoMethodError, 'specify policy_folder for patching')
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
# Indicates is this feature has been disabled by the configuration,
|
|
29
|
-
#
|
|
29
|
+
# Indicates is this feature has been disabled by the configuration, read at startup, and therefore can never
|
|
30
|
+
# be enabled.
|
|
30
31
|
def disabled_globally?
|
|
31
32
|
raise(NoMethodError, 'specify disabled_globally? conditions for patching')
|
|
32
33
|
end
|
|
@@ -58,17 +59,15 @@ module Contrast
|
|
|
58
59
|
from_hash_string(json)
|
|
59
60
|
end
|
|
60
61
|
|
|
61
|
-
# Our policy for patching rules is a 'dope ass' JSON file. Rather than
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
# This let's us be flexible and extensible.
|
|
62
|
+
# Our policy for patching rules is a 'dope ass' JSON file. Rather than hard code in a bunch of things to
|
|
63
|
+
# monkey patch, we let the JSON file define the conditions in which modifications are applied. This let's us
|
|
64
|
+
# be flexible and extensible.
|
|
65
65
|
def from_hash_string string
|
|
66
|
-
# The default behavior of the agent is to load the policy on startup,
|
|
67
|
-
#
|
|
66
|
+
# The default behavior of the agent is to load the policy on startup, as at this point we do not know in
|
|
67
|
+
# which mode we'll be run.
|
|
68
68
|
#
|
|
69
|
-
# If the configuration file explicitly disables a feature, we know
|
|
70
|
-
#
|
|
71
|
-
# can skip policy loading.
|
|
69
|
+
# If the configuration file explicitly disables a feature, we know that we will not ever be able to enable
|
|
70
|
+
# it, so in that case, we can skip policy loading.
|
|
72
71
|
return if disabled_globally?
|
|
73
72
|
|
|
74
73
|
policy_data = JSON.parse(string)
|
|
@@ -110,13 +109,7 @@ module Contrast
|
|
|
110
109
|
end
|
|
111
110
|
|
|
112
111
|
def module_names
|
|
113
|
-
@_module_names ||=
|
|
114
|
-
m = Set.new
|
|
115
|
-
sources.each { |source| m << source.class_name }
|
|
116
|
-
propagators.each { |propagator| m << propagator.class_name }
|
|
117
|
-
triggers.each { |trigger| m << trigger.class_name }
|
|
118
|
-
m
|
|
119
|
-
end
|
|
112
|
+
@_module_names ||= Set.new([sources, propagators, triggers].flatten.map!(&:class_name))
|
|
120
113
|
end
|
|
121
114
|
|
|
122
115
|
def find_triggers_by_rule rule_id
|
|
@@ -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'
|
|
@@ -44,10 +44,20 @@ module Contrast
|
|
|
44
44
|
# later on. Really, if they don't have these things, they couldn't have
|
|
45
45
|
# done their jobs anyway.
|
|
46
46
|
def validate
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
unless class_name
|
|
48
|
+
raise(ArgumentError, "#{ node_class } #{ id } did not have a proper class name. Unable to create.")
|
|
49
|
+
end
|
|
50
|
+
unless method_name
|
|
51
|
+
raise(ArgumentError, "#{ node_class } #{ id } did not have a proper method name. Unable to create.")
|
|
52
|
+
end
|
|
53
|
+
unless method_name.is_a?(Symbol)
|
|
54
|
+
raise(ArgumentError, "#{ node_class } #{ id } has a non symbol @method_name value. Unable to create.")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
unless method_visibility.is_a?(Symbol)
|
|
58
|
+
raise(ArgumentError,
|
|
59
|
+
"#{ node_class } #{ id } has a non symbol @method_visibility value. Unable to create.")
|
|
60
|
+
end
|
|
51
61
|
unless method_scope.nil? || Contrast::Agent::Scope.valid_scope?(method_scope)
|
|
52
62
|
raise(ArgumentError, "#{ node_class } #{ id } requires an undefined scope. Unable to create.")
|
|
53
63
|
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/extension/module'
|
|
@@ -21,7 +21,8 @@ module Contrast
|
|
|
21
21
|
JSON_OPTIONAL_PROPS = 'optional_properties'
|
|
22
22
|
JSON_ON_EXCEPTION = 'on_exception'
|
|
23
23
|
|
|
24
|
-
attr_reader :applicator, :applicator_method, :on_exception, :optional_properties, :required_properties,
|
|
24
|
+
attr_reader :applicator, :applicator_method, :on_exception, :optional_properties, :required_properties,
|
|
25
|
+
:rule_id
|
|
25
26
|
|
|
26
27
|
def initialize trigger_hash = {}, rule_hash = {}
|
|
27
28
|
super(trigger_hash)
|
|
@@ -42,27 +43,42 @@ module Contrast
|
|
|
42
43
|
|
|
43
44
|
def validate
|
|
44
45
|
super
|
|
45
|
-
unless applicator.public_methods(false).any?
|
|
46
|
+
unless applicator.public_methods(false).any?(applicator_method)
|
|
46
47
|
raise(ArgumentError,
|
|
47
|
-
"#{ id } did not have a proper applicator method:
|
|
48
|
+
"#{ id } did not have a proper applicator method: "\
|
|
49
|
+
"#{ applicator } does not respond to #{ applicator_method }. Unable to create.")
|
|
48
50
|
end
|
|
51
|
+
validate_properties
|
|
52
|
+
validate_rule
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def validate_properties
|
|
49
56
|
if (required_properties & optional_properties).any?
|
|
50
|
-
raise(ArgumentError,
|
|
57
|
+
raise(ArgumentError,
|
|
58
|
+
"#{ rule_id } had overlapping elements between required and optional properties. Unable to create.")
|
|
51
59
|
end
|
|
52
60
|
if (properties.keys - (required_properties | optional_properties)).any?
|
|
53
61
|
raise(ArgumentError, "#{ id } had an unexpected property. Unable to create.")
|
|
54
62
|
end
|
|
55
|
-
raise(ArgumentError, "#{ id } did not have a required property. Unable to create.") if (required_properties - properties.keys).any?
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
return unless (required_properties - properties.keys).any?
|
|
65
|
+
|
|
66
|
+
raise(ArgumentError, "#{ id } did not have a required property. Unable to create.")
|
|
58
67
|
end
|
|
59
68
|
|
|
60
69
|
def validate_rule
|
|
61
70
|
raise(ArgumentError, 'Unknown rule did not have a proper name. Unable to create.') unless rule_id
|
|
62
71
|
raise(ArgumentError, "#{ id } did not have a proper applicator. Unable to create.") unless applicator
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
|
|
73
|
+
unless applicator_method
|
|
74
|
+
raise(ArgumentError, "#{ id } did not have a proper applicator method. Unable to create.")
|
|
75
|
+
end
|
|
76
|
+
unless required_properties
|
|
77
|
+
raise(ArgumentError, "#{ id } did not have a proper set of required properties. Unable to create.")
|
|
78
|
+
end
|
|
79
|
+
return if optional_properties
|
|
80
|
+
|
|
81
|
+
raise(ArgumentError, "#{ id } did not have a proper set of optional properties. Unable to create.")
|
|
66
82
|
end
|
|
67
83
|
|
|
68
84
|
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/agent/protect/rule/cmd_injection'
|
|
@@ -37,7 +37,7 @@ module Contrast
|
|
|
37
37
|
|
|
38
38
|
protected
|
|
39
39
|
|
|
40
|
-
def
|
|
40
|
+
def rule_name
|
|
41
41
|
Contrast::Agent::Protect::Rule::CmdInjection::NAME
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -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/protect/rule/deserialization'
|
|
@@ -71,7 +71,7 @@ module Contrast
|
|
|
71
71
|
|
|
72
72
|
protected
|
|
73
73
|
|
|
74
|
-
def
|
|
74
|
+
def rule_name
|
|
75
75
|
Contrast::Agent::Protect::Rule::Deserialization::NAME
|
|
76
76
|
end
|
|
77
77
|
|
|
@@ -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/protect/rule/no_sqli'
|
|
@@ -34,7 +34,7 @@ module Contrast
|
|
|
34
34
|
|
|
35
35
|
protected
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def rule_name
|
|
38
38
|
Contrast::Agent::Protect::Rule::NoSqli::NAME
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -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/protect/rule/path_traversal'
|
|
@@ -42,15 +42,14 @@ module Contrast
|
|
|
42
42
|
|
|
43
43
|
protected
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def rule_name
|
|
46
46
|
Contrast::Agent::Protect::Rule::PathTraversal::NAME
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
private
|
|
50
50
|
|
|
51
51
|
def possible_write? input
|
|
52
|
-
input.cs__respond_to?(:to_s) &&
|
|
53
|
-
input.to_s.include?(Contrast::Utils::ObjectShare::WRITE_FLAG)
|
|
52
|
+
input.cs__respond_to?(:to_s) && input.to_s.include?(Contrast::Utils::ObjectShare::WRITE_FLAG)
|
|
54
53
|
end
|
|
55
54
|
|
|
56
55
|
READ = 'read'
|
|
@@ -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/protect/rule/sqli'
|
|
@@ -34,7 +34,7 @@ module Contrast
|
|
|
34
34
|
|
|
35
35
|
protected
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def rule_name
|
|
38
38
|
Contrast::Agent::Protect::Rule::Sqli::NAME
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -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/protect/rule/xxe'
|
|
@@ -49,16 +49,15 @@ module Contrast
|
|
|
49
49
|
|
|
50
50
|
protected
|
|
51
51
|
|
|
52
|
-
def
|
|
52
|
+
def rule_name
|
|
53
53
|
Contrast::Agent::Protect::Rule::Xxe::NAME
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
-
DATA_KEY =
|
|
58
|
+
DATA_KEY = :@data
|
|
59
59
|
def valid_data_input? object
|
|
60
|
-
object.instance_variable_defined?(DATA_KEY) &&
|
|
61
|
-
object.instance_variable_get(DATA_KEY)
|
|
60
|
+
object.instance_variable_defined?(DATA_KEY) && object.instance_variable_get(DATA_KEY)
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
NOKOGIRI_MARKER = 'Nokogiri::'
|
|
@@ -115,11 +114,8 @@ module Contrast
|
|
|
115
114
|
raise e
|
|
116
115
|
rescue StandardError => e
|
|
117
116
|
parser ||= Contrast::Utils::ObjectShare::UNKNOWN
|
|
118
|
-
logger.error(
|
|
119
|
-
|
|
120
|
-
e,
|
|
121
|
-
module: potential_parser.cs__class.cs__name,
|
|
122
|
-
method: method, parser: parser)
|
|
117
|
+
logger.error('Error applying xxe', e, module: potential_parser.cs__class.cs__name, method: method,
|
|
118
|
+
parser: parser)
|
|
123
119
|
end
|
|
124
120
|
end
|
|
125
121
|
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/patching/policy/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'
|
|
@@ -42,7 +42,8 @@ module Contrast
|
|
|
42
42
|
rescue Contrast::SecurityException => e
|
|
43
43
|
raise e
|
|
44
44
|
rescue StandardError => e
|
|
45
|
-
logger.error('Error applying protect rule', e, module: object.cs__class.cs__name, method: method,
|
|
45
|
+
logger.error('Error applying protect rule', e, module: object.cs__class.cs__name, method: method,
|
|
46
|
+
rule: rule_name)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
protected
|
|
@@ -68,11 +69,10 @@ module Contrast
|
|
|
68
69
|
raise NoMethodError, 'This is abstract, override it.'
|
|
69
70
|
end
|
|
70
71
|
|
|
71
|
-
# The name of the rule, as expected by the Contrast Service and
|
|
72
|
-
# Contrast UI.
|
|
72
|
+
# The name of the rule, as expected by the Contrast Service and Contrast UI.
|
|
73
73
|
#
|
|
74
74
|
# @return [String]
|
|
75
|
-
def
|
|
75
|
+
def rule_name
|
|
76
76
|
raise NoMethodError, 'This is abstract, override it.'
|
|
77
77
|
end
|
|
78
78
|
|
|
@@ -82,7 +82,7 @@ module Contrast
|
|
|
82
82
|
#
|
|
83
83
|
# @return [Contrast::Agent::Protect::Rule::Base]
|
|
84
84
|
def rule
|
|
85
|
-
PROTECT.rule
|
|
85
|
+
PROTECT.rule rule_name
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
# Should we skip analysis for this rule for this method invocation?
|
|
@@ -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
|
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
|
require 'contrast/components/interface'
|
|
@@ -36,42 +36,31 @@ module Contrast
|
|
|
36
36
|
|
|
37
37
|
attr_reader :mode
|
|
38
38
|
|
|
39
|
-
def initialize
|
|
40
|
-
PROTECT.rules[
|
|
41
|
-
@mode = mode_from_settings
|
|
39
|
+
def initialize
|
|
40
|
+
PROTECT.rules[rule_name] = self
|
|
41
|
+
@mode = mode_from_settings
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Should return the name as it is known to Teamserver; defaults to class
|
|
45
|
-
def
|
|
46
|
-
cs__class.
|
|
45
|
+
def rule_name
|
|
46
|
+
cs__class.cs__name
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
OFF = 'off'
|
|
50
|
-
|
|
51
49
|
def enabled?
|
|
52
50
|
# 1. it is not enabled because protect is not enabled
|
|
53
51
|
return false unless AGENT.enabled?
|
|
54
52
|
return false unless PROTECT.enabled?
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# 2. it is not enabled because it is in the list of disabled protect rules
|
|
59
|
-
disabled_rules = rule_configs.disabled_rules
|
|
60
|
-
return false if disabled_rules&.include?(name)
|
|
61
|
-
|
|
62
|
-
# 3. it is not enabled because it has been turned "off" explicitly
|
|
63
|
-
rule_config = rule_configs.send(name)
|
|
64
|
-
|
|
65
|
-
return rule_config.mode != OFF unless rule_config.mode.nil?
|
|
66
|
-
end
|
|
54
|
+
# 2. it is not enabled because it is in the list of disabled protect rules
|
|
55
|
+
return false if PROTECT.rule_config&.disabled_rules&.include?(rule_name)
|
|
67
56
|
|
|
68
|
-
#
|
|
69
|
-
@mode !=
|
|
57
|
+
# 3. it is enabled so long as its mode is not NO_ACTION
|
|
58
|
+
@mode != Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION
|
|
70
59
|
end
|
|
71
60
|
|
|
72
61
|
def excluded? exclusions
|
|
73
62
|
Array(exclusions).any? do |ex|
|
|
74
|
-
ex.protection_rule?(
|
|
63
|
+
ex.protection_rule?(rule_name)
|
|
75
64
|
end
|
|
76
65
|
end
|
|
77
66
|
|
|
@@ -187,8 +176,8 @@ module Contrast
|
|
|
187
176
|
protected
|
|
188
177
|
|
|
189
178
|
def mode_from_settings
|
|
190
|
-
PROTECT.rule_mode(
|
|
191
|
-
logger.trace('Retrieving rule mode', rule:
|
|
179
|
+
PROTECT.rule_mode(rule_name).tap do |mode|
|
|
180
|
+
logger.trace('Retrieving rule mode', rule: rule_name, mode: mode)
|
|
192
181
|
end
|
|
193
182
|
end
|
|
194
183
|
|
|
@@ -205,7 +194,7 @@ module Contrast
|
|
|
205
194
|
exclusions = SETTINGS.code_exclusions
|
|
206
195
|
return false unless exclusions
|
|
207
196
|
|
|
208
|
-
for_rule = exclusions.select { |ex| ex.protection_rule?(
|
|
197
|
+
for_rule = exclusions.select { |ex| ex.protection_rule?(rule_name) }
|
|
209
198
|
return false if for_rule.empty?
|
|
210
199
|
|
|
211
200
|
stack = caller_locations
|
|
@@ -224,7 +213,7 @@ module Contrast
|
|
|
224
213
|
# @param _kwargs [Hash] key-value pairs used by the rule to build a
|
|
225
214
|
# report.
|
|
226
215
|
def find_attacker _context, _potential_attack_string, **_kwargs
|
|
227
|
-
raise NoMethodError, "Rule #{
|
|
216
|
+
raise NoMethodError, "Rule #{ rule_name } did not implement find_attack"
|
|
228
217
|
end
|
|
229
218
|
|
|
230
219
|
def update_successful_attack_response context, ia_result, result, attack_string = nil
|
|
@@ -260,7 +249,7 @@ module Contrast
|
|
|
260
249
|
# @return [Contrast::Api::Dtm::AttackResult]
|
|
261
250
|
def build_attack_result _context
|
|
262
251
|
result = Contrast::Api::Dtm::AttackResult.new
|
|
263
|
-
result.rule_id =
|
|
252
|
+
result.rule_id = rule_name
|
|
264
253
|
result
|
|
265
254
|
end
|
|
266
255
|
|
|
@@ -297,7 +286,7 @@ module Contrast
|
|
|
297
286
|
|
|
298
287
|
def log_rule_matched _context, ia_result, response, _matched_string = nil
|
|
299
288
|
logger.debug('A successful attack was detected',
|
|
300
|
-
rule:
|
|
289
|
+
rule: rule_name,
|
|
301
290
|
type: ia_result&.input_type,
|
|
302
291
|
name: ia_result&.key,
|
|
303
292
|
input: ia_result&.value,
|
|
@@ -307,11 +296,8 @@ module Contrast
|
|
|
307
296
|
private
|
|
308
297
|
|
|
309
298
|
def log_rule_probed _context, ia_result
|
|
310
|
-
logger.debug('An unsuccessful attack was detected',
|
|
311
|
-
|
|
312
|
-
type: ia_result&.input_type,
|
|
313
|
-
name: ia_result&.key,
|
|
314
|
-
input: ia_result&.value)
|
|
299
|
+
logger.debug('An unsuccessful attack was detected', rule: rule_name, type: ia_result&.input_type,
|
|
300
|
+
name: ia_result&.key, input: ia_result&.value)
|
|
315
301
|
end
|
|
316
302
|
end
|
|
317
303
|
end
|