contrast-agent 6.1.1 → 6.3.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_basic_object/cs__assess_basic_object.c +7 -5
- data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
- data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
- data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
- data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
- data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
- data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
- data/ext/cs__common/cs__common.c +5 -4
- data/ext/cs__contrast_patch/cs__contrast_patch.c +3 -10
- data/lib/contrast/agent/assess/events/source_event.rb +16 -12
- data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
- data/lib/contrast/agent/assess/policy/propagation_method.rb +3 -39
- data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
- data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +2 -47
- data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
- data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
- data/lib/contrast/agent/assess/property/evented.rb +4 -18
- data/lib/contrast/agent/assess/tag.rb +19 -0
- data/lib/contrast/agent/at_exit_hook.rb +9 -8
- data/lib/contrast/agent/inventory/database_config.rb +18 -7
- data/lib/contrast/agent/inventory/dependency_analysis.rb +3 -2
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +13 -9
- data/lib/contrast/agent/middleware.rb +4 -0
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
- data/lib/contrast/agent/patching/policy/policy.rb +5 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
- data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
- data/lib/contrast/agent/protect/rule/base.rb +1 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
- data/lib/contrast/agent/protect/rule/xss.rb +4 -0
- data/lib/contrast/agent/reporting/reporter.rb +33 -17
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +21 -15
- data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +3 -18
- data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
- data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +83 -16
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +9 -3
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +18 -20
- data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -24
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +13 -6
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -4
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +10 -4
- data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +9 -0
- data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +2 -6
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -32
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -4
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
- data/lib/contrast/agent/reporting/reporting_utilities/response.rb +60 -2
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +32 -10
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +58 -26
- data/lib/contrast/agent/reporting/settings/application_settings.rb +8 -23
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +27 -33
- data/lib/contrast/agent/reporting/settings/bot_blocker.rb +68 -0
- data/lib/contrast/agent/reporting/settings/code_exclusion.rb +27 -0
- data/lib/contrast/agent/reporting/settings/exclusion_base.rb +33 -0
- data/lib/contrast/agent/reporting/settings/exclusions.rb +39 -57
- data/lib/contrast/agent/reporting/settings/helpers.rb +56 -0
- data/lib/contrast/agent/reporting/settings/input_exclusion.rb +37 -0
- data/lib/contrast/agent/reporting/settings/ip_filter.rb +35 -0
- data/lib/contrast/agent/reporting/settings/keyword.rb +74 -0
- data/lib/contrast/agent/reporting/settings/log_enhancer.rb +65 -0
- data/lib/contrast/agent/reporting/settings/protect.rb +4 -2
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +62 -115
- data/lib/contrast/agent/reporting/settings/reaction.rb +11 -2
- data/lib/contrast/agent/reporting/settings/rule_definition.rb +63 -0
- data/lib/contrast/agent/reporting/settings/sampling.rb +10 -0
- data/lib/contrast/agent/reporting/settings/sanitizer.rb +38 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +9 -1
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +7 -0
- data/lib/contrast/agent/reporting/settings/server_features.rb +8 -0
- data/lib/contrast/agent/reporting/settings/syslog.rb +176 -0
- data/lib/contrast/agent/reporting/settings/url_exclusion.rb +42 -0
- data/lib/contrast/agent/reporting/settings/validator.rb +17 -0
- data/lib/contrast/agent/request.rb +5 -7
- data/lib/contrast/agent/request_context.rb +8 -13
- data/lib/contrast/agent/request_context_extend.rb +8 -9
- data/lib/contrast/agent/request_handler.rb +10 -35
- data/lib/contrast/agent/rule_set.rb +4 -0
- data/lib/contrast/agent/service_heartbeat.rb +1 -1
- data/lib/contrast/agent/static_analysis.rb +6 -15
- data/lib/contrast/agent/telemetry/base.rb +35 -35
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
- data/lib/contrast/agent/thread_watcher.rb +2 -6
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +1 -3
- data/lib/contrast/api/communication/socket.rb +1 -0
- data/lib/contrast/api/decorators/message.rb +0 -6
- data/lib/contrast/api/decorators.rb +0 -3
- data/lib/contrast/components/assess.rb +0 -6
- data/lib/contrast/components/config.rb +18 -2
- data/lib/contrast/config/base_configuration.rb +0 -13
- data/lib/contrast/config/root_configuration.rb +1 -0
- data/lib/contrast/config/ruby_configuration.rb +2 -9
- data/lib/contrast/configuration.rb +0 -2
- data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
- data/lib/contrast/extension/assess/hash.rb +3 -2
- data/lib/contrast/extension/assess/kernel.rb +22 -0
- data/lib/contrast/extension/assess/marshal.rb +16 -0
- data/lib/contrast/extension/assess/string.rb +21 -20
- data/lib/contrast/framework/base_support.rb +13 -4
- data/lib/contrast/framework/grape/support.rb +6 -6
- data/lib/contrast/framework/manager.rb +7 -23
- data/lib/contrast/framework/manager_extend.rb +1 -1
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -15
- data/lib/contrast/framework/rails/support.rb +9 -2
- data/lib/contrast/framework/sinatra/support.rb +3 -2
- data/lib/contrast/logger/aliased_logging.rb +33 -26
- data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
- data/lib/contrast/utils/lru_cache.rb +3 -0
- data/lib/contrast/utils/middleware_utils.rb +2 -0
- data/lib/contrast/utils/response_utils.rb +14 -1
- data/lib/contrast/utils/telemetry.rb +9 -0
- data/lib/contrast/utils/telemetry_client.rb +7 -7
- data/lib/contrast/utils/telemetry_hash.rb +36 -12
- data/lib/contrast/utils/telemetry_identifier.rb +8 -0
- data/lib/contrast/utils/thread_tracker.rb +26 -9
- data/lib/contrast/utils/timer.rb +6 -1
- data/lib/contrast.rb +1 -3
- data/resources/assess/policy.json +2 -11
- data/ruby-agent.gemspec +1 -1
- metadata +36 -22
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
- data/lib/contrast/api/decorators/application_update.rb +0 -52
- data/lib/contrast/api/decorators/library.rb +0 -56
- data/lib/contrast/api/decorators/library_usage_update.rb +0 -31
- data/lib/contrast/framework/platform_version.rb +0 -22
@@ -0,0 +1,38 @@
|
|
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
|
+
module Settings
|
8
|
+
# The sanitizers defined by the user for use by the agent on this server for this organization.
|
9
|
+
class Sanitizer
|
10
|
+
ATTRIBUTES = %i[uuid api tags rules].cs__freeze
|
11
|
+
|
12
|
+
# @return uuid [String]
|
13
|
+
attr_accessor :uuid
|
14
|
+
# @return api [String]
|
15
|
+
attr_accessor :api
|
16
|
+
# @return uuid [Array<String>]
|
17
|
+
attr_accessor :tags
|
18
|
+
# @return uuid [Array<String>]
|
19
|
+
attr_accessor :rules
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@tags = []
|
23
|
+
@rules = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_controlled_hash
|
27
|
+
{
|
28
|
+
api: api,
|
29
|
+
rules: rules,
|
30
|
+
tags: tags,
|
31
|
+
uuid: uuid
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -66,7 +66,7 @@ module Contrast
|
|
66
66
|
# @param settings_rules [Hash] Response settings under Settings/sensitive_data_masking_policy/rules
|
67
67
|
# @return rules [Array<Contrast::Agent::Reporting::Settings::SensitiveDataMaskingRule>, nil
|
68
68
|
def build_rules_form_settings settings_rules
|
69
|
-
return
|
69
|
+
return if settings_rules.nil? || settings_rules.empty?
|
70
70
|
|
71
71
|
settings_rules.each do |rule|
|
72
72
|
instance = Contrast::Agent::Reporting::Settings::SensitiveDataMaskingRule.new
|
@@ -77,6 +77,14 @@ module Contrast
|
|
77
77
|
rules
|
78
78
|
end
|
79
79
|
|
80
|
+
def to_controlled_hash
|
81
|
+
{
|
82
|
+
rules: rules.map(&:to_controlled_hash),
|
83
|
+
mask_attack_vector: mask_attack_vector?,
|
84
|
+
mask_http_body: mask_http_body?
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
80
88
|
private
|
81
89
|
|
82
90
|
# Determine if parameter is array of Rules.
|
@@ -71,6 +71,14 @@ module Contrast
|
|
71
71
|
def protect
|
72
72
|
@_protect ||= Contrast::Agent::Reporting::Settings::ProtectServerFeature.new
|
73
73
|
end
|
74
|
+
|
75
|
+
def to_controlled_hash
|
76
|
+
{
|
77
|
+
assessment: @_assess ? assess.to_controlled_hash : {},
|
78
|
+
defend: @_protect ? protect.to_controlled_hash : {},
|
79
|
+
telemetry: telemetry
|
80
|
+
}.compact
|
81
|
+
end
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -0,0 +1,176 @@
|
|
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
|
+
module Settings
|
10
|
+
# Controls for the syslogging feature in the agent
|
11
|
+
class Syslog
|
12
|
+
CONNECTION_TYPE = %w[UNENCRYPTED ENCRYPTED].cs__freeze
|
13
|
+
# Used for:
|
14
|
+
# severity_blocked, severity_blocked_perimeter, severity_exploited, severity_probed,
|
15
|
+
# severity_probed_perimeter
|
16
|
+
SEVERITIES = %w[ALERT CRITICAL ERROR WARNING NOTICE INFO DEBUG].cs__freeze
|
17
|
+
SYSLOG_METHODS = %i[
|
18
|
+
enable= ip= port= facility= protocol= connection_type= severity_exploited= severity_blocked=
|
19
|
+
severity_probed= severity_probed_suspicious= severity_blocked_perimeter= severity_probed_perimeter=
|
20
|
+
].cs__freeze
|
21
|
+
SYSLOG_RESPONSE_KEYS = %i[
|
22
|
+
syslogEnabled syslogIpAddress syslogPortNumber syslogFacilityCode syslogProtocol
|
23
|
+
syslogConnectionType syslogSeverityExploited syslogSeverityBlocked syslogSeverityProbed
|
24
|
+
syslogSeveritySuspicious syslogSeverityBlockedPerimeter syslogSeverityProbedPerimeter
|
25
|
+
].cs__freeze
|
26
|
+
|
27
|
+
# @return enable [Boolean]
|
28
|
+
attr_accessor :enable
|
29
|
+
# @return ip [Integer]
|
30
|
+
attr_accessor :ip
|
31
|
+
# @return port [Integer]
|
32
|
+
attr_accessor :port
|
33
|
+
# @return facility [Integer]
|
34
|
+
attr_accessor :facility
|
35
|
+
# @return protocol [String]
|
36
|
+
attr_accessor :protocol
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
@enable = false
|
40
|
+
@ip = Contrast::Utils::ObjectShare::EMPTY_STRING
|
41
|
+
@port = 0
|
42
|
+
@facility = 0
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
46
|
+
def connection_type
|
47
|
+
@_connection_type ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set the connection type
|
51
|
+
#
|
52
|
+
# @param type [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
53
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
54
|
+
def connection_type= type
|
55
|
+
@_connection_type = type if valid_entry?(type, CONNECTION_TYPE)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return severity_blocked [String]
|
59
|
+
def severity_blocked
|
60
|
+
@_severity_blocked ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set the severity type
|
64
|
+
#
|
65
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
66
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
67
|
+
def severity_blocked= severity
|
68
|
+
@_severity_blocked = severity if valid_entry?(severity, SEVERITIES)
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return severity_blocked [String]
|
72
|
+
def severity_blocked_perimeter
|
73
|
+
@_severity_blocked_perimeter ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set the severity type
|
77
|
+
#
|
78
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
79
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
80
|
+
def severity_blocked_perimeter= severity
|
81
|
+
@_severity_blocked_perimeter = severity if valid_entry?(severity, SEVERITIES)
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return severity_blocked [String]
|
85
|
+
def severity_exploited
|
86
|
+
@_severity_exploited ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
87
|
+
end
|
88
|
+
|
89
|
+
# Set the severity type
|
90
|
+
#
|
91
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
92
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
93
|
+
def severity_exploited= severity
|
94
|
+
@_severity_exploited = severity if valid_entry?(severity, SEVERITIES)
|
95
|
+
end
|
96
|
+
|
97
|
+
# @return severity_blocked [String]
|
98
|
+
def severity_probed
|
99
|
+
@_severity_probed ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
100
|
+
end
|
101
|
+
|
102
|
+
# Set the severity type
|
103
|
+
#
|
104
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
105
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
106
|
+
def severity_probed= severity
|
107
|
+
@_severity_probed = severity if valid_entry?(severity, SEVERITIES)
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return severity_blocked [String]
|
111
|
+
def severity_probed_perimeter
|
112
|
+
@_severity_probed_perimeter ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
113
|
+
end
|
114
|
+
|
115
|
+
# Set the severity type
|
116
|
+
#
|
117
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
118
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
119
|
+
def severity_probed_perimeter= severity
|
120
|
+
@_severity_probed_perimeter = severity if valid_entry?(severity, SEVERITIES)
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return severity_blocked [String]
|
124
|
+
def severity_probed_suspicious
|
125
|
+
@_severity_probed_suspicious ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
126
|
+
end
|
127
|
+
|
128
|
+
# Set the severity type
|
129
|
+
#
|
130
|
+
# @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
|
131
|
+
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
132
|
+
def severity_probed_suspicious= severity
|
133
|
+
@_severity_probed_suspicious = severity if valid_entry?(severity, SEVERITIES)
|
134
|
+
end
|
135
|
+
|
136
|
+
# @param settings_array [Array] Settings retrieved from response
|
137
|
+
def assign_array settings_array
|
138
|
+
Contrast::Agent::Reporting::Settings::Syslog::SYSLOG_METHODS.each_with_index do |method, index|
|
139
|
+
send(method, settings_array[SYSLOG_RESPONSE_KEYS[index]])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_controlled_hash
|
144
|
+
{
|
145
|
+
syslogEnabled: enable,
|
146
|
+
syslogIpAddress: ip,
|
147
|
+
syslogPortNumber: port,
|
148
|
+
syslogFacilityCode: facility,
|
149
|
+
syslogConnectionType: connection_type,
|
150
|
+
syslogProtocol: protocol,
|
151
|
+
syslogSeverityExploited: severity_exploited,
|
152
|
+
syslogSeverityBlocked: severity_blocked,
|
153
|
+
syslogSeverityProbed: severity_probed,
|
154
|
+
syslogSeveritySuspicious: severity_probed_suspicious,
|
155
|
+
syslogSeverityBlockedPerimeter: severity_blocked_perimeter,
|
156
|
+
syslogSeverityProbedPerimeter: severity_probed_perimeter
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
# Gets String or Symbol value and assigns it to iv after
|
163
|
+
# validation with allowed types.
|
164
|
+
#
|
165
|
+
# @param value [String, Symbol] value to write
|
166
|
+
# @param validation_hash [Hash] to validate against
|
167
|
+
def valid_entry? value, validation_hash
|
168
|
+
return false unless value && validation_hash
|
169
|
+
|
170
|
+
validation_hash.include?(value)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,42 @@
|
|
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/settings/exclusion_base'
|
5
|
+
require 'contrast/utils/object_share'
|
6
|
+
|
7
|
+
module Contrast
|
8
|
+
module Agent
|
9
|
+
module Reporting
|
10
|
+
module Settings
|
11
|
+
# UrlExclusions class
|
12
|
+
class UrlExclusion < ExclusionBase
|
13
|
+
ATTRIBUTES = BASE_ATTRIBUTES.dup << :urls
|
14
|
+
ATTRIBUTES << :match_strategy
|
15
|
+
ATTRIBUTES.cs__freeze
|
16
|
+
STRATEGIES = %w[ALL ONLY].cs__freeze
|
17
|
+
|
18
|
+
# @return urls [Array<String>]
|
19
|
+
attr_accessor :urls
|
20
|
+
|
21
|
+
# @return match_strategy [String] The type of the input
|
22
|
+
def match_strategy
|
23
|
+
@_match_strategy ||= Contrast::Utils::ObjectShare::EMPTY_STRING
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param new_strategy [String] Set new input type.
|
27
|
+
# @return type [String] The type of the input.
|
28
|
+
def match_strategy= new_strategy
|
29
|
+
@_match_strategy = new_strategy if STRATEGIES.include?(new_strategy)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_controlled_hash
|
33
|
+
hash = super
|
34
|
+
hash[:urls] = urls
|
35
|
+
hash[:matchStrategy] = match_strategy
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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/settings/sanitizer'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Reporting
|
9
|
+
module Settings
|
10
|
+
# The validators defined by the user for use by the agent on this server for this organization.
|
11
|
+
class Validator < Sanitizer
|
12
|
+
# This uses the same fields as Sanitizer.
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -17,12 +17,6 @@ module Contrast
|
|
17
17
|
# provides access to the original Rack::Request object as well as extracts
|
18
18
|
# data in a format that the Agent expects, caching those transformations in
|
19
19
|
# order to avoid repeatedly creating Strings & thrashing GC.
|
20
|
-
#
|
21
|
-
# @attr_reader rack_request [Rack::Request] The passed to the Agent RackRequest to be wrapped.
|
22
|
-
# @attr_accessor route [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
|
23
|
-
# @attr_accessor observed_route [Contrast::Api::Dtm::ObservedRoute] the route, used for coverage of this request
|
24
|
-
# @attr_accessor new_observed_route [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of
|
25
|
-
# this request
|
26
20
|
class Request
|
27
21
|
include Contrast::Utils::RequestUtils
|
28
22
|
include Contrast::Components::Logger::InstanceMethods
|
@@ -37,8 +31,12 @@ module Contrast
|
|
37
31
|
STATIC_SUFFIXES = /\.(?:js|css|jpeg|jpg|gif|png|ico|woff|svg|pdf|eot|ttf|jar)$/i.cs__freeze
|
38
32
|
MEDIA_TYPE_MARKERS = %w[image/ text/css text/javascript].cs__freeze
|
39
33
|
|
34
|
+
# @return [Rack::Request] The passed to the Agent RackRequest to be wrapped.
|
40
35
|
attr_reader :rack_request
|
41
|
-
|
36
|
+
# @return [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
|
37
|
+
attr_accessor :route
|
38
|
+
# @return [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of this request
|
39
|
+
attr_accessor :observed_route
|
42
40
|
|
43
41
|
# Delegate calls to the following methods to the attribute @rack_request
|
44
42
|
def_delegators :@rack_request, :base_url, :cookies, :env, :ip, :media_type, :path, :port, :query_string,
|
@@ -30,8 +30,6 @@ module Contrast
|
|
30
30
|
# @return [Hash] context used to log the request
|
31
31
|
attr_reader :logging_hash
|
32
32
|
# @return [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of this request
|
33
|
-
attr_reader :new_observed_route
|
34
|
-
# @return [Contrast::Api::Dtm::ObservedRoute] the route, used for coverage, of this request
|
35
33
|
attr_reader :observed_route
|
36
34
|
# @return [Contrast::Agent::Request] our wrapper around the Rack::Request for this context
|
37
35
|
attr_reader :request
|
@@ -40,8 +38,6 @@ module Contrast
|
|
40
38
|
attr_reader :response
|
41
39
|
# @return [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
|
42
40
|
attr_reader :route
|
43
|
-
# @return [Contrast::Api::Dtm::ServerActivity] the server activity found in this request
|
44
|
-
attr_reader :server_activity
|
45
41
|
# @return [Contrast::Api::Settings::InputAnalysis] the protect input analysis of sources on this request
|
46
42
|
attr_reader :speedracer_input_analysis
|
47
43
|
# @return [Contrast::Utils::Timer] when the context was created
|
@@ -59,8 +55,6 @@ module Contrast
|
|
59
55
|
@activity = Contrast::Api::Dtm::Activity.new
|
60
56
|
@activity.http_request = request.dtm
|
61
57
|
|
62
|
-
@server_activity = Contrast::Api::Dtm::ServerActivity.new
|
63
|
-
|
64
58
|
# build analyzer
|
65
59
|
@do_not_track = false
|
66
60
|
@speedracer_input_analysis = EMPTY_INPUT_ANALYSIS_PB
|
@@ -124,20 +118,21 @@ module Contrast
|
|
124
118
|
|
125
119
|
def reset_activity
|
126
120
|
@activity = Contrast::Api::Dtm::Activity.new(http_request: request.dtm)
|
127
|
-
@
|
128
|
-
@observed_route = Contrast::Api::Dtm::ObservedRoute.new # TODO: RUBY-1438 -- remove
|
129
|
-
@new_observed_route = Contrast::Agent::Reporting::ObservedRoute.new
|
121
|
+
@observed_route = Contrast::Agent::Reporting::ObservedRoute.new
|
130
122
|
end
|
131
123
|
|
132
124
|
private
|
133
125
|
|
134
126
|
def handle_routes
|
135
|
-
@observed_route = Contrast::
|
136
|
-
|
127
|
+
@observed_route = Contrast::Agent::Reporting::ObservedRoute.new
|
128
|
+
# TODO: RUBY-1705 when we no longer need the DTM style, delete this method and use the get_route_information
|
129
|
+
# instead.
|
137
130
|
route_dtm = Contrast::Agent.framework_manager.get_route_dtm(@request)
|
138
|
-
new_route_coverage_dtm = Contrast::Agent.framework_manager.get_route_information(@request)
|
131
|
+
# new_route_coverage_dtm = Contrast::Agent.framework_manager.get_route_information(@request)
|
132
|
+
# TODO: RUBY-1705 -- delete append_route_coverage
|
139
133
|
append_route_coverage(route_dtm)
|
140
|
-
|
134
|
+
# TODO: RUBY-1705 -- change to take [Contrast::Agent::Reporting::ObservedRoute]
|
135
|
+
append_to_observed_route(route_dtm)
|
141
136
|
end
|
142
137
|
end
|
143
138
|
end
|
@@ -38,23 +38,20 @@ module Contrast
|
|
38
38
|
@activity.routes << route
|
39
39
|
|
40
40
|
# For TS routes
|
41
|
-
@observed_route.signature = route.route
|
42
|
-
@observed_route.verb = route.verb
|
43
|
-
@observed_route.url = route.url if route.url
|
44
41
|
@request.route = route
|
45
|
-
@request.observed_route = @observed_route
|
46
42
|
end
|
47
43
|
|
48
44
|
# Convert the discovered route for this request to appropriate forms and disseminate it to those locations
|
49
45
|
# where it is necessary for our route coverage and finding vulnerability discovery features to function.
|
50
46
|
#
|
51
|
-
|
47
|
+
# @param route [Contrast::Api::Dtm::RouteCoverage]
|
48
|
+
def append_to_observed_route route
|
52
49
|
return unless route
|
53
50
|
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@
|
57
|
-
@request.
|
51
|
+
@observed_route.signature = route.route
|
52
|
+
@observed_route.verb = route.verb
|
53
|
+
@observed_route.url = route.url if route.url
|
54
|
+
@request.observed_route = @observed_route
|
58
55
|
end
|
59
56
|
|
60
57
|
# Collect the results for the given rule with the given action
|
@@ -71,6 +68,7 @@ module Contrast
|
|
71
68
|
end
|
72
69
|
end
|
73
70
|
|
71
|
+
# @raise [Contrast::SecurityException]
|
74
72
|
def service_extract_request
|
75
73
|
return false unless ::Contrast::AGENT.enabled?
|
76
74
|
return false unless ::Contrast::PROTECT.enabled?
|
@@ -105,6 +103,7 @@ module Contrast
|
|
105
103
|
# Normally these should be generated on Speedracer for any attacks detected during prefilter.
|
106
104
|
#
|
107
105
|
# @param agent_settings [Contrast::Api::Settings::AgentSettings]
|
106
|
+
# @raise[Contrast::SecurityException]
|
108
107
|
def handle_protect_state agent_settings
|
109
108
|
return unless agent_settings&.protect_state
|
110
109
|
|
@@ -22,52 +22,27 @@ module Contrast
|
|
22
22
|
@ruleset = ::Contrast::AGENT.ruleset
|
23
23
|
end
|
24
24
|
|
25
|
-
# Send Activities messages to TS [Contrast::
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# Contrast::Api::Dtm::ObservedRoute]
|
29
|
-
# If bypass is enabled use the reporting service if not than the messages are
|
30
|
-
# send with speedracer
|
31
|
-
# TODO: RUBY-1355
|
32
|
-
# TODO: RUBY-1358
|
33
|
-
# TODO: RUBY-1438 -- remove
|
25
|
+
# Send Activities messages to TS [Contrast::Api::Dtm::Activity]
|
26
|
+
# TODO: RUBY-1704
|
27
|
+
# TODO: RUBY-1438
|
34
28
|
def send_activity_messages
|
35
|
-
|
36
|
-
unless Contrast::Agent::Reporter.enabled?
|
37
|
-
Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.generate_library_usage(context.activity)
|
38
|
-
events << context.server_activity
|
39
|
-
events << context.observed_route
|
40
|
-
end
|
41
|
-
events.each do |message|
|
42
|
-
Contrast::Agent.messaging_queue&.send_event_eventually(message)
|
43
|
-
end
|
29
|
+
Contrast::Agent.messaging_queue&.send_event_eventually(context.activity)
|
44
30
|
end
|
45
31
|
|
46
32
|
# reports events[Contrast::Agent::Reporting::ReporterEvent] to TS
|
47
33
|
# This method is used to send our JSON messages directly to TeamServer at the end of each request. As we move
|
48
34
|
# more endpoints over, this method will take the messages originally sent by #send_actiivty_messages. At the end,
|
49
35
|
# that method should be removed.
|
50
|
-
def report_activity
|
51
|
-
return unless Contrast::Agent
|
36
|
+
def report_activity
|
37
|
+
return unless (reporter = Contrast::Agent.reporter)
|
52
38
|
|
53
|
-
reporter
|
54
|
-
return unless
|
39
|
+
reporter.send_event(context.observed_route)
|
40
|
+
return unless Contrast::Agent::Reporter.enabled?
|
55
41
|
|
56
42
|
# Mask Sensitive Data
|
57
43
|
Contrast::Agent::Reporting::Masker.mask(context.activity)
|
58
|
-
|
59
|
-
|
60
|
-
[
|
61
|
-
context.new_observed_route,
|
62
|
-
Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.server_activity),
|
63
|
-
Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity.library_usages),
|
64
|
-
Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity)
|
65
|
-
].each do |event|
|
66
|
-
reporter.send_event(event)
|
67
|
-
rescue StandardError => e
|
68
|
-
logger.warn('Unable to send Event Activity', e)
|
69
|
-
end
|
70
|
-
context.activity.library_usages.clear # TODO: RUBY-1355 remove when no longer using activity
|
44
|
+
event = Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity)
|
45
|
+
reporter.send_event(event)
|
71
46
|
end
|
72
47
|
|
73
48
|
# If the response is streaming, we should only perform filtering on our stream safe rules
|
@@ -14,6 +14,8 @@ module Contrast
|
|
14
14
|
# The main action here is snapshotting the request as provided to the application from the
|
15
15
|
# user before any application code has acted upon it. Additionally, this is where Protect will
|
16
16
|
# terminate requests on attack detection if set to block at perimeter
|
17
|
+
#
|
18
|
+
# @raise [Contrast::SecurityException] raises error if security exception is thrown in prefilter
|
17
19
|
def prefilter
|
18
20
|
context = Contrast::Agent::REQUEST_TRACKER.current
|
19
21
|
return unless context&.analyze_request?
|
@@ -30,6 +32,8 @@ module Contrast
|
|
30
32
|
|
31
33
|
# The filtering that needs occur after the application has acted on the request and the response
|
32
34
|
# has been created. The main actions here are analyzing the response for unsafe state or actions.
|
35
|
+
#
|
36
|
+
# @raise [Contrast::SecurityException] raises error if security exception is thrown in postfilter
|
33
37
|
def postfilter
|
34
38
|
context = Contrast::Agent::REQUEST_TRACKER.current
|
35
39
|
return unless context&.analyze_response?
|
@@ -22,7 +22,7 @@ module Contrast
|
|
22
22
|
@_thread = Contrast::Agent::Thread.new do
|
23
23
|
logger.info('Starting heartbeat thread.')
|
24
24
|
loop do
|
25
|
-
Contrast::Agent.messaging_queue
|
25
|
+
Contrast::Agent.messaging_queue&.send_event_eventually(poll_message)
|
26
26
|
sleep(REFRESH_INTERVAL_SEC)
|
27
27
|
end
|
28
28
|
end
|
@@ -4,7 +4,6 @@
|
|
4
4
|
require 'contrast/components/logger'
|
5
5
|
require 'contrast/components/scope'
|
6
6
|
require 'contrast/agent/reporting/reporting_events/application_update'
|
7
|
-
require 'contrast/api/decorators/application_update'
|
8
7
|
|
9
8
|
module Contrast
|
10
9
|
module Agent
|
@@ -24,23 +23,15 @@ module Contrast
|
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
# TODO: RUBY-1356
|
28
26
|
def send_inventory_message
|
29
27
|
return unless ::Contrast::INVENTORY.enabled?
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
Contrast::Agent::Inventory::
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Contrast::Agent.reporter.send_event(report)
|
38
|
-
|
39
|
-
# This is being reported separately because we extract the data from the same message
|
40
|
-
inventory_report = Contrast::Agent::Reporting::ApplicationInventory.convert(app_update_msg)
|
41
|
-
Contrast::Agent.reporter.send_event(inventory_report)
|
42
|
-
else
|
43
|
-
Contrast::Agent.messaging_queue.send_event_eventually(app_update_msg, force: true)
|
29
|
+
report = Contrast::Agent::Reporting::ApplicationUpdate.new
|
30
|
+
# This convert here is left as it'll be easier to be replaced when the Library is being changed
|
31
|
+
report.libraries = Contrast::Agent::Inventory::DependencyAnalysis.instance.library_pb_list
|
32
|
+
Contrast::Agent::Inventory::DatabaseConfig.append_db_config(report)
|
33
|
+
[report, Contrast::Agent::Reporting::ApplicationInventory.new].each do |e|
|
34
|
+
Contrast::Agent.reporter.send_event(e)
|
44
35
|
end
|
45
36
|
end
|
46
37
|
|