contrast-agent 6.8.0 → 6.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/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
|