contrast-agent 5.1.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/cs__assess_array/cs__assess_array.c +7 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +19 -5
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
- data/ext/cs__assess_hash/cs__assess_hash.c +3 -4
- data/ext/cs__assess_kernel/cs__assess_kernel.c +7 -5
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +26 -12
- data/ext/cs__assess_module/cs__assess_module.c +7 -7
- data/ext/cs__assess_string/cs__assess_string.c +13 -1
- data/ext/cs__common/cs__common.c +16 -11
- data/ext/cs__common/cs__common.h +1 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.c +100 -64
- data/ext/cs__contrast_patch/cs__contrast_patch.h +2 -0
- data/ext/cs__os_information/cs__os_information.c +13 -10
- data/ext/cs__scope/cs__scope.c +796 -0
- data/ext/cs__scope/cs__scope.h +88 -0
- data/ext/cs__scope/extconf.rb +5 -0
- data/lib/contrast/agent/assess/contrast_event.rb +20 -13
- data/lib/contrast/agent/assess/contrast_object.rb +4 -1
- data/lib/contrast/agent/assess/finalizers/hash.rb +2 -0
- data/lib/contrast/agent/assess/policy/policy_node.rb +50 -27
- data/lib/contrast/agent/assess/policy/policy_node_utils.rb +51 -0
- data/lib/contrast/agent/assess/policy/preshift.rb +8 -2
- data/lib/contrast/agent/assess/policy/propagation_method.rb +47 -13
- data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -5
- data/lib/contrast/agent/assess/policy/propagator/buffer.rb +118 -0
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +19 -4
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -0
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +18 -2
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +17 -3
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/substitution_utils.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +7 -7
- data/lib/contrast/agent/assess/policy/trigger_method.rb +6 -1
- data/lib/contrast/agent/assess/property/tagged.rb +1 -1
- data/lib/contrast/agent/assess/rule/response/{autocomplete_rule.rb → auto_complete_rule.rb} +4 -3
- data/lib/contrast/agent/assess/rule/response/base_rule.rb +12 -79
- data/lib/contrast/agent/assess/rule/response/body_rule.rb +109 -0
- data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +157 -0
- data/lib/contrast/agent/assess/rule/response/click_jacking_header_rule.rb +26 -0
- data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +14 -15
- data/lib/contrast/agent/assess/rule/response/csp_header_missing_rule.rb +5 -25
- data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +29 -0
- data/lib/contrast/agent/assess/rule/response/header_rule.rb +70 -0
- data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +12 -36
- data/lib/contrast/agent/assess/rule/response/parameters_pollution_rule.rb +2 -1
- data/lib/contrast/agent/assess/rule/response/x_content_type_header_rule.rb +26 -0
- data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +35 -0
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +0 -7
- data/lib/contrast/agent/deadzone/policy/policy.rb +0 -6
- data/lib/contrast/agent/exclusion_matcher.rb +3 -3
- data/lib/contrast/agent/middleware.rb +4 -1
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +1 -3
- data/lib/contrast/agent/patching/policy/patch.rb +2 -6
- data/lib/contrast/agent/patching/policy/patcher.rb +4 -4
- data/lib/contrast/agent/patching/policy/policy_node.rb +15 -2
- data/lib/contrast/agent/protect/exploitable_collection.rb +38 -0
- data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +147 -0
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +2 -1
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +2 -2
- data/lib/contrast/agent/protect/rule/base.rb +61 -2
- data/lib/contrast/agent/protect/rule/base_service.rb +12 -1
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +15 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +83 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_worth_watching.rb +64 -0
- data/lib/contrast/agent/protect/rule/deserialization.rb +6 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering/http_method_tampering_input_classification.rb +96 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +13 -1
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +231 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +28 -0
- data/lib/contrast/agent/protect/rule/path_traversal.rb +1 -0
- data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +88 -0
- data/lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb +118 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +33 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +82 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_matcher.rb +45 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +42 -0
- data/lib/contrast/agent/protect/rule/xxe.rb +4 -0
- data/lib/contrast/agent/reporting/attack_result/attack_result.rb +63 -0
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +52 -0
- data/lib/contrast/agent/reporting/attack_result/response_type.rb +29 -0
- data/lib/contrast/agent/reporting/attack_result/user_input.rb +87 -0
- data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +44 -0
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +115 -0
- data/lib/contrast/agent/reporting/input_analysis/input_type.rb +44 -0
- data/lib/contrast/agent/reporting/input_analysis/score_level.rb +21 -0
- data/lib/contrast/agent/reporting/masker/masker.rb +246 -0
- data/lib/contrast/agent/reporting/masker/masker_utils.rb +58 -0
- data/lib/contrast/agent/reporting/report.rb +3 -0
- data/lib/contrast/agent/reporting/reporter.rb +31 -12
- data/lib/contrast/agent/reporting/reporting_events/agent_startup.rb +30 -0
- data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +7 -3
- data/lib/contrast/agent/reporting/reporting_events/application_startup.rb +40 -0
- data/lib/contrast/agent/reporting/reporting_events/application_startup_instrumentation.rb +27 -0
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +69 -36
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +88 -59
- data/lib/contrast/agent/reporting/reporting_events/{finding_object.rb → finding_event_object.rb} +24 -20
- data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +39 -0
- data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +40 -0
- data/lib/contrast/agent/reporting/reporting_events/{finding_signature.rb → finding_event_signature.rb} +29 -24
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +12 -8
- data/lib/contrast/agent/reporting/reporting_events/{finding_stack.rb → finding_event_stack.rb} +23 -19
- data/lib/contrast/agent/reporting/reporting_events/{finding_taint_range.rb → finding_event_taint_range.rb} +17 -15
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +26 -53
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +5 -5
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +9 -9
- data/lib/contrast/agent/reporting/reporting_events/poll.rb +29 -0
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +2 -1
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +6 -4
- data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +8 -6
- data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +1 -0
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +0 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +17 -5
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +54 -45
- data/lib/contrast/agent/reporting/reporting_utilities/reporting_storage.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +97 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +69 -7
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +63 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +123 -85
- data/lib/contrast/agent/reporting/settings/application_settings.rb +9 -0
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +5 -33
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +1 -1
- data/lib/contrast/agent/reporting/settings/sampling.rb +36 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +110 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +58 -0
- data/lib/contrast/agent/request_context.rb +7 -2
- data/lib/contrast/agent/request_context_extend.rb +85 -21
- data/lib/contrast/agent/request_handler.rb +4 -0
- data/lib/contrast/agent/scope.rb +102 -107
- data/lib/contrast/agent/service_heartbeat.rb +45 -2
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +51 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +36 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +97 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +65 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +47 -0
- data/lib/contrast/agent/{metric_telemetry_event.rb → telemetry/events/metric_telemetry_event.rb} +1 -1
- data/lib/contrast/agent/{startup_metrics_telemetry_event.rb → telemetry/events/startup_metrics_telemetry_event.rb} +3 -3
- data/lib/contrast/agent/{telemetry_event.rb → telemetry/events/telemetry_event.rb} +1 -1
- data/lib/contrast/agent/{telemetry.rb → telemetry/telemetry.rb} +32 -19
- data/lib/contrast/agent/thread_watcher.rb +1 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +3 -0
- data/lib/contrast/api/communication/speedracer.rb +1 -1
- data/lib/contrast/api/decorators/address.rb +1 -1
- data/lib/contrast/api/decorators/bot_blocker.rb +37 -0
- data/lib/contrast/api/decorators/ip_denylist.rb +37 -0
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +29 -0
- data/lib/contrast/api/decorators/response_type.rb +30 -0
- data/lib/contrast/api/decorators/user_input.rb +11 -1
- data/lib/contrast/api/decorators/virtual_patch.rb +34 -0
- data/lib/contrast/api/decorators.rb +1 -0
- data/lib/contrast/components/app_context.rb +0 -4
- data/lib/contrast/components/assess.rb +14 -0
- data/lib/contrast/components/logger.rb +5 -0
- data/lib/contrast/components/protect.rb +6 -4
- data/lib/contrast/components/sampling.rb +7 -11
- data/lib/contrast/components/scope.rb +98 -91
- data/lib/contrast/components/settings.rb +106 -8
- data/lib/contrast/config/agent_configuration.rb +41 -12
- data/lib/contrast/config/api_configuration.rb +37 -12
- data/lib/contrast/config/api_proxy_configuration.rb +12 -3
- data/lib/contrast/config/application_configuration.rb +38 -14
- data/lib/contrast/config/assess_configuration.rb +47 -12
- data/lib/contrast/config/assess_rules_configuration.rb +15 -3
- data/lib/contrast/config/base_configuration.rb +18 -50
- data/lib/contrast/config/certification_configuration.rb +17 -3
- data/lib/contrast/config/exception_configuration.rb +14 -3
- data/lib/contrast/config/heap_dump_configuration.rb +43 -17
- data/lib/contrast/config/inventory_configuration.rb +17 -3
- data/lib/contrast/config/logger_configuration.rb +10 -3
- data/lib/contrast/config/protect_configuration.rb +17 -7
- data/lib/contrast/config/protect_rule_configuration.rb +17 -8
- data/lib/contrast/config/protect_rules_configuration.rb +115 -17
- data/lib/contrast/config/request_audit_configuration.rb +26 -3
- data/lib/contrast/config/root_configuration.rb +52 -12
- data/lib/contrast/config/ruby_configuration.rb +60 -22
- data/lib/contrast/config/sampling_configuration.rb +19 -9
- data/lib/contrast/config/server_configuration.rb +19 -10
- data/lib/contrast/config/service_configuration.rb +27 -11
- data/lib/contrast/configuration.rb +5 -3
- data/lib/contrast/extension/assess/string.rb +20 -1
- data/lib/contrast/extension/module.rb +0 -1
- data/lib/contrast/framework/manager.rb +2 -2
- data/lib/contrast/logger/application.rb +1 -1
- data/lib/contrast/logger/cef_log.rb +151 -0
- data/lib/contrast/tasks/config.rb +90 -3
- data/lib/contrast/utils/assess/object_store.rb +36 -0
- data/lib/contrast/utils/assess/propagation_method_utils.rb +6 -0
- data/lib/contrast/utils/class_util.rb +3 -12
- data/lib/contrast/utils/hash_digest.rb +14 -6
- data/lib/contrast/utils/input_classification.rb +73 -0
- data/lib/contrast/utils/log_utils.rb +114 -0
- data/lib/contrast/utils/middleware_utils.rb +9 -9
- data/lib/contrast/utils/net_http_base.rb +13 -10
- data/lib/contrast/utils/object_share.rb +2 -1
- data/lib/contrast/utils/os.rb +0 -5
- data/lib/contrast/utils/patching/policy/patch_utils.rb +4 -9
- data/lib/contrast/utils/response_utils.rb +18 -33
- data/lib/contrast/utils/telemetry.rb +1 -1
- data/lib/contrast/utils/telemetry_client.rb +1 -1
- data/lib/contrast/utils/telemetry_identifier.rb +1 -1
- data/lib/contrast.rb +4 -3
- data/resources/assess/policy.json +98 -0
- data/resources/deadzone/policy.json +0 -86
- data/ruby-agent.gemspec +9 -8
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +103 -38
- data/lib/contrast/agent/assess/rule/response/cachecontrol_rule.rb +0 -184
- data/lib/contrast/agent/assess/rule/response/clickjacking_rule.rb +0 -66
- data/lib/contrast/agent/assess/rule/response/x_content_type_rule.rb +0 -52
- data/lib/contrast/agent/assess/rule/response/x_xss_protection_rule.rb +0 -53
- data/lib/contrast/extension/kernel.rb +0 -54
@@ -2,19 +2,61 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/protect/rule/base_service'
|
5
|
+
require 'contrast/agent/reporting/input_analysis/input_type'
|
6
|
+
require 'contrast/agent/reporting/input_analysis/score_level'
|
5
7
|
|
6
8
|
module Contrast
|
7
9
|
module Agent
|
8
10
|
module Protect
|
9
11
|
module Rule
|
10
12
|
# The Ruby implementation of the Protect Unsafe File Upload rule.
|
13
|
+
# The unsafe-file-upload rule can trigger the following results:
|
14
|
+
# BLOCKED in Blocking mode na SUSPICIOUS in Monitor mode.
|
11
15
|
class UnsafeFileUpload < Contrast::Agent::Protect::Rule::BaseService
|
16
|
+
include Contrast::Agent::Reporting::InputType
|
17
|
+
|
12
18
|
NAME = 'unsafe-file-upload'
|
13
19
|
BLOCK_MESSAGE = 'Unsafe file upload rule triggered. Request blocked.'
|
20
|
+
APPLICABLE_USER_INPUTS = [MULTIPART_NAME, MULTIPART_FIELD_NAME].cs__freeze
|
14
21
|
|
15
22
|
def rule_name
|
16
23
|
NAME
|
17
24
|
end
|
25
|
+
|
26
|
+
def block_message
|
27
|
+
BLOCK_MESSAGE
|
28
|
+
end
|
29
|
+
|
30
|
+
def prefilter context
|
31
|
+
return unless prefilter?(context)
|
32
|
+
|
33
|
+
ia_results = gather_ia_results context
|
34
|
+
|
35
|
+
ia_results.each do |ia_result|
|
36
|
+
result = build_attack_result(context)
|
37
|
+
build_attack_without_match context, ia_result, result
|
38
|
+
append_to_activity context, result
|
39
|
+
|
40
|
+
cef_logging result, :successful_attack
|
41
|
+
raise Contrast::SecurityException.new(self, BLOCK_MESSAGE) if blocked?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def prefilter? context
|
48
|
+
return false unless context&.agent_input_analysis&.results
|
49
|
+
return false unless enabled?
|
50
|
+
return false if protect_excluded_by_code?
|
51
|
+
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
def gather_ia_results context
|
56
|
+
context.agent_input_analysis.results.select do |ia_result|
|
57
|
+
ia_result.rule_id == rule_name
|
58
|
+
end
|
59
|
+
end
|
18
60
|
end
|
19
61
|
end
|
20
62
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'contrast/agent/protect/rule/base'
|
5
5
|
require 'contrast/utils/timer'
|
6
|
+
require 'contrast/components/logger'
|
6
7
|
|
7
8
|
module Contrast
|
8
9
|
module Agent
|
@@ -11,6 +12,8 @@ module Contrast
|
|
11
12
|
# Implementation of the XXE Protect Rule used to evaluate XML calls for exploit
|
12
13
|
# of unsafe external entity resolution.
|
13
14
|
class Xxe < Contrast::Agent::Protect::Rule::Base
|
15
|
+
include Contrast::Components::Logger::InstanceMethods
|
16
|
+
|
14
17
|
NAME = 'xxe'
|
15
18
|
BLOCK_MESSAGE = 'XXE rule triggered. Response blocked.'
|
16
19
|
EXTERNAL_ENTITY_PATTERN = /<!ENTITY\s+[a-zA-Z0-f]+\s+(?:SYSTEM|PUBLIC)\s+(.*?)>/.cs__freeze
|
@@ -36,6 +39,7 @@ module Contrast
|
|
36
39
|
append_to_activity(context, result)
|
37
40
|
return unless blocked?
|
38
41
|
|
42
|
+
cef_logging result, :successful_attack, xml
|
39
43
|
raise Contrast::SecurityException.new(self, BLOCK_MESSAGE)
|
40
44
|
end
|
41
45
|
|
@@ -0,0 +1,63 @@
|
|
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/utils/object_share'
|
5
|
+
require 'contrast/utils/timer'
|
6
|
+
require 'contrast/agent/reporting/attack_result/response_type'
|
7
|
+
require 'contrast/agent/reporting/attack_result/rasp_rule_sample'
|
8
|
+
|
9
|
+
module Contrast
|
10
|
+
module Agent
|
11
|
+
module Reporting
|
12
|
+
# This class will hold the new Attacks results generated by our
|
13
|
+
# protect rules.
|
14
|
+
class AttackResult
|
15
|
+
RESPONSE_TYPE = Contrast::Agent::Reporting::ResponseType
|
16
|
+
# Generated the attack result
|
17
|
+
#
|
18
|
+
# @return @_response_type [Contrast::Agent::Reporting::ResponseType]
|
19
|
+
def response
|
20
|
+
@_response ||= RESPONSE_TYPE::NO_ACTION
|
21
|
+
end
|
22
|
+
|
23
|
+
# sets the response_type
|
24
|
+
#
|
25
|
+
# @param response_type [Contrast::Agent::Reporting::Settings::InputAnalysisResult]
|
26
|
+
# @return @_response_type []
|
27
|
+
def response= response_type
|
28
|
+
@_response = response_type if RESPONSE_TYPE.to_a.include?(response_type)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return @_rule_id [String]
|
32
|
+
def rule_id
|
33
|
+
@_rule_id ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param rule_id [String]
|
37
|
+
# @return @_rule_id [String]
|
38
|
+
def rule_id= rule_id
|
39
|
+
@_rule_id = rule_id if rule_id.is_a?(String)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return @_samples [Array<Contrast::Agent::Reporting::RaspRuleSample>]
|
43
|
+
def samples
|
44
|
+
@_samples ||= []
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param samples [Array<Contrast::Agent::Reporting::RaspRuleSample>]
|
48
|
+
# @return @_samples [Array<Contrast::Agent::Reporting::RaspRuleSample>]
|
49
|
+
def samples= samples
|
50
|
+
@_samples = samples if samples.is_a?(Array)
|
51
|
+
end
|
52
|
+
|
53
|
+
def tags
|
54
|
+
@_tags ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
55
|
+
end
|
56
|
+
|
57
|
+
def tags= tags
|
58
|
+
@_tags = tags if tags.is_a?(String)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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/utils/object_share'
|
5
|
+
require 'contrast/utils/timer'
|
6
|
+
require 'contrast/agent/reporting/attack_result/user_input'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Agent
|
10
|
+
module Reporting
|
11
|
+
# This class will hold the new RaspRuleSample.
|
12
|
+
# protect rules.
|
13
|
+
class RaspRuleSample
|
14
|
+
def timestamp
|
15
|
+
@_timestamp ||= 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def timestamp= timestamp_ms
|
19
|
+
@_timestamp = timestamp_ms
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_input
|
23
|
+
@_user_input ||= Contrast::Agent::Reporting::UserInput.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def user_input= input
|
27
|
+
@_user_input = input if input.is_a?(Contrast::Agent::Reporting::UserInput)
|
28
|
+
end
|
29
|
+
|
30
|
+
def build context, ia_result
|
31
|
+
sample = self
|
32
|
+
sample.timestamp = context&.timer&.start_ms
|
33
|
+
sample.user_input = build_user_input_from_ia(ia_result)
|
34
|
+
sample.user_input.document_type = if context&.request
|
35
|
+
Contrast::Utils::StringUtils.force_utf8(context.request.document_type)
|
36
|
+
end
|
37
|
+
sample
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_user_input_from_ia ia_result
|
41
|
+
user_input = Contrast::Agent::Reporting::UserInput.new
|
42
|
+
user_input.input_type = ia_result.input_type
|
43
|
+
user_input.matcher_ids = ia_result.ids
|
44
|
+
user_input.path = ia_result.path
|
45
|
+
user_input.key = ia_result.key if ia_result.key
|
46
|
+
user_input.value = ia_result.value if ia_result.value
|
47
|
+
user_input
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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/utils/object_share'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Reporting
|
9
|
+
# This module will hold the response types used to generate
|
10
|
+
# attack result.
|
11
|
+
module ResponseType
|
12
|
+
BLOCKED = :BLOCKED.cs__freeze
|
13
|
+
MONITORED = :MONITORED.cs__freeze
|
14
|
+
PROBED = :PROBED.cs__freeze
|
15
|
+
BLOCK_AT_PERIMETER = :BLOCK_AT_PERIMETER.cs__freeze
|
16
|
+
SUSPICIOUS = :SUSPICIOUS.cs__freeze
|
17
|
+
AGGREGATED = :AGGREGATED.cs__freeze
|
18
|
+
EXPLOITED = :EXPLOITED.cs__freeze
|
19
|
+
NO_ACTION = :NO_ACTION.cs__freeze
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def to_a
|
23
|
+
[NO_ACTION, BLOCKED, MONITORED, PROBED, BLOCK_AT_PERIMETER, EXPLOITED, SUSPICIOUS, AGGREGATED]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,87 @@
|
|
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/utils/object_share'
|
5
|
+
require 'contrast/agent/reporting/input_analysis/input_type'
|
6
|
+
require 'contrast/agent/request_context'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Agent
|
10
|
+
module Reporting
|
11
|
+
# This class will hold the new Sqli detail used by RaspRuleSample
|
12
|
+
class UserInput
|
13
|
+
INPUT_TYPE = Contrast::Agent::Reporting::InputType
|
14
|
+
DOCUMENT_TYPE = { XML: :XML, JSON: :JSON, NORMAL: :NORMAL }.cs__freeze
|
15
|
+
|
16
|
+
# @return @_path [String]
|
17
|
+
def path
|
18
|
+
@_path ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param path [String]
|
22
|
+
# @return @_path [String]
|
23
|
+
def path= path
|
24
|
+
@_path = path if path.is_a?(String)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return @_key [String]
|
28
|
+
def key
|
29
|
+
@_key ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param key [String]
|
33
|
+
# @return @_key [String]
|
34
|
+
def key= key
|
35
|
+
@_key = key if key.is_a?(String)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return value [String]
|
39
|
+
def value
|
40
|
+
@_value ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param value [String]
|
44
|
+
# @return value [String]
|
45
|
+
def value= value
|
46
|
+
@_value = value if value.is_a?(String)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return @_input_type [
|
50
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
51
|
+
def input_type
|
52
|
+
@_input_type ||= INPUT_TYPE::UNDEFINED_TYPE
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param input_type [
|
56
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
57
|
+
# @return @_input_type [
|
58
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
59
|
+
def input_type= input_type
|
60
|
+
@_input_type = input_type if INPUT_TYPE.to_a.include?(input_type)
|
61
|
+
end
|
62
|
+
|
63
|
+
# type [Symbol<:XML, :JSON, :NORMAL>]
|
64
|
+
def document_type
|
65
|
+
@_document_type ||= DOCUMENT_TYPE[:NORMAL]
|
66
|
+
end
|
67
|
+
|
68
|
+
def document_type= type
|
69
|
+
@_document_type = type if DOCUMENT_TYPE.value?(type)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Matchers IDs
|
73
|
+
# @return @_ids [Array<String>]
|
74
|
+
def matcher_ids
|
75
|
+
@_matcher_ids ||= []
|
76
|
+
end
|
77
|
+
|
78
|
+
# Matchers IDs
|
79
|
+
# @param ids [Array<String>]
|
80
|
+
# @return @_ids [Array<String>]
|
81
|
+
def matcher_ids= ids
|
82
|
+
@_matcher_ids = ids if ids.is_a?(Array) && ids.any?(String)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -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/utils/object_share'
|
5
|
+
require 'contrast/agent/reporting/input_analysis/input_analysis_result'
|
6
|
+
|
7
|
+
module Contrast
|
8
|
+
module Agent
|
9
|
+
module Reporting
|
10
|
+
# This class will do ia analysis for our protect rules instead of
|
11
|
+
# using the service.
|
12
|
+
class InputAnalysis
|
13
|
+
# result from input analysis
|
14
|
+
#
|
15
|
+
# @return @_results [Array<Contrast::Agent::Reporting::Settings::InputAnalysisResult>]
|
16
|
+
def results
|
17
|
+
@_results ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
# result from input analysis
|
21
|
+
#
|
22
|
+
# @return @_results [Array<Contrast::Agent::Reporting::Settings::InputAnalysisResult>]
|
23
|
+
def results= results
|
24
|
+
@_results = results
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns our wrapper around the Rack::Request for this context
|
28
|
+
#
|
29
|
+
# @return request [Contrast::Agent::Request, nil]
|
30
|
+
def request
|
31
|
+
@_request ||= nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sets current request
|
35
|
+
#
|
36
|
+
# @param request [Contrast::Agent::Request] our wrapper around the Rack::Request for this context
|
37
|
+
# @return request [Contrast::Agent::Request, nil]
|
38
|
+
def request= request
|
39
|
+
@_request = request if request.instance_of?(Contrast::Agent::Request)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,115 @@
|
|
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/utils/object_share'
|
5
|
+
require 'contrast/agent/reporting/input_analysis/input_type'
|
6
|
+
require 'contrast/agent/reporting/input_analysis/score_level'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Agent
|
10
|
+
module Reporting
|
11
|
+
# This class will do ia analysis for our protect rules instead of
|
12
|
+
# using the service.
|
13
|
+
class InputAnalysisResult
|
14
|
+
INPUT_TYPE = Contrast::Agent::Reporting::InputType
|
15
|
+
SCORE_LEVEL = Contrast::Agent::Reporting::ScoreLevel
|
16
|
+
|
17
|
+
# @return @_rule_id [String]
|
18
|
+
def rule_id
|
19
|
+
@_rule_id ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param id [String]
|
23
|
+
# @return @_rule_id [String]
|
24
|
+
def rule_id= id
|
25
|
+
@_rule_id = id if id.is_a?(String)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return @_input_type [
|
29
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
30
|
+
def input_type
|
31
|
+
@_input_type ||= INPUT_TYPE::UNDEFINED_TYPE
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param input_type [
|
35
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
36
|
+
# @return @_input_type [
|
37
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::InputType>]
|
38
|
+
def input_type= input_type
|
39
|
+
@_input_type = input_type if INPUT_TYPE.to_a.include?(input_type)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return @_path [String]
|
43
|
+
def path
|
44
|
+
@_path ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param path [String]
|
48
|
+
# @return @_path [String]
|
49
|
+
def path= path
|
50
|
+
@_path = path if path.is_a?(String)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return @_key [String]
|
54
|
+
def key
|
55
|
+
@_key ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param key [String]
|
59
|
+
# @return @_key [String]
|
60
|
+
def key= key
|
61
|
+
@_key = key if key.is_a?(String)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return value [String]
|
65
|
+
def value
|
66
|
+
@_value ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
67
|
+
end
|
68
|
+
|
69
|
+
# @param value [String]
|
70
|
+
# @return value [String]
|
71
|
+
def value= value
|
72
|
+
@_value = value if value.is_a?(String)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Matchers IDs
|
76
|
+
# @return @_ids [Array<String>]
|
77
|
+
def ids
|
78
|
+
@_ids ||= []
|
79
|
+
end
|
80
|
+
|
81
|
+
# Matchers IDs
|
82
|
+
# @param ids [Array<String>]
|
83
|
+
# @return @_ids [Array<String>]
|
84
|
+
def ids= ids
|
85
|
+
@_ids = ids if ids.is_a?(Array) && ids.any?(String)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return @_attack_count [Integer]
|
89
|
+
def attack_count
|
90
|
+
@_attack_count ||= 0
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param attack_count
|
94
|
+
# @return @_attack_count
|
95
|
+
def attack_count= attack_count
|
96
|
+
@_attack_count = attack_count if attack_count.is_a?(Integer)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return @_score_level [
|
100
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::ScoreLevel>]
|
101
|
+
def score_level
|
102
|
+
@_score_level ||= SCORE_LEVEL::IGNORE
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param score_level [
|
106
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::ScoreLevel>]
|
107
|
+
# @return @_score_level [
|
108
|
+
# Symbol<Contrast::Agent::Reporting::Settings::InputAnalysis::InputAnalysisResult::ScoreLevel>]
|
109
|
+
def score_level= score_level
|
110
|
+
@_score_level = score_level if SCORE_LEVEL.to_a.include?(score_level)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -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
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Reporting
|
7
|
+
# input types for InputAnalysis results
|
8
|
+
module InputType
|
9
|
+
UNDEFINED_TYPE = :UNDEFINED_TYPE.cs__freeze
|
10
|
+
BODY = :BODY.cs__freeze
|
11
|
+
COOKIE_NAME = :COOKIE_NAME.cs__freeze
|
12
|
+
COOKIE_VALUE = :COOKIE_VALUE.cs__freeze
|
13
|
+
HEADER = :HEADER.cs__freeze
|
14
|
+
PARAMETER_NAME = :PARAMETER_NAME.cs__freeze
|
15
|
+
PARAMETER_VALUE = :PARAMETER_VALUE.cs__freeze
|
16
|
+
QUERYSTRING = :QUERYSTRING.cs__freeze
|
17
|
+
URI = :URI.cs__freeze
|
18
|
+
SOCKET = :SOCKET.cs__freeze
|
19
|
+
JSON_VALUE = :JSON_VALUE.cs__freeze
|
20
|
+
JSON_ARRAYED_VALUE = :JSON_ARRAYED_VALUE.cs__freeze
|
21
|
+
MULTIPART_CONTENT_TYPE = :MULTIPART_CONTENT_TYPE.cs__freeze
|
22
|
+
MULTIPART_VALUE = :MULTIPART_VALUE.cs__freeze
|
23
|
+
MULTIPART_FIELD_NAME = :MULTIPART_FIELD_NAME.cs__freeze
|
24
|
+
MULTIPART_NAME = :MULTIPART_NAME.cs__freeze
|
25
|
+
XML_VALUE = :XML_VALUE.cs__freeze
|
26
|
+
DWR_VALUE = :DWR_VALUE.cs__freeze
|
27
|
+
METHOD = :METHOD.cs__freeze
|
28
|
+
REQUEST = :REQUEST.cs__freeze
|
29
|
+
URL_PARAMETER = :URL_PARAMETER.cs__freeze
|
30
|
+
UNKNOWN = :UNKNOWN.cs__freeze
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def to_a
|
34
|
+
[
|
35
|
+
UNDEFINED_TYPE, BODY, COOKIE_NAME, COOKIE_VALUE, HEADER, PARAMETER_NAME, PARAMETER_VALUE,
|
36
|
+
QUERYSTRING, URI, SOCKET, JSON_VALUE, JSON_ARRAYED_VALUE, MULTIPART_CONTENT_TYPE, MULTIPART_VALUE,
|
37
|
+
MULTIPART_FIELD_NAME, MULTIPART_NAME, XML_VALUE, DWR_VALUE, METHOD, REQUEST, URL_PARAMETER, UNKNOWN
|
38
|
+
]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
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
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Reporting
|
7
|
+
# input types for InputAnalysis results
|
8
|
+
module ScoreLevel
|
9
|
+
IGNORE = :DONTCARE.cs__freeze
|
10
|
+
WORTHWATCHING = :WORTHWATCHING.cs__freeze
|
11
|
+
DEFINITEATTACK = :DEFINITEATTACK.cs__freeze
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def to_a
|
15
|
+
[IGNORE, WORTHWATCHING, DEFINITEATTACK]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|