contrast-agent 6.8.0 → 6.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/contrast/agent/assess/policy/trigger_method.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 +1 -1
- data/lib/contrast/agent/middleware.rb +8 -2
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +116 -0
- data/lib/contrast/agent/protect/rule/base.rb +2 -2
- data/lib/contrast/agent/protect/rule/bot_blocker.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +8 -7
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +0 -5
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +0 -5
- data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -3
- data/lib/contrast/agent/protect/rule/sqli.rb +4 -3
- data/lib/contrast/agent/protect/rule/xss.rb +1 -0
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +1 -1
- data/lib/contrast/agent/reporting/report.rb +1 -0
- data/lib/contrast/agent/reporting/reporter.rb +34 -0
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +3 -9
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +12 -7
- data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -1
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +2 -2
- 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/observed_route.rb +12 -0
- 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/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_extractor.rb +58 -4
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +4 -3
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +76 -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/helpers.rb +7 -0
- 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 +1 -0
- 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 +35 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +6 -0
- data/lib/contrast/api/communication/connection_status.rb +15 -0
- data/lib/contrast/components/agent.rb +34 -0
- data/lib/contrast/components/api.rb +23 -0
- data/lib/contrast/components/app_context.rb +23 -3
- 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 +18 -1
- 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 +48 -1
- data/lib/contrast/components/ruby_component.rb +15 -0
- data/lib/contrast/components/sampling.rb +70 -13
- data/lib/contrast/components/security_logger.rb +13 -0
- data/lib/contrast/components/settings.rb +74 -7
- 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 +1 -1
- data/lib/contrast/config/protect_rules_configuration.rb +8 -7
- data/lib/contrast/config/request_audit_configuration.rb +13 -0
- data/lib/contrast/config/server_configuration.rb +41 -2
- data/lib/contrast/configuration.rb +28 -2
- data/lib/contrast/extension/assess/erb.rb +1 -1
- 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/hash_digest.rb +2 -2
- data/lib/contrast/utils/input_classification_base.rb +1 -2
- data/lib/contrast/utils/reporting/application_activity_batch_utils.rb +81 -0
- data/lib/contrast/utils/routes_sent.rb +60 -0
- data/lib/contrast/utils/telemetry_client.rb +1 -2
- data/lib/contrast/utils/timer.rb +16 -0
- data/lib/contrast.rb +3 -1
- data/ruby-agent.gemspec +5 -1
- metadata +29 -20
- 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/reporting/reporting_events/server_activity.rb +0 -36
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
require 'contrast/utils/object_share'
|
|
5
5
|
require 'contrast/agent/reporting/settings/assess_server_feature'
|
|
6
6
|
require 'contrast/agent/reporting/settings/protect_server_feature'
|
|
7
|
+
require 'contrast/agent/reporting/settings/security_logger'
|
|
7
8
|
|
|
8
9
|
module Contrast
|
|
9
10
|
module Agent
|
|
@@ -46,6 +47,13 @@ module Contrast
|
|
|
46
47
|
@_log_file = log_file if log_file.is_a?(String)
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
# Class holding security logger settings:
|
|
51
|
+
#
|
|
52
|
+
# @return [Contrast::Agent::Reporting::Settings::SecurityLogger]
|
|
53
|
+
def security_logger
|
|
54
|
+
@_security_logger ||= Contrast::Agent::Reporting::Settings::SecurityLogger.new
|
|
55
|
+
end
|
|
56
|
+
|
|
49
57
|
# Controls for the reporting of telemetry events from the agent to TeamServer.
|
|
50
58
|
# This is NOT for the agent telemetry feature collecting metrics sent to other services.
|
|
51
59
|
#
|
|
@@ -74,6 +82,7 @@ module Contrast
|
|
|
74
82
|
|
|
75
83
|
def to_controlled_hash
|
|
76
84
|
{
|
|
85
|
+
security_logger: security_logger.settings_blank? ? nil : security_logger.to_controlled_hash,
|
|
77
86
|
assessment: @_assess ? assess.to_controlled_hash : {},
|
|
78
87
|
defend: @_protect ? protect.to_controlled_hash : {},
|
|
79
88
|
telemetry: telemetry
|
|
@@ -14,15 +14,24 @@ module Contrast
|
|
|
14
14
|
# severity_blocked, severity_blocked_perimeter, severity_exploited, severity_probed,
|
|
15
15
|
# severity_probed_perimeter
|
|
16
16
|
SEVERITIES = %w[ALERT CRITICAL ERROR WARNING NOTICE INFO DEBUG].cs__freeze
|
|
17
|
-
|
|
17
|
+
# Order and elements matter, the same setter must be called against same response field.
|
|
18
|
+
SYSLOG_METHODS_NG = %i[
|
|
18
19
|
enable= ip= port= facility= protocol= connection_type= severity_exploited= severity_blocked=
|
|
19
20
|
severity_probed= severity_probed_suspicious= severity_blocked_perimeter= severity_probed_perimeter=
|
|
20
21
|
].cs__freeze
|
|
21
|
-
|
|
22
|
+
SYSLOG_RESPONSE_KEYS_NG = %i[
|
|
22
23
|
syslogEnabled syslogIpAddress syslogPortNumber syslogFacilityCode syslogProtocol
|
|
23
24
|
syslogConnectionType syslogSeverityExploited syslogSeverityBlocked syslogSeverityProbed
|
|
24
25
|
syslogSeveritySuspicious syslogSeverityBlockedPerimeter syslogSeverityProbedPerimeter
|
|
25
26
|
].cs__freeze
|
|
27
|
+
SYSLOG_METHODS = %i[
|
|
28
|
+
enable= ip= port= facility= connection_type= severity_blocked= severity_blocked_perimeter=
|
|
29
|
+
severity_exploited= severity_probed= severity_probed_perimeter=
|
|
30
|
+
].cs__freeze
|
|
31
|
+
SYSLOG_RESPONSE_KEYS = %i[
|
|
32
|
+
enable ip facility connection_type severity_blocked severity_blocked_perimeter severity_exploited
|
|
33
|
+
severity_probed severity_probed_perimeter
|
|
34
|
+
].cs__freeze
|
|
26
35
|
|
|
27
36
|
# @return enable [Boolean]
|
|
28
37
|
attr_accessor :enable
|
|
@@ -40,6 +49,21 @@ module Contrast
|
|
|
40
49
|
@ip = Contrast::Utils::ObjectShare::EMPTY_STRING
|
|
41
50
|
@port = 0
|
|
42
51
|
@facility = 0
|
|
52
|
+
@blank = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# check to see if object is being used
|
|
56
|
+
#
|
|
57
|
+
# @return [Boolean]
|
|
58
|
+
def settings_blank?
|
|
59
|
+
@blank
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Set the state of settings
|
|
63
|
+
#
|
|
64
|
+
# @return [Boolean]
|
|
65
|
+
def not_blank!
|
|
66
|
+
@blank = false
|
|
43
67
|
end
|
|
44
68
|
|
|
45
69
|
# @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
|
|
@@ -134,10 +158,15 @@ module Contrast
|
|
|
134
158
|
end
|
|
135
159
|
|
|
136
160
|
# @param settings_array [Array] Settings retrieved from response
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
161
|
+
# @param ng_ [Boolean]
|
|
162
|
+
def assign_array settings_array, ng_: true
|
|
163
|
+
methods = ng_ ? SYSLOG_METHODS_NG : SYSLOG_METHODS
|
|
164
|
+
response_keys = ng_ ? SYSLOG_RESPONSE_KEYS_NG : SYSLOG_RESPONSE_KEYS
|
|
165
|
+
|
|
166
|
+
methods.each_with_index do |method, index|
|
|
167
|
+
send(method, settings_array[response_keys[index]])
|
|
140
168
|
end
|
|
169
|
+
not_blank!
|
|
141
170
|
end
|
|
142
171
|
|
|
143
172
|
def to_controlled_hash
|
|
@@ -76,6 +76,7 @@ module Contrast
|
|
|
76
76
|
@_normalized_uri ||= begin
|
|
77
77
|
path = rack_request.path_info || rack_request.path.to_s
|
|
78
78
|
path = '/' if path.empty?
|
|
79
|
+
|
|
79
80
|
uri = path.split(Contrast::Utils::ObjectShare::SEMICOLON)[0] # remove ;jsessionid
|
|
80
81
|
uri = uri.split(Contrast::Utils::ObjectShare::QUESTION_MARK)[0] # remove ?query_string=
|
|
81
82
|
uri.gsub(INNER_REST_TOKEN, INNER_NUMBER_MARKER) # replace interior tokens
|
|
@@ -21,18 +21,13 @@ module Contrast
|
|
|
21
21
|
@ruleset = ::Contrast::AGENT.ruleset
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
# reports events[Contrast::Agent::Reporting::
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
def report_activity
|
|
24
|
+
# reports events[Contrast::Agent::Reporting::ObservedRoute] to TS
|
|
25
|
+
# Other ReportingEvents are handled through batching in the middleware
|
|
26
|
+
#
|
|
27
|
+
def report_observed_route
|
|
29
28
|
return unless (reporter = Contrast::Agent.reporter)
|
|
30
29
|
|
|
31
|
-
reporter.send_event(context.observed_route)
|
|
32
|
-
# Mask Sensitive Data
|
|
33
|
-
Contrast::Agent::Reporting::Masker.mask(context.activity)
|
|
34
|
-
event = context.activity
|
|
35
|
-
reporter.send_event(event)
|
|
30
|
+
reporter.send_event(context.observed_route) if Contrast::ROUTES_SENT.sendable?(context.observed_route)
|
|
36
31
|
end
|
|
37
32
|
|
|
38
33
|
# If the response is streaming, we should only perform filtering on our stream safe rules
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
require 'contrast/components/logger'
|
|
5
5
|
require 'contrast/agent/reporting/report'
|
|
6
6
|
require 'contrast/agent/reporting/reporter_heartbeat'
|
|
7
|
+
require 'contrast/agent/reporting/server_settings_worker'
|
|
7
8
|
require 'contrast/agent/telemetry/base'
|
|
9
|
+
require 'contrast/agent/protect/input_analyzer/worth_watching_analyzer'
|
|
10
|
+
require 'contrast/config/diagnostics'
|
|
8
11
|
|
|
9
12
|
module Contrast
|
|
10
13
|
module Agent
|
|
@@ -18,13 +21,19 @@ module Contrast
|
|
|
18
21
|
attr_reader :reporter
|
|
19
22
|
# @return [Contrast::Agent::ReporterHeartbeat]
|
|
20
23
|
attr_reader :reporter_heartbeat
|
|
24
|
+
# @return [Contrast::Agent::Protect::WorthWatchingInputAnalyzer]
|
|
25
|
+
attr_reader :worth_watching_analyzer
|
|
26
|
+
# @return [Contrast::Agent::ServerSettingsWorker]
|
|
27
|
+
attr_reader :reporter_settings_worker
|
|
21
28
|
|
|
22
29
|
def initialize
|
|
23
30
|
@pids = {}
|
|
24
31
|
@heapdump_util = Contrast::Utils::HeapDumpUtil.new
|
|
25
32
|
@reporter = Contrast::Agent::Reporter.new
|
|
26
33
|
@reporter_heartbeat = Contrast::Agent::ReporterHeartbeat.new
|
|
34
|
+
@reporter_settings_worker = Contrast::Agent::ServerSettingsWorker.new
|
|
27
35
|
@telemetry = Contrast::Agent::Telemetry::Base.new if Contrast::Agent::Telemetry::Base.enabled?
|
|
36
|
+
@worth_watching_analyzer = Contrast::Agent::Protect::WorthWatchingInputAnalyzer.new unless protect_disabled?
|
|
28
37
|
end
|
|
29
38
|
|
|
30
39
|
# @return [Hash, nil] map of process to thread startup status
|
|
@@ -34,11 +43,16 @@ module Contrast
|
|
|
34
43
|
logger.debug('ThreadWatcher started threads')
|
|
35
44
|
reporter_status = init_thread(reporter)
|
|
36
45
|
reporter_heartbeat_status = init_thread(reporter_heartbeat)
|
|
37
|
-
|
|
46
|
+
reporter_settings_worker_status = init_thread(reporter_settings_worker)
|
|
47
|
+
@pids[Process.pid] = reporter_status && reporter_heartbeat_status && reporter_settings_worker_status
|
|
38
48
|
if Contrast::Agent::Telemetry::Base.enabled?
|
|
39
49
|
telemetry_status = init_thread(telemetry_queue)
|
|
40
50
|
@pids[Process.pid] = @pids[Process.pid] && telemetry_status
|
|
41
51
|
end
|
|
52
|
+
unless protect_disabled?
|
|
53
|
+
worth_watching_analyzer_status = init_thread(worth_watching_analyzer)
|
|
54
|
+
@pids[Process.pid] = @pids[Process.pid] && worth_watching_analyzer_status
|
|
55
|
+
end
|
|
42
56
|
@pids
|
|
43
57
|
end
|
|
44
58
|
|
|
@@ -49,11 +63,27 @@ module Contrast
|
|
|
49
63
|
startup!
|
|
50
64
|
end
|
|
51
65
|
|
|
66
|
+
# This method will check the config and if the config is invalid - it will kill the agent
|
|
67
|
+
def self.check_before_start
|
|
68
|
+
return if Contrast::CONFIG.send(:validate)
|
|
69
|
+
|
|
70
|
+
@_diagnostics = Contrast::Agent::DiagnosticsConfig::Diagnostics.new(Contrast::AGENT.logger.path ||
|
|
71
|
+
Contrast::Components::Config::CONTRAST_LOG)
|
|
72
|
+
@_diagnostics.config.populate_fail_connection
|
|
73
|
+
@_diagnostics.write_to_file_logic(false, reset: false)
|
|
74
|
+
# kill agent
|
|
75
|
+
Contrast::AGENT.disable_agent!
|
|
76
|
+
# TODO: RUBY-1822
|
|
77
|
+
# set the in_application_scope to 1 so we short circuit it
|
|
78
|
+
end
|
|
79
|
+
|
|
52
80
|
def shutdown!
|
|
53
81
|
heapdump_util&.stop!
|
|
54
82
|
telemetry_queue&.stop!
|
|
55
83
|
reporter&.stop!
|
|
56
84
|
reporter_heartbeat&.stop!
|
|
85
|
+
worth_watching_analyzer&.stop!
|
|
86
|
+
reporter_settings_worker&.stop!
|
|
57
87
|
end
|
|
58
88
|
|
|
59
89
|
# @return [Contrast::Agent::Telemetry::Base]
|
|
@@ -78,6 +108,10 @@ module Contrast
|
|
|
78
108
|
logger.debug('Thread status', type: watcher.to_s, alive: result)
|
|
79
109
|
result
|
|
80
110
|
end
|
|
111
|
+
|
|
112
|
+
def protect_disabled?
|
|
113
|
+
::Contrast::PROTECT.forcibly_disabled?
|
|
114
|
+
end
|
|
81
115
|
end
|
|
82
116
|
end
|
|
83
117
|
end
|
data/lib/contrast/agent.rb
CHANGED
|
@@ -73,6 +73,12 @@ module Contrast
|
|
|
73
73
|
thread_watcher.reporter
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
# @return [Contrast::Agent::Protect::WorthWatchingAnalyzer]
|
|
77
|
+
def self.worth_watching_analyzer
|
|
78
|
+
thread_watcher.worth_watching_analyzer
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @return [Contrast::Agent::ThreadWatcher]
|
|
76
82
|
def self.thread_watcher
|
|
77
83
|
@_thread_watcher ||= Contrast::Agent::ThreadWatcher.new
|
|
78
84
|
end
|
|
@@ -10,6 +10,7 @@ module Contrast
|
|
|
10
10
|
@last_success = nil
|
|
11
11
|
@last_failure = nil
|
|
12
12
|
@startup_messages_sent = false
|
|
13
|
+
@_startup_server_message_sent = false
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
# Whether we have sent startup message to TeamServer. True after successfully sending startup messages to
|
|
@@ -20,6 +21,20 @@ module Contrast
|
|
|
20
21
|
@startup_messages_sent
|
|
21
22
|
end
|
|
22
23
|
|
|
24
|
+
# Check to see if we have sent server message and received settings from TS.
|
|
25
|
+
#
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
def startup_server_message_sent?
|
|
28
|
+
@_startup_server_message_sent
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Set the server message status state
|
|
32
|
+
#
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def server_response_success!
|
|
35
|
+
@_startup_server_message_sent = true
|
|
36
|
+
end
|
|
37
|
+
|
|
23
38
|
# The last message sent was successful or not
|
|
24
39
|
#
|
|
25
40
|
# @return [Boolean]
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'rubygems/version'
|
|
5
|
+
require 'contrast/components/base'
|
|
5
6
|
require 'contrast/agent/rule_set'
|
|
6
7
|
require 'contrast/components/logger'
|
|
7
8
|
require 'contrast/components/security_logger'
|
|
8
9
|
require 'contrast/components/heap_dump'
|
|
9
10
|
require 'contrast/components/ruby_component'
|
|
11
|
+
require 'contrast/components/polling'
|
|
10
12
|
|
|
11
13
|
module Contrast
|
|
12
14
|
module Components
|
|
@@ -17,11 +19,22 @@ module Contrast
|
|
|
17
19
|
class Interface
|
|
18
20
|
include Contrast::Components::ComponentBase
|
|
19
21
|
|
|
22
|
+
# @return [String]
|
|
23
|
+
attr_reader :canon_name
|
|
24
|
+
# @return [Array]
|
|
25
|
+
attr_reader :config_values
|
|
26
|
+
|
|
27
|
+
CANON_NAME = 'agent'
|
|
28
|
+
CONFIG_VALUES = %w[enabled? omit_body?].cs__freeze
|
|
29
|
+
|
|
20
30
|
def initialize hsh = {}
|
|
31
|
+
@config_values = CONFIG_VALUES
|
|
32
|
+
@canon_name = CANON_NAME
|
|
21
33
|
return unless hsh
|
|
22
34
|
|
|
23
35
|
@_enable = hsh[:enable]
|
|
24
36
|
@_omit_body = hsh[:omit_body]
|
|
37
|
+
@_polling = Contrast::Components::Polling::Interface.new(hsh[:polling])
|
|
25
38
|
@_logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
|
|
26
39
|
@_security_logger = Contrast::Components::SecurityLogger::Interface.new(hsh[:security_logger])
|
|
27
40
|
@_ruby = Contrast::Components::Ruby::Interface.new(hsh[:ruby])
|
|
@@ -34,6 +47,10 @@ module Contrast
|
|
|
34
47
|
@_logger = Contrast::Components::Logger::Interface.new
|
|
35
48
|
end
|
|
36
49
|
|
|
50
|
+
def polling
|
|
51
|
+
@_polling ||= Contrast::Components::Polling::Interface.new
|
|
52
|
+
end
|
|
53
|
+
|
|
37
54
|
def security_logger
|
|
38
55
|
return @_security_logger unless @_security_logger.nil?
|
|
39
56
|
|
|
@@ -87,6 +104,10 @@ module Contrast
|
|
|
87
104
|
@_omit_body
|
|
88
105
|
end
|
|
89
106
|
|
|
107
|
+
def disable_agent!
|
|
108
|
+
@_enable = false
|
|
109
|
+
end
|
|
110
|
+
|
|
90
111
|
def exception_control
|
|
91
112
|
@_exception_control ||= {
|
|
92
113
|
enable: true?(ruby.exceptions.capture),
|
|
@@ -110,6 +131,19 @@ module Contrast
|
|
|
110
131
|
Contrast::Agent::TracePointHook.enable!
|
|
111
132
|
end
|
|
112
133
|
|
|
134
|
+
# Converts current configuration to effective config values class and appends them to
|
|
135
|
+
# EffectiveConfig class.
|
|
136
|
+
#
|
|
137
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
138
|
+
def to_effective_config effective_config
|
|
139
|
+
super
|
|
140
|
+
logger&.to_effective_config(effective_config)
|
|
141
|
+
security_logger&.to_effective_config(effective_config)
|
|
142
|
+
ruby&.to_effective_config(effective_config)
|
|
143
|
+
heap_dump&.to_effective_config(effective_config)
|
|
144
|
+
polling&.to_effective_config(effective_config)
|
|
145
|
+
end
|
|
146
|
+
|
|
113
147
|
protected
|
|
114
148
|
|
|
115
149
|
def retrieve_protect_ruleset
|
|
@@ -17,6 +17,10 @@ module Contrast
|
|
|
17
17
|
include Contrast::Components::ComponentBase
|
|
18
18
|
include Contrast::Config::BaseConfiguration
|
|
19
19
|
|
|
20
|
+
CANON_NAME = 'api'
|
|
21
|
+
PROXY_NAME = "#{ CANON_NAME }.proxy"
|
|
22
|
+
CONFIG_VALUES = %w[api_key user_name service_key url].cs__freeze
|
|
23
|
+
|
|
20
24
|
# @return [String]
|
|
21
25
|
attr_accessor :api_key
|
|
22
26
|
# @return [String]
|
|
@@ -120,8 +124,27 @@ module Contrast
|
|
|
120
124
|
@_certification_key_file ||= ::Contrast::CONFIG.api.certificate.key_file
|
|
121
125
|
end
|
|
122
126
|
|
|
127
|
+
# Converts current configuration to effective config values class and appends them to
|
|
128
|
+
# EffectiveConfig class.
|
|
129
|
+
#
|
|
130
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
131
|
+
def to_effective_config effective_config
|
|
132
|
+
add_effective_config_values(effective_config, CONFIG_VALUES, CANON_NAME, CONTRAST)
|
|
133
|
+
effective_proxy(effective_config)
|
|
134
|
+
request_audit&.to_effective_config(effective_config)
|
|
135
|
+
certificate&.to_effective_config(effective_config)
|
|
136
|
+
end
|
|
137
|
+
|
|
123
138
|
private
|
|
124
139
|
|
|
140
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
141
|
+
def effective_proxy effective_config
|
|
142
|
+
add_single_effective_value(effective_config, ENABLE, proxy_enable.to_s, PROXY_NAME, "#{ CONTRAST }.proxy")
|
|
143
|
+
return unless proxy_url && proxy_enable
|
|
144
|
+
|
|
145
|
+
add_single_effective_value(effective_config, 'url', proxy_url, PROXY_NAME, "#{ CONTRAST }.proxy")
|
|
146
|
+
end
|
|
147
|
+
|
|
125
148
|
def certification_truly_enabled? config_path
|
|
126
149
|
return false unless true?(config_path.enable)
|
|
127
150
|
return true if file_exists?(certification_ca_file) && valid_cert?(certification_ca_file)
|
|
@@ -14,7 +14,7 @@ module Contrast
|
|
|
14
14
|
# parent_configuration_spec.yaml.
|
|
15
15
|
# Specifically, this allows for querying the state of the Application,
|
|
16
16
|
# including the Client, Process, and Server information.
|
|
17
|
-
class Interface
|
|
17
|
+
class Interface # rubocop:disable Metrics/ClassLength
|
|
18
18
|
include Contrast::Components::AppContextExtend
|
|
19
19
|
include Contrast::Components::ComponentBase
|
|
20
20
|
include Contrast::Config::BaseConfiguration
|
|
@@ -23,6 +23,8 @@ module Contrast
|
|
|
23
23
|
DEFAULT_APP_PATH = '/'
|
|
24
24
|
DEFAULT_SERVER_NAME = 'localhost'
|
|
25
25
|
DEFAULT_SERVER_PATH = '/'
|
|
26
|
+
CANON_NAME = 'application'
|
|
27
|
+
CONFIG_VALUES = %w[name version language path group tags code metadata session_id session_metadata].cs__freeze
|
|
26
28
|
|
|
27
29
|
# @return [String]
|
|
28
30
|
attr_accessor :version
|
|
@@ -30,15 +32,20 @@ module Contrast
|
|
|
30
32
|
attr_accessor :language
|
|
31
33
|
# @return [String]
|
|
32
34
|
attr_accessor :group
|
|
33
|
-
|
|
34
|
-
attr_accessor :tags
|
|
35
|
+
attr_writer :tags
|
|
35
36
|
# @return [String]
|
|
36
37
|
attr_accessor :code
|
|
37
38
|
# @return [String]
|
|
38
39
|
attr_accessor :metadata
|
|
40
|
+
# @return [String]
|
|
41
|
+
attr_reader :canon_name
|
|
42
|
+
# @return [Array]
|
|
43
|
+
attr_reader :config_values
|
|
39
44
|
|
|
40
45
|
def initialize hsh = {}
|
|
41
46
|
original_pid
|
|
47
|
+
@config_values = CONFIG_VALUES
|
|
48
|
+
@canon_name = CANON_NAME
|
|
42
49
|
return unless hsh
|
|
43
50
|
|
|
44
51
|
@_name = hsh[:name]
|
|
@@ -135,6 +142,10 @@ module Contrast
|
|
|
135
142
|
end
|
|
136
143
|
end
|
|
137
144
|
|
|
145
|
+
def tags
|
|
146
|
+
stringify_array(@tags)
|
|
147
|
+
end
|
|
148
|
+
|
|
138
149
|
# Determines if the Process we're currently in matches that of the
|
|
139
150
|
# Process in which the App Context instance was created.
|
|
140
151
|
# If it doesn't, that indicates the running context is in a new
|
|
@@ -147,6 +158,15 @@ module Contrast
|
|
|
147
158
|
current_pid != original_pid
|
|
148
159
|
end
|
|
149
160
|
|
|
161
|
+
# Converts current configuration to effective config values class and appends them to
|
|
162
|
+
# EffectiveConfig class.
|
|
163
|
+
#
|
|
164
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
165
|
+
def to_effective_config effective_config
|
|
166
|
+
super
|
|
167
|
+
Contrast::CONFIG.server.to_effective_config(effective_config)
|
|
168
|
+
end
|
|
169
|
+
|
|
150
170
|
private
|
|
151
171
|
|
|
152
172
|
def original_pid
|
|
@@ -15,21 +15,36 @@ module Contrast
|
|
|
15
15
|
class Interface # rubocop:disable Metrics/ClassLength
|
|
16
16
|
include Contrast::Components::ComponentBase
|
|
17
17
|
|
|
18
|
-
# @return [String, nil]
|
|
19
|
-
attr_accessor :tags
|
|
20
18
|
# @return [Boolean, nil]
|
|
21
19
|
attr_accessor :enable
|
|
22
20
|
# @return [Array, nil]
|
|
23
|
-
attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces
|
|
21
|
+
attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces, :tags
|
|
22
|
+
# @return [String]
|
|
23
|
+
attr_reader :canon_name
|
|
24
|
+
# @return [Array]
|
|
25
|
+
attr_reader :config_values
|
|
24
26
|
|
|
25
27
|
DEFAULT_STACKTRACES = 'ALL'
|
|
26
28
|
DEFAULT_MAX_SOURCE_EVENTS = 50_000
|
|
27
29
|
DEFAULT_MAX_PROPAGATION_EVENTS = 50_000
|
|
28
30
|
DEFAULT_MAX_RULE_REPORTED = 100
|
|
29
31
|
DEFAULT_MAX_RULE_TIME_THRESHOLD = 300_000
|
|
30
|
-
|
|
32
|
+
CANON_NAME = 'assess'
|
|
33
|
+
CONFIG_VALUES = %w[
|
|
34
|
+
enabled?
|
|
35
|
+
tags
|
|
36
|
+
enable_scan_response
|
|
37
|
+
enable_original_object
|
|
38
|
+
stacktraces
|
|
39
|
+
max_context_source_events
|
|
40
|
+
max_propagation_events
|
|
41
|
+
max_rule_reported
|
|
42
|
+
time_limit_threshold
|
|
43
|
+
].cs__freeze
|
|
31
44
|
# rubocop:disable Naming/MemoizedInstanceVariableName
|
|
32
45
|
def initialize hsh = {}
|
|
46
|
+
@config_values = CONFIG_VALUES
|
|
47
|
+
@canon_name = CANON_NAME
|
|
33
48
|
return unless hsh
|
|
34
49
|
|
|
35
50
|
@enable = hsh[:enable]
|
|
@@ -91,6 +106,11 @@ module Contrast
|
|
|
91
106
|
@max_context_source_events ||= DEFAULT_MAX_SOURCE_EVENTS
|
|
92
107
|
end
|
|
93
108
|
|
|
109
|
+
# @return [String, nil]
|
|
110
|
+
def tags
|
|
111
|
+
stringify_array(@tags)
|
|
112
|
+
end
|
|
113
|
+
|
|
94
114
|
def enabled?
|
|
95
115
|
# config overrides if forcibly set
|
|
96
116
|
return false if forcibly_disabled?
|
|
@@ -187,6 +207,16 @@ module Contrast
|
|
|
187
207
|
::Contrast::SETTINGS.assess_state.session_id
|
|
188
208
|
end
|
|
189
209
|
|
|
210
|
+
# Converts current configuration to effective config values class and appends them to
|
|
211
|
+
# EffectiveConfig class.
|
|
212
|
+
#
|
|
213
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
214
|
+
def to_effective_config effective_config
|
|
215
|
+
super
|
|
216
|
+
sampling&.to_effective_config(effective_config)
|
|
217
|
+
rules&.to_effective_config(effective_config)
|
|
218
|
+
end
|
|
219
|
+
|
|
190
220
|
# rubocop:enable Naming/MemoizedInstanceVariableName
|
|
191
221
|
private
|
|
192
222
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'contrast/config/base_configuration'
|
|
5
|
+
require 'contrast/utils/object_share'
|
|
6
|
+
require 'contrast/components/base'
|
|
5
7
|
|
|
6
8
|
module Contrast
|
|
7
9
|
module Components
|
|
@@ -10,17 +12,33 @@ module Contrast
|
|
|
10
12
|
module AssessRules
|
|
11
13
|
class Interface # :nodoc:
|
|
12
14
|
include Contrast::Config::BaseConfiguration
|
|
15
|
+
include Contrast::Components::ComponentBase
|
|
13
16
|
|
|
14
17
|
SPEC_KEY = :disabled_rules.cs__freeze
|
|
18
|
+
CANON_NAME = 'assess.rules'
|
|
19
|
+
NAME_PREFIX = "#{ CONTRAST }.#{ CANON_NAME }"
|
|
20
|
+
|
|
15
21
|
# @return [Array, nil] list of disabled assess rules
|
|
16
22
|
attr_accessor :disabled_rules
|
|
23
|
+
# @return [String]
|
|
24
|
+
attr_reader :canon_name
|
|
17
25
|
|
|
18
26
|
def initialize hsh = {}
|
|
27
|
+
@canon_name = CANON_NAME
|
|
28
|
+
@disabled_rules = []
|
|
19
29
|
return unless hsh
|
|
20
30
|
|
|
21
31
|
@disabled_rules = cast_disabled_rules(hsh)
|
|
22
32
|
end
|
|
23
33
|
|
|
34
|
+
# Converts current configuration to effective config values class and appends them to
|
|
35
|
+
# EffectiveConfig class.
|
|
36
|
+
#
|
|
37
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
38
|
+
def to_effective_config effective_config
|
|
39
|
+
add_single_effective_value(effective_config, SPEC_KEY.to_s, disabled_rules, canon_name, NAME_PREFIX)
|
|
40
|
+
end
|
|
41
|
+
|
|
24
42
|
private
|
|
25
43
|
|
|
26
44
|
def cast_disabled_rules hsh
|
|
@@ -1,11 +1,33 @@
|
|
|
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/config/diagnostics_tools'
|
|
5
|
+
require 'contrast/utils/object_share'
|
|
6
|
+
|
|
4
7
|
module Contrast
|
|
5
8
|
module Components
|
|
6
9
|
# All components should inherit from this,
|
|
7
10
|
# whether Interfaces, InstanceMethods or ClassMethods.
|
|
8
11
|
module ComponentBase
|
|
12
|
+
include Contrast::Agent::DiagnosticsConfig::DiagnosticsTools
|
|
13
|
+
|
|
14
|
+
CONTRAST = 'contrast'
|
|
15
|
+
ENABLE = 'enable'
|
|
16
|
+
|
|
17
|
+
# Used for config diagnostics. Override per rule.
|
|
18
|
+
#
|
|
19
|
+
# @return [String]
|
|
20
|
+
def canon_name
|
|
21
|
+
Contrast::Utils::ObjectShare::EMPTY_STRING
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Used for config diagnostics. Override per rule.
|
|
25
|
+
#
|
|
26
|
+
# @return [Array]
|
|
27
|
+
def config_values
|
|
28
|
+
Contrast::Utils::ObjectShare::EMPTY_ARRAY
|
|
29
|
+
end
|
|
30
|
+
|
|
9
31
|
# use this to determine if the configuration value is literally boolean
|
|
10
32
|
# false or some form of the word `false`, regardless of case. It should
|
|
11
33
|
# be used for those values which default to `true` as they should only
|
|
@@ -58,6 +80,24 @@ module Contrast
|
|
|
58
80
|
|
|
59
81
|
File.exist?(path)
|
|
60
82
|
end
|
|
83
|
+
|
|
84
|
+
# Converts current configuration to effective config values class and appends them to
|
|
85
|
+
# EffectiveConfig class.
|
|
86
|
+
#
|
|
87
|
+
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
|
88
|
+
def to_effective_config effective_config
|
|
89
|
+
add_effective_config_values(effective_config, config_values, canon_name, "#{ CONTRAST }.#{ canon_name }")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# attempts to stringifys the config value if it is an array with the join char
|
|
93
|
+
# @param val[Object] val to stringify
|
|
94
|
+
# @param join_char[String, ','] join character defaults to ','
|
|
95
|
+
# @return [String, Object] the stringified val or the object as is
|
|
96
|
+
def stringify_array val, join_char = ','
|
|
97
|
+
return val.join(join_char) if val.cs__is_a?(Array)
|
|
98
|
+
|
|
99
|
+
val
|
|
100
|
+
end
|
|
61
101
|
end
|
|
62
102
|
end
|
|
63
103
|
end
|