contrast-agent 6.7.0 → 6.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/.simplecov +0 -1
- data/Rakefile +0 -1
- data/ext/cs__assess_array/cs__assess_array.c +41 -10
- data/ext/cs__assess_array/cs__assess_array.h +4 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +3 -3
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +1 -1
- data/lib/contrast/agent/assess/property/evented.rb +11 -11
- data/lib/contrast/agent/assess.rb +0 -1
- data/lib/contrast/agent/excluder.rb +53 -35
- data/lib/contrast/agent/exclusion_matcher.rb +21 -9
- data/lib/contrast/agent/middleware.rb +12 -6
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +6 -0
- data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +146 -127
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +116 -0
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +20 -0
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +1 -1
- data/lib/contrast/agent/protect/rule/base.rb +47 -55
- data/lib/contrast/agent/protect/rule/base_service.rb +48 -24
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +98 -0
- data/lib/contrast/agent/protect/rule/bot_blocker.rb +81 -0
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +20 -2
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +8 -5
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +22 -22
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +64 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +63 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +2 -58
- data/lib/contrast/agent/protect/rule/default_scanner.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +3 -14
- data/lib/contrast/agent/protect/rule/http_method_tampering/http_method_tampering_input_classification.rb +2 -2
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +0 -11
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +29 -34
- data/lib/contrast/agent/protect/rule/no_sqli.rb +25 -18
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_input_classification.rb +61 -0
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +114 -0
- data/lib/contrast/agent/protect/rule/path_traversal.rb +40 -13
- data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +33 -15
- data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +0 -14
- data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +2 -62
- data/lib/contrast/agent/protect/rule/sqli.rb +74 -3
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +39 -63
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +6 -33
- data/lib/contrast/agent/protect/rule/xss/reflected_xss_input_classification.rb +58 -0
- data/lib/contrast/agent/protect/rule/xss.rb +15 -20
- data/lib/contrast/agent/protect/rule/xxe.rb +4 -24
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +19 -40
- data/lib/contrast/agent/reporting/attack_result/response_type.rb +9 -9
- data/lib/contrast/agent/reporting/details/ip_denylist_details.rb +10 -2
- data/lib/contrast/agent/reporting/details/virtual_patch_details.rb +8 -2
- data/lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb +27 -0
- data/lib/contrast/agent/reporting/input_analysis/details/protect_rule_details.rb +15 -0
- data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +1 -2
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +16 -2
- data/lib/contrast/agent/reporting/masker/masker.rb +2 -0
- data/lib/contrast/agent/reporting/report.rb +1 -0
- data/lib/contrast/agent/reporting/reporter.rb +35 -14
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +3 -9
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +16 -13
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +12 -7
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_activity.rb +3 -3
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +1 -2
- data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -1
- data/lib/contrast/agent/reporting/reporting_events/application_update.rb +0 -2
- data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +6 -6
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +239 -93
- data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -23
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +10 -9
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +0 -5
- data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -0
- data/lib/contrast/agent/reporting/reporting_events/poll.rb +1 -11
- data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_events/server_reporting_event.rb +8 -0
- data/lib/contrast/agent/reporting/reporting_events/server_settings.rb +40 -0
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +2 -2
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +6 -0
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +43 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +8 -4
- data/lib/contrast/agent/reporting/reporting_utilities/response.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +58 -4
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +4 -6
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +77 -16
- data/lib/contrast/agent/reporting/server_settings_worker.rb +44 -0
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +14 -2
- data/lib/contrast/agent/reporting/settings/code_exclusion.rb +6 -1
- data/lib/contrast/agent/reporting/settings/exclusion_base.rb +18 -0
- data/lib/contrast/agent/reporting/settings/exclusions.rb +2 -1
- data/lib/contrast/agent/reporting/settings/helpers.rb +7 -0
- data/lib/contrast/agent/reporting/settings/input_exclusion.rb +9 -3
- data/lib/contrast/agent/reporting/settings/protect.rb +15 -15
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +39 -2
- data/lib/contrast/agent/reporting/settings/rule_definition.rb +3 -0
- data/lib/contrast/agent/reporting/settings/security_logger.rb +77 -0
- data/lib/contrast/agent/reporting/settings/server_features.rb +9 -0
- data/lib/contrast/agent/reporting/settings/syslog.rb +34 -5
- data/lib/contrast/agent/request.rb +3 -14
- data/lib/contrast/agent/request_context.rb +6 -9
- data/lib/contrast/agent/request_context_extend.rb +9 -148
- data/lib/contrast/agent/request_handler.rb +5 -10
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +1 -1
- data/lib/contrast/agent/thread_watcher.rb +37 -18
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +6 -11
- data/lib/contrast/agent_lib/api/command_injection.rb +46 -0
- data/lib/contrast/agent_lib/api/init.rb +101 -0
- data/lib/contrast/agent_lib/api/input_tracing.rb +267 -0
- data/lib/contrast/agent_lib/api/method_tempering.rb +29 -0
- data/lib/contrast/agent_lib/api/panic.rb +87 -0
- data/lib/contrast/agent_lib/api/path_semantic_file_security_bypass.rb +40 -0
- data/lib/contrast/agent_lib/interface.rb +260 -0
- data/lib/contrast/agent_lib/interface_base.rb +118 -0
- data/lib/contrast/agent_lib/return_types/eval_result.rb +44 -0
- data/lib/contrast/agent_lib/test.rb +29 -0
- data/lib/contrast/api/communication/connection_status.rb +20 -5
- data/lib/contrast/components/agent.rb +34 -14
- data/lib/contrast/components/api.rb +23 -0
- data/lib/contrast/components/app_context.rb +23 -5
- data/lib/contrast/components/app_context_extend.rb +0 -25
- data/lib/contrast/components/assess.rb +34 -4
- data/lib/contrast/components/assess_rules.rb +18 -0
- data/lib/contrast/components/base.rb +40 -0
- data/lib/contrast/components/config/sources.rb +95 -0
- data/lib/contrast/components/config.rb +19 -19
- data/lib/contrast/components/heap_dump.rb +10 -0
- data/lib/contrast/components/inventory.rb +15 -2
- data/lib/contrast/components/logger.rb +18 -0
- data/lib/contrast/components/polling.rb +36 -0
- data/lib/contrast/components/protect.rb +52 -2
- data/lib/contrast/components/ruby_component.rb +16 -1
- data/lib/contrast/components/sampling.rb +70 -13
- data/lib/contrast/components/security_logger.rb +13 -0
- data/lib/contrast/components/settings.rb +105 -90
- data/lib/contrast/config/certification_configuration.rb +14 -0
- data/lib/contrast/config/config.rb +46 -0
- data/lib/contrast/config/diagnostics.rb +114 -0
- data/lib/contrast/config/diagnostics_tools.rb +98 -0
- data/lib/contrast/config/effective_config.rb +65 -0
- data/lib/contrast/config/effective_config_value.rb +32 -0
- data/lib/contrast/config/exception_configuration.rb +12 -0
- data/lib/contrast/config/protect_rule_configuration.rb +8 -8
- data/lib/contrast/config/protect_rules_configuration.rb +23 -60
- data/lib/contrast/config/request_audit_configuration.rb +13 -0
- data/lib/contrast/config/server_configuration.rb +41 -2
- data/lib/contrast/configuration.rb +29 -12
- data/lib/contrast/extension/assess/array.rb +9 -0
- data/lib/contrast/extension/assess/erb.rb +1 -1
- data/lib/contrast/extension/delegator.rb +2 -0
- data/lib/contrast/framework/manager.rb +3 -1
- data/lib/contrast/framework/rails/railtie.rb +0 -1
- data/lib/contrast/framework/rails/support.rb +0 -1
- data/lib/contrast/tasks/config.rb +1 -8
- data/lib/contrast/utils/assess/event_limit_utils.rb +31 -9
- data/lib/contrast/utils/assess/trigger_method_utils.rb +5 -4
- data/lib/contrast/utils/duck_utils.rb +1 -0
- data/lib/contrast/utils/hash_digest.rb +2 -2
- data/lib/contrast/utils/input_classification_base.rb +155 -0
- data/lib/contrast/utils/os.rb +0 -20
- data/lib/contrast/utils/reporting/application_activity_batch_utils.rb +81 -0
- data/lib/contrast/utils/response_utils.rb +0 -16
- data/lib/contrast/utils/routes_sent.rb +60 -0
- data/lib/contrast/utils/stack_trace_utils.rb +3 -15
- data/lib/contrast/utils/string_utils.rb +10 -7
- data/lib/contrast/utils/telemetry_client.rb +1 -2
- data/lib/contrast/utils/timer.rb +16 -0
- data/lib/contrast.rb +5 -4
- data/resources/protect/policy.json +1 -2
- data/ruby-agent.gemspec +7 -6
- metadata +69 -130
- data/exe/contrast_service +0 -23
- data/lib/contrast/agent/assess/contrast_event.rb +0 -157
- data/lib/contrast/agent/assess/events/event_factory.rb +0 -34
- data/lib/contrast/agent/assess/events/source_event.rb +0 -46
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_worth_watching.rb +0 -64
- data/lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb +0 -118
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_matcher.rb +0 -45
- data/lib/contrast/agent/reaction_processor.rb +0 -47
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -36
- data/lib/contrast/agent/service_heartbeat.rb +0 -35
- data/lib/contrast/api/communication/messaging_queue.rb +0 -128
- data/lib/contrast/api/communication/response_processor.rb +0 -90
- data/lib/contrast/api/communication/service_lifecycle.rb +0 -77
- data/lib/contrast/api/communication/socket.rb +0 -44
- data/lib/contrast/api/communication/socket_client.rb +0 -130
- data/lib/contrast/api/communication/speedracer.rb +0 -138
- data/lib/contrast/api/communication/tcp_socket.rb +0 -32
- data/lib/contrast/api/communication/unix_socket.rb +0 -28
- data/lib/contrast/api/communication.rb +0 -20
- data/lib/contrast/api/decorators/address.rb +0 -59
- data/lib/contrast/api/decorators/agent_startup.rb +0 -56
- data/lib/contrast/api/decorators/application_settings.rb +0 -43
- data/lib/contrast/api/decorators/application_startup.rb +0 -56
- data/lib/contrast/api/decorators/bot_blocker.rb +0 -37
- data/lib/contrast/api/decorators/http_request.rb +0 -137
- data/lib/contrast/api/decorators/input_analysis.rb +0 -18
- data/lib/contrast/api/decorators/instrumentation_mode.rb +0 -35
- data/lib/contrast/api/decorators/ip_denylist.rb +0 -37
- data/lib/contrast/api/decorators/message.rb +0 -67
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +0 -52
- data/lib/contrast/api/decorators/response_type.rb +0 -17
- data/lib/contrast/api/decorators/server_features.rb +0 -25
- data/lib/contrast/api/decorators/user_input.rb +0 -51
- data/lib/contrast/api/decorators/virtual_patch.rb +0 -34
- data/lib/contrast/api/decorators.rb +0 -22
- data/lib/contrast/api/dtm.pb.rb +0 -363
- data/lib/contrast/api/settings.pb.rb +0 -500
- data/lib/contrast/api.rb +0 -16
- data/lib/contrast/components/contrast_service.rb +0 -88
- data/lib/contrast/components/service.rb +0 -55
- data/lib/contrast/tasks/service.rb +0 -84
- data/lib/contrast/utils/input_classification.rb +0 -73
- data/lib/protobuf/code_generator.rb +0 -129
- data/lib/protobuf/decoder.rb +0 -28
- data/lib/protobuf/deprecation.rb +0 -117
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +0 -79
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +0 -360
- data/lib/protobuf/descriptors.rb +0 -3
- data/lib/protobuf/encoder.rb +0 -11
- data/lib/protobuf/enum.rb +0 -365
- data/lib/protobuf/exceptions.rb +0 -9
- data/lib/protobuf/field/base_field.rb +0 -380
- data/lib/protobuf/field/base_field_object_definitions.rb +0 -504
- data/lib/protobuf/field/bool_field.rb +0 -64
- data/lib/protobuf/field/bytes_field.rb +0 -67
- data/lib/protobuf/field/double_field.rb +0 -25
- data/lib/protobuf/field/enum_field.rb +0 -56
- data/lib/protobuf/field/field_array.rb +0 -102
- data/lib/protobuf/field/field_hash.rb +0 -122
- data/lib/protobuf/field/fixed32_field.rb +0 -25
- data/lib/protobuf/field/fixed64_field.rb +0 -28
- data/lib/protobuf/field/float_field.rb +0 -43
- data/lib/protobuf/field/int32_field.rb +0 -21
- data/lib/protobuf/field/int64_field.rb +0 -34
- data/lib/protobuf/field/integer_field.rb +0 -23
- data/lib/protobuf/field/message_field.rb +0 -51
- data/lib/protobuf/field/sfixed32_field.rb +0 -27
- data/lib/protobuf/field/sfixed64_field.rb +0 -28
- data/lib/protobuf/field/signed_integer_field.rb +0 -29
- data/lib/protobuf/field/sint32_field.rb +0 -21
- data/lib/protobuf/field/sint64_field.rb +0 -21
- data/lib/protobuf/field/string_field.rb +0 -51
- data/lib/protobuf/field/uint32_field.rb +0 -21
- data/lib/protobuf/field/uint64_field.rb +0 -21
- data/lib/protobuf/field/varint_field.rb +0 -77
- data/lib/protobuf/field.rb +0 -74
- data/lib/protobuf/generators/base.rb +0 -85
- data/lib/protobuf/generators/enum_generator.rb +0 -39
- data/lib/protobuf/generators/extension_generator.rb +0 -27
- data/lib/protobuf/generators/field_generator.rb +0 -193
- data/lib/protobuf/generators/file_generator.rb +0 -262
- data/lib/protobuf/generators/group_generator.rb +0 -122
- data/lib/protobuf/generators/message_generator.rb +0 -104
- data/lib/protobuf/generators/option_generator.rb +0 -17
- data/lib/protobuf/generators/printable.rb +0 -160
- data/lib/protobuf/generators/service_generator.rb +0 -50
- data/lib/protobuf/lifecycle.rb +0 -33
- data/lib/protobuf/logging.rb +0 -39
- data/lib/protobuf/message/fields.rb +0 -233
- data/lib/protobuf/message/serialization.rb +0 -85
- data/lib/protobuf/message.rb +0 -241
- data/lib/protobuf/optionable.rb +0 -72
- data/lib/protobuf/tasks/compile.rake +0 -80
- data/lib/protobuf/tasks.rb +0 -1
- data/lib/protobuf/varint.rb +0 -20
- data/lib/protobuf/varint_pure.rb +0 -31
- data/lib/protobuf/version.rb +0 -3
- data/lib/protobuf/wire_type.rb +0 -10
- data/lib/protobuf.rb +0 -91
- data/proto/dynamic_discovery.proto +0 -46
- data/proto/google/protobuf/compiler/plugin.proto +0 -183
- data/proto/google/protobuf/descriptor.proto +0 -911
- data/proto/rpc.proto +0 -71
- data/service_executables/.gitkeep +0 -0
- data/service_executables/VERSION +0 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
@@ -21,6 +21,14 @@ module Contrast
|
|
21
21
|
def since_last_update
|
22
22
|
(update_time = Contrast::SETTINGS.last_server_update_ms) ? Contrast::Utils::Timer.now_ms - update_time : 0
|
23
23
|
end
|
24
|
+
|
25
|
+
# Human readable last time update for header set. Set to 0 if the agent is just starting and have not received
|
26
|
+
# the latest header from TS.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
def since_last_update_httpdate
|
30
|
+
Contrast::SETTINGS.server_settings_last_httpdate || Contrast::Utils::Timer.ms_to_httpdate(0)
|
31
|
+
end
|
24
32
|
end
|
25
33
|
end
|
26
34
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/reporting/reporting_events/server_reporting_event'
|
5
|
+
require 'contrast/agent/reporting/reporting_utilities/endpoints'
|
6
|
+
require 'contrast/utils/timer'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Agent
|
10
|
+
module Reporting
|
11
|
+
# This class will initialize a GET request to be send to TS. The server settings endpoint is the way the Agent
|
12
|
+
# receives server sittings - Protect rules settings, patterns, keywords and deny/allow lists, log setting.
|
13
|
+
class ServerSettings < Contrast::Agent::Reporting::ServerReportingEvent
|
14
|
+
def initialize
|
15
|
+
@event_method = :GET
|
16
|
+
@event_endpoint = Contrast::Agent::Reporting::Endpoints.server_settings
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def file_name
|
21
|
+
'server-settings'
|
22
|
+
end
|
23
|
+
|
24
|
+
# Attach the last server settings received timestamp to the request as it is required.
|
25
|
+
#
|
26
|
+
# If-Modified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
|
27
|
+
# @param request [Net::HTTPRequest]
|
28
|
+
def attach_headers request
|
29
|
+
request['If-Modified-Since'] = since_last_update_httpdate
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash]
|
33
|
+
# @raise [ArgumentError]
|
34
|
+
def to_controlled_hash
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -19,8 +19,8 @@ module Contrast
|
|
19
19
|
generate_paths if enabled?
|
20
20
|
end
|
21
21
|
|
22
|
-
# This method will be handling the auditing of the requests and responses we send to
|
23
|
-
# feature is enabled, we'll log to file the request and/or response
|
22
|
+
# This method will be handling the auditing of the requests and responses we send to TeamServer. If the audit
|
23
|
+
# feature is enabled, we'll log to file the request and/or response JSON objects.
|
24
24
|
#
|
25
25
|
# @param event [Contrast::Agent::Reporting::ReportingEvent] One of the DTMs valid for the
|
26
26
|
# event field of Contrast::Agent::Reporting::ReportingEvent
|
@@ -10,6 +10,8 @@ require 'contrast/agent/reporting/reporting_utilities/response_handler'
|
|
10
10
|
require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
|
11
11
|
require 'contrast/agent/reporting/reporting_utilities/endpoints'
|
12
12
|
require 'contrast/agent/reporting/reporting_utilities/headers'
|
13
|
+
require 'contrast/agent/reporting/reporting_events/server_settings'
|
14
|
+
require 'contrast/config/diagnostics'
|
13
15
|
|
14
16
|
module Contrast
|
15
17
|
module Agent
|
@@ -21,8 +23,10 @@ module Contrast
|
|
21
23
|
|
22
24
|
include Contrast::Agent::Reporting::Endpoints
|
23
25
|
include Contrast::Agent::Reporting::ReporterClientUtils
|
26
|
+
include Contrast::Agent::Reporting::ResponseHandlerUtils
|
24
27
|
include Contrast::Components::Logger::InstanceMethods
|
25
28
|
SERVICE_NAME = 'Reporter'
|
29
|
+
REPORT_CONFIG_WHEN = %w[200 304].cs__freeze
|
26
30
|
def initialize
|
27
31
|
@headers = Contrast::Agent::Reporting::Headers.new
|
28
32
|
super()
|
@@ -61,13 +65,47 @@ module Contrast
|
|
61
65
|
request = build_request(event)
|
62
66
|
response = connection.request(request)
|
63
67
|
audit&.audit_event(event, response) if ::Contrast::API.request_audit_enable
|
64
|
-
process_settings_response(response)
|
68
|
+
process_settings_response(response, event)
|
69
|
+
record_status(response, event)
|
70
|
+
record_configuration(response, event)
|
65
71
|
process_preflight_response(event, response, connection)
|
66
72
|
response
|
67
73
|
rescue StandardError => e
|
68
74
|
handle_error(event, e)
|
69
75
|
end
|
70
76
|
|
77
|
+
# This is going to populate the config status value in the diagnostics json
|
78
|
+
#
|
79
|
+
# @param response [Contrast::Agent::Reporting::Response, nil]
|
80
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent]
|
81
|
+
def record_status response, event
|
82
|
+
return unless response
|
83
|
+
return unless event&.cs__class == Contrast::Agent::Reporting::AgentStartup ||
|
84
|
+
event&.cs__class == Contrast::Agent::Reporting::ApplicationStartup
|
85
|
+
|
86
|
+
diagnostics.config.determine_config_status(response)
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
# Write effective config to file:
|
91
|
+
# If we are here the create and server messages are sent and the code received is
|
92
|
+
# 200 or 304. In case of 304 there will be no new settings and we can write current ones.
|
93
|
+
# This is done on every settings request.
|
94
|
+
#
|
95
|
+
# @param response [Contrast::Agent::Reporting::Response, nil]
|
96
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent]
|
97
|
+
def record_configuration response, event
|
98
|
+
return unless response
|
99
|
+
return unless REPORT_CONFIG_WHEN.include?(response_handler.last_response_code)
|
100
|
+
return unless event&.cs__class == Contrast::Agent::Reporting::ServerSettings ||
|
101
|
+
event&.cs__class == Contrast::Agent::Reporting::AgentStartup ||
|
102
|
+
event&.cs__class == Contrast::Agent::Reporting::ApplicationStartup
|
103
|
+
|
104
|
+
logger.info('[Reporter Diagnostics] last response code:', response_code: response_handler.last_response_code)
|
105
|
+
diagnostics.write_to_file
|
106
|
+
status.server_response_success!
|
107
|
+
end
|
108
|
+
|
71
109
|
def status
|
72
110
|
@_status ||= Contrast::Api::Communication::ConnectionStatus.new
|
73
111
|
end
|
@@ -76,6 +114,10 @@ module Contrast
|
|
76
114
|
@_response_handler ||= Contrast::Agent::Reporting::ResponseHandler.new
|
77
115
|
end
|
78
116
|
|
117
|
+
def diagnostics
|
118
|
+
@_diagnostics ||= Contrast::Agent::DiagnosticsConfig::Diagnostics.new(Contrast::LOGGER.path)
|
119
|
+
end
|
120
|
+
|
79
121
|
def sleep?
|
80
122
|
response_handler.sleep?
|
81
123
|
end
|
@@ -84,10 +84,12 @@ module Contrast
|
|
84
84
|
|
85
85
|
# Handles response processing and sets status
|
86
86
|
#
|
87
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
|
87
88
|
# @param response [Net::HTTP::Response]
|
88
|
-
def process_settings_response response
|
89
|
-
response_handler.process(response)
|
90
|
-
status.success!
|
89
|
+
def process_settings_response response, event
|
90
|
+
res = response_handler.process(response, event)
|
91
|
+
status.success! if res
|
92
|
+
res
|
91
93
|
end
|
92
94
|
|
93
95
|
# Given a response from preflght, when the finding hash is desired, then send the finding to which it pertains.
|
@@ -100,7 +102,7 @@ module Contrast
|
|
100
102
|
# @param connection [Net::HTTP] open connection
|
101
103
|
def process_preflight_response event, response, connection
|
102
104
|
return unless event.cs__is_a?(Contrast::Agent::Reporting::Preflight)
|
103
|
-
return unless response && connection
|
105
|
+
return unless response&.body && connection
|
104
106
|
|
105
107
|
findings_to_return = response.body.split(',').delete_if { |el| el.include?('*') }
|
106
108
|
findings_to_return.each do |index|
|
@@ -125,6 +127,8 @@ module Contrast
|
|
125
127
|
request = case event.event_method
|
126
128
|
when :PUT
|
127
129
|
Net::HTTP::Put.new(event.event_endpoint)
|
130
|
+
when :GET
|
131
|
+
Net::HTTP::Get.new(event.event_endpoint)
|
128
132
|
else # :POST
|
129
133
|
Net::HTTP::Post.new(event.event_endpoint)
|
130
134
|
end
|
@@ -19,7 +19,7 @@ module Contrast
|
|
19
19
|
|
20
20
|
# All of the feature server_features
|
21
21
|
#
|
22
|
-
# @return [Contrast::Agent::Reporting::Settings::
|
22
|
+
# @return [Contrast::Agent::Reporting::Settings::ServerFeatures, nil]
|
23
23
|
attr_accessor :server_features
|
24
24
|
|
25
25
|
# Success boolean message value
|
@@ -49,13 +49,20 @@ module Contrast
|
|
49
49
|
res.reactions = response_data[:reactions] if response_data[:features]
|
50
50
|
end
|
51
51
|
|
52
|
+
# This method is universal and used for both ng endpoing of feature settings and the new
|
53
|
+
# Server settings endpoint. Used in both build_feature_settings and build_server_settings.
|
54
|
+
# Passing the ng_ flag determines the use of the endpoint and response used because some of
|
55
|
+
# the response fields are with different names or do not exist: [enabled vs enable]
|
56
|
+
#
|
52
57
|
# @param response_data [Hash]
|
53
58
|
# @param res [Contrast::Agent::Reporting::Response]
|
54
|
-
|
55
|
-
|
59
|
+
# @param ng_ [Boolean]
|
60
|
+
def extract_assess_settings response_data, res, ng_: true
|
61
|
+
assess = ng_ ? response_data[:features][:assessment] : response_data[:assess]
|
56
62
|
return unless assess
|
57
63
|
|
58
|
-
res.server_features.assess.enabled = assess[:enabled]
|
64
|
+
res.server_features.assess.enabled = ng_ ? assess[:enabled] : assess[:enable]
|
65
|
+
res.server_features.assess.report_stacktraces = assess[:report_stacktraces] unless ng_
|
59
66
|
res.server_features.assess.sampling = assess[:sampling]
|
60
67
|
res.server_features.assess.sanitizers = assess[:sanitizers]
|
61
68
|
res.server_features.assess.validators = assess[:validators]
|
@@ -78,7 +85,7 @@ module Contrast
|
|
78
85
|
def extract_syslog response_data, res
|
79
86
|
return unless (syslog = response_data[:features][:defend][:syslog])
|
80
87
|
|
81
|
-
res.server_features.protect.syslog.assign_array(syslog)
|
88
|
+
res.server_features.protect.syslog.assign_array(syslog, ng_: true)
|
82
89
|
end
|
83
90
|
|
84
91
|
# @param response_data [Hash]
|
@@ -116,6 +123,53 @@ module Contrast
|
|
116
123
|
res.server_features.log_level = log_level
|
117
124
|
res.server_features.log_file = response_data[:logFile] if response_data[:logFile]
|
118
125
|
end
|
126
|
+
|
127
|
+
# This method is used with ServerSettings as we expect to have data for
|
128
|
+
# all the loggers - security_logger, logger, syslog.
|
129
|
+
#
|
130
|
+
# @param response_data [Hash]
|
131
|
+
# @param res [Contrast::Agent::Reporting::Response]
|
132
|
+
def extract_loggers response_data, res
|
133
|
+
logger = response_data[:logger]
|
134
|
+
security_logger = response_data[:security_logger]
|
135
|
+
|
136
|
+
if logger
|
137
|
+
res.server_features.log_level = logger[:level]
|
138
|
+
res.server_features.log_file = logger[:path]
|
139
|
+
end
|
140
|
+
return unless security_logger
|
141
|
+
|
142
|
+
log_level = security_logger[:level]
|
143
|
+
log_file = security_logger[:path]
|
144
|
+
res.server_features.security_logger.log_level = log_level
|
145
|
+
res.server_features.security_logger.log_file = log_file
|
146
|
+
res.server_features.security_logger.not_blank!
|
147
|
+
res.server_features.security_logger.syslog.assign_array(response_data[:security_logger][:syslog], ng_: false)
|
148
|
+
end
|
149
|
+
|
150
|
+
# @param response_data [Hash]
|
151
|
+
# @param res [Contrast::Agent::Reporting::Response]
|
152
|
+
def extract_protect_server_settings response_data, res
|
153
|
+
protect = response_data[:protect]
|
154
|
+
return unless protect
|
155
|
+
|
156
|
+
res.server_features.protect.enabled = protect[:enable]
|
157
|
+
res.server_features.protect.observability = protect[:observability]
|
158
|
+
res.server_features.protect.log_enhancers = protect[:log_enhancers]
|
159
|
+
update_protect_rules(protect, res)
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param protect [Hash] response data
|
163
|
+
# @param res [Contrast::Agent::Reporting::Response]
|
164
|
+
def update_protect_rules protect, res
|
165
|
+
return unless (rules = protect[:rules])
|
166
|
+
|
167
|
+
res.server_features.protect.ip_allowlist = rules[:ip_allowlist]
|
168
|
+
res.server_features.protect.ip_denylist = rules[:ip_denylist]
|
169
|
+
res.server_features.protect.bot_blocker.enable = rules[:bot_blocker][:enable]
|
170
|
+
res.server_features.protect.bot_blocker.bots = rules[:bot_blocker][:bots]
|
171
|
+
res.server_features.protect.rules_to_definition_list(rules)
|
172
|
+
end
|
119
173
|
end
|
120
174
|
end
|
121
175
|
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
# Copyright (c) 2022 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/api/communication/response_processor'
|
5
|
-
require 'contrast/api/decorators/application_settings'
|
6
4
|
require 'contrast/agent/reporting/reporting_utilities/response'
|
7
5
|
require 'contrast/agent/reporting/reporting_utilities/response_handler_utils'
|
8
6
|
require 'contrast/agent/reporting/reporting_utilities/response_handler_mode'
|
9
|
-
require 'contrast/api/decorators/server_features'
|
10
7
|
require 'contrast/components/logger'
|
11
8
|
require 'json'
|
12
9
|
|
@@ -23,13 +20,14 @@ module Contrast
|
|
23
20
|
# Process the response from TS
|
24
21
|
#
|
25
22
|
# @param response [Net::HTTP::Response, nil]
|
23
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
|
26
24
|
# @return response [Net::HTTP::Response, nil]
|
27
|
-
def process response
|
25
|
+
def process response, event
|
28
26
|
logger.debug('Reporter Received a response')
|
29
27
|
return unless analyze_response?(response)
|
30
28
|
|
31
29
|
# Handle the response body and obtain server_features or app_settings
|
32
|
-
report_response = convert_response(response)
|
30
|
+
report_response = convert_response(response, event)
|
33
31
|
return unless report_response
|
34
32
|
|
35
33
|
# Update Server Features and Application Settings to provide current agent settings
|
@@ -90,7 +88,7 @@ module Contrast
|
|
90
88
|
when ERROR_CODES[:too_many_requests]
|
91
89
|
handle_response_errors(response, RETRY_AFTER_MSG, mode.resending)
|
92
90
|
else
|
93
|
-
logger.error('
|
91
|
+
logger.error('Unable to execute agent post_call')
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/reporting/reporting_utilities/response_extractor'
|
5
|
+
require 'contrast/agent/disable_reaction'
|
5
6
|
|
6
7
|
module Contrast
|
7
8
|
module Agent
|
@@ -31,6 +32,17 @@ module Contrast
|
|
31
32
|
UNPROCESSABLE_ENTITY_MSG = 'Reporter received Unprocessable Entity response. Disabling permanently.'
|
32
33
|
RETRY_AFTER_MSG = "There are too many requests of this type being sent by this Agent. #{ SUSPEND_MSG }"
|
33
34
|
|
35
|
+
def last_response_code
|
36
|
+
@_last_response_code ||= ''
|
37
|
+
end
|
38
|
+
|
39
|
+
# String format of the Header:<day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def last_server_modified
|
43
|
+
@_last_server_modified
|
44
|
+
end
|
45
|
+
|
34
46
|
private
|
35
47
|
|
36
48
|
# check if response code is valid before analyze it
|
@@ -78,6 +90,11 @@ module Contrast
|
|
78
90
|
# in the standard format per RFC 2616
|
79
91
|
# used for in observed routes message.
|
80
92
|
return false unless response && (response_code = response&.code)
|
93
|
+
|
94
|
+
# We still need to check the response code even if we are not analyzing it, since the 304 code does not
|
95
|
+
# contain settings to be extracted but we still need to know for the diagnostics. Do not move this bellow
|
96
|
+
# the ANALYZE_WHEN check.
|
97
|
+
@_last_response_code = response_code
|
81
98
|
return true if ANALYZE_WHEN.include?(response_code)
|
82
99
|
|
83
100
|
handle_error(response) if ERROR_CODES.value?(response_code)
|
@@ -109,7 +126,7 @@ module Contrast
|
|
109
126
|
|
110
127
|
stop_reporting(message, application: Contrast::APP_CONTEXT.name, error_message: error_message) # rubocop:disable Security/Module/Name
|
111
128
|
rescue StandardError => e
|
112
|
-
logger.debug('Could not handle Response error information', error: e)
|
129
|
+
logger.debug('Could not handle Response error information', error: e, backtrace: e.backtrace)
|
113
130
|
end
|
114
131
|
|
115
132
|
# Extract what we've received.
|
@@ -126,6 +143,19 @@ module Contrast
|
|
126
143
|
[ready_after.to_i, error_message, auth_error]
|
127
144
|
end
|
128
145
|
|
146
|
+
# Extract Last-Modified header from ServerSettings response.
|
147
|
+
# The new GET server settings endpoint have different payload.
|
148
|
+
# Extract the last modify headers with last update form TS.
|
149
|
+
#
|
150
|
+
# @param response [Net::HTTP::Response, nil]
|
151
|
+
# @return last_modified[integer, nil] Time since last server update
|
152
|
+
def extract_response_last_modified response
|
153
|
+
return unless response.cs__is_a?(Net::HTTPResponse)
|
154
|
+
|
155
|
+
header = response['Last-Modified'] if response&.to_hash&.keys&.map(&:downcase)&.include?('last-modified')
|
156
|
+
@_last_server_modified = header if header
|
157
|
+
end
|
158
|
+
|
129
159
|
# Cease reporting about this application
|
130
160
|
#
|
131
161
|
# @param message [String] Message to log
|
@@ -193,27 +223,32 @@ module Contrast
|
|
193
223
|
# Converts response from Net to Reporting Response object
|
194
224
|
#
|
195
225
|
# @param response [Net::HTTP::Response, nil]
|
226
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
|
196
227
|
# @return response [Contrast::Agent::Reporting::Response]
|
197
|
-
def convert_response response
|
228
|
+
def convert_response response, event
|
198
229
|
response_body = response&.body
|
199
230
|
return unless response_body
|
200
231
|
|
201
232
|
response_data = JSON.parse(response_body, symbolize_names: true)
|
202
233
|
return unless response_data.cs__is_a?(Hash)
|
203
234
|
|
204
|
-
|
235
|
+
extract_response_last_modified(response)
|
236
|
+
populate_response(response_data, event)
|
205
237
|
rescue StandardError => e
|
206
238
|
logger.error('Unable to convert response', e)
|
207
239
|
nil
|
208
240
|
end
|
209
241
|
|
210
|
-
# Extracts the data from the response and coverts it to
|
211
|
-
#
|
242
|
+
# Extracts the data from the response and coverts it to Contrast::Agent::Reporting::Response.
|
243
|
+
# The response is being checked for it's type and settings received so the extractor methods
|
244
|
+
# are invoked accordingly to the response type.
|
212
245
|
#
|
213
246
|
# @param response_data[Hash]
|
214
|
-
# @
|
215
|
-
|
216
|
-
|
247
|
+
# @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
|
248
|
+
# this is used to check the expected response type for this event.
|
249
|
+
# @return response [Contrast::Agent::Reporting::Response, nil]
|
250
|
+
def populate_response response_data, event
|
251
|
+
return unless (success, messages = extract_success(response_data, event))
|
217
252
|
|
218
253
|
# check if response contains application settings or Feature settings
|
219
254
|
if response_data[:settings]
|
@@ -225,17 +260,23 @@ module Contrast
|
|
225
260
|
logger.trace('Agent: Received updated application settings', raw: response_data, processed: app_settings)
|
226
261
|
app_settings
|
227
262
|
else
|
228
|
-
# the response contains FeatureSettings
|
263
|
+
# the response contains FeatureSettings. The ng endpoint data feature
|
229
264
|
response = Contrast::Agent::Reporting::Response.build_server_response
|
230
265
|
response.success = success
|
231
266
|
response.messages = messages
|
232
|
-
server_features =
|
233
|
-
|
267
|
+
server_features = if event.cs__is_a?(Contrast::Agent::Reporting::ServerSettings)
|
268
|
+
# do the new extraction.
|
269
|
+
build_server_settings(response_data, response)
|
270
|
+
else
|
271
|
+
build_feature_settings(response_data, response)
|
272
|
+
end
|
273
|
+
logger.trace('Agent: Received updated feature settings', raw: response_data, processed: server_features)
|
234
274
|
server_features
|
235
275
|
end
|
236
|
-
response
|
237
276
|
end
|
238
277
|
|
278
|
+
# This method is used with the ng endpoint.
|
279
|
+
#
|
239
280
|
# @param response_data [Hash]
|
240
281
|
# @return res [Contrast::Agent::Reporting::Response]
|
241
282
|
def build_application_settings response_data, response
|
@@ -247,11 +288,13 @@ module Contrast
|
|
247
288
|
response
|
248
289
|
end
|
249
290
|
|
291
|
+
# This method is used with the ng startup endpoint.
|
292
|
+
#
|
250
293
|
# @param response_data [Hash]
|
251
294
|
# @return res [Contrast::Agent::Reporting::Response]
|
252
295
|
def build_feature_settings response_data, response
|
253
296
|
extract_reactions(response_data, response)
|
254
|
-
|
297
|
+
extract_assess_settings(response_data, response)
|
255
298
|
extract_protect_server_features(response_data, response)
|
256
299
|
extract_protect_lists(response_data, response)
|
257
300
|
extract_log_settings(response_data, response)
|
@@ -259,15 +302,33 @@ module Contrast
|
|
259
302
|
response
|
260
303
|
end
|
261
304
|
|
305
|
+
# This method is used with the server settings endpoint.
|
306
|
+
#
|
307
|
+
# @param response_data [Hash]
|
308
|
+
# @return res [Contrast::Agent::Reporting::Response]
|
309
|
+
def build_server_settings response_data, response
|
310
|
+
extract_loggers(response_data, response)
|
311
|
+
extract_protect_server_settings(response_data, response)
|
312
|
+
extract_assess_settings(response_data, response, ng_: false)
|
313
|
+
response.server_features.telemetry = response_data[:telemetry][:enable]
|
314
|
+
response
|
315
|
+
end
|
316
|
+
|
262
317
|
# This method with check the success and messages field of the response.
|
263
318
|
# If the success is false, then it will return nil and log the error.
|
264
319
|
#
|
265
320
|
# @param response_data [Hash]
|
266
321
|
# @return [Array, nil] Returns the success status or nil if request
|
267
322
|
# was not processed by TS.
|
268
|
-
def extract_success response_data
|
269
|
-
|
270
|
-
|
323
|
+
def extract_success response_data, event
|
324
|
+
if event.cs__is_a?(Contrast::Agent::Reporting::ServerSettings)
|
325
|
+
# we don't those in the body but we can count on the response code.
|
326
|
+
success = @_last_response_code == '200' ? true : nil
|
327
|
+
messages = @_last_response_code == '200' ? ['success'] : nil
|
328
|
+
else
|
329
|
+
success = response_data[:success]
|
330
|
+
messages = response_data[:messages]
|
331
|
+
end
|
271
332
|
return [success, messages] if success
|
272
333
|
|
273
334
|
logger.error('Unable to connect to Contrast UI') if messages.nil?
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/worker_thread'
|
5
|
+
require 'contrast/agent/reporting/report'
|
6
|
+
|
7
|
+
module Contrast
|
8
|
+
module Agent
|
9
|
+
# The ServerSettingsWorker will send request on interval, to make sure the Agent gets the settings it
|
10
|
+
# need to operate, from TS. This Thead should be started after the AgentStartup is complete.
|
11
|
+
class ServerSettingsWorker < WorkerThread
|
12
|
+
RESEND_INTERVAL_MS = 60_000.cs__freeze
|
13
|
+
|
14
|
+
def start_thread!
|
15
|
+
return if running?
|
16
|
+
|
17
|
+
@_thread = Contrast::Agent::Thread.new do
|
18
|
+
logger.info('Starting Server Settings Worker thread.', sending_interval: server_settings_resend_ms)
|
19
|
+
loop do
|
20
|
+
logger.info('Fetching Settings', sending_interval: server_settings_resend_ms)
|
21
|
+
Contrast::Agent.reporter&.send_event(settings_message)
|
22
|
+
sleep(server_settings_resend_ms / 1000)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Polling messages for this thread. Including Server settings:
|
30
|
+
#
|
31
|
+
# @return [Contrast::Agent::Reporting::ReportingEvent]
|
32
|
+
def settings_message
|
33
|
+
@_settings_message ||= Contrast::Agent::Reporting::ServerSettings.new
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get the value from settings or use the default one.
|
37
|
+
#
|
38
|
+
# @return resend_ms [Integer] time to resend the message
|
39
|
+
def server_settings_resend_ms
|
40
|
+
@_server_settings_resend_ms ||= Contrast::AGENT.polling.server_settings_ms&.to_i || RESEND_INTERVAL_MS
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -15,6 +15,7 @@ module Contrast
|
|
15
15
|
# Application level settings for the Assess featureset.
|
16
16
|
# Used for the FeatureSet TS response
|
17
17
|
class AssessServerFeature
|
18
|
+
REPORT_STACKTRACES = %w[ALL SOME NONE].cs__freeze
|
18
19
|
# Indicate if the assess feature set is enabled for this server or not.
|
19
20
|
#
|
20
21
|
# @return enabled [Boolean]
|
@@ -27,7 +28,17 @@ module Contrast
|
|
27
28
|
# @param enabled [Boolean]
|
28
29
|
# @return enabled [Boolean]
|
29
30
|
def enabled= enabled
|
30
|
-
@_enabled = enabled
|
31
|
+
@_enabled = enabled
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] ALL, SOME, NONE
|
35
|
+
def report_stacktraces
|
36
|
+
@_report_stacktraces
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String] ALL, SOME, NONE
|
40
|
+
def report_stacktraces= level
|
41
|
+
@_report_stacktraces = level if REPORT_STACKTRACES.include?(level)
|
31
42
|
end
|
32
43
|
|
33
44
|
# Used to control the sampling feature in the agent.
|
@@ -91,9 +102,10 @@ module Contrast
|
|
91
102
|
{
|
92
103
|
enabled: enabled?,
|
93
104
|
sampling: sampling.to_controlled_hash,
|
105
|
+
report_stacktraces: report_stacktraces, # used with ServerSettings only
|
94
106
|
sanitizers: sanitizers.map(&:to_controlled_hash),
|
95
107
|
validators: validators.map(&:to_controlled_hash)
|
96
|
-
}
|
108
|
+
}.compact
|
97
109
|
end
|
98
110
|
end
|
99
111
|
end
|
@@ -12,9 +12,14 @@ module Contrast
|
|
12
12
|
ATTRIBUTES = BASE_ATTRIBUTES.dup << :denylist
|
13
13
|
ATTRIBUTES.cs__freeze
|
14
14
|
|
15
|
-
# @return
|
15
|
+
# @return [Array<String>]
|
16
16
|
attr_accessor :denylist
|
17
17
|
|
18
|
+
def initialize
|
19
|
+
super
|
20
|
+
@denylist = []
|
21
|
+
end
|
22
|
+
|
18
23
|
def to_controlled_hash
|
19
24
|
hash = super
|
20
25
|
hash[:denylist] = denylist
|
@@ -18,6 +18,24 @@ module Contrast
|
|
18
18
|
# @return protect_rules [Array<String>]
|
19
19
|
attr_accessor :protect_rules
|
20
20
|
|
21
|
+
def initialize
|
22
|
+
@modes = []
|
23
|
+
@assess_rules = []
|
24
|
+
@protect_rules = []
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Boolean] does this exclusion apply to Assess or not
|
28
|
+
def assess
|
29
|
+
@_assess = modes&.include?('assess') if @_assess.nil?
|
30
|
+
@_assess
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Boolean] does this exclusion apply to Protect or not
|
34
|
+
def protect
|
35
|
+
@_protect = modes&.include?('defend') if @_protect.nil?
|
36
|
+
@_protect
|
37
|
+
end
|
38
|
+
|
21
39
|
def to_controlled_hash
|
22
40
|
{
|
23
41
|
name: name, # rubocop:disable Security/Module/Name
|