contrast-agent 7.0.0 → 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/extconf_common.rb +88 -14
- data/lib/contrast/agent/assess/policy/policy.rb +1 -1
- data/lib/contrast/agent/assess/policy/source_method.rb +13 -4
- data/lib/contrast/agent/assess/policy/trigger_method.rb +12 -18
- data/lib/contrast/agent/deadzone/policy/policy.rb +1 -1
- data/lib/contrast/agent/excluder/excluder.rb +64 -31
- data/lib/contrast/agent/patching/policy/policy.rb +2 -2
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +3 -0
- data/lib/contrast/agent/protect/rule/base.rb +4 -6
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker.rb +1 -1
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +2 -2
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization/deserialization.rb +2 -2
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli.rb +1 -1
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +1 -1
- data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +1 -1
- data/lib/contrast/agent/protect/rule/utils/filters.rb +6 -6
- data/lib/contrast/agent/protect/rule/xxe/xxe.rb +1 -1
- data/lib/contrast/agent/reporting/client/interface.rb +132 -0
- data/lib/contrast/agent/reporting/client/interface_base.rb +27 -0
- data/lib/contrast/agent/reporting/connection_status.rb +0 -1
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +6 -4
- data/lib/contrast/agent/reporting/reporter.rb +23 -23
- data/lib/contrast/agent/reporting/reporting_events/agent_effective_config.rb +32 -0
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +7 -0
- data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +3 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +57 -12
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +55 -38
- data/lib/contrast/agent/reporting/reporting_utilities/resend.rb +144 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +35 -13
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +14 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +13 -12
- data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +3 -0
- data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +3 -0
- data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +3 -0
- data/lib/contrast/agent/request/request.rb +27 -12
- data/lib/contrast/agent/telemetry/base.rb +55 -31
- data/lib/contrast/agent/telemetry/client.rb +1 -3
- data/lib/contrast/agent/telemetry/exception/obfuscate.rb +97 -0
- data/lib/contrast/agent/telemetry/exception.rb +1 -0
- data/lib/contrast/agent/telemetry/telemetry.rb +0 -7
- data/lib/contrast/agent/thread/thread_watcher.rb +2 -2
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/components/agent.rb +1 -1
- data/lib/contrast/components/api.rb +2 -2
- data/lib/contrast/components/app_context.rb +1 -1
- data/lib/contrast/components/assess.rb +1 -1
- data/lib/contrast/components/assess_rules.rb +1 -1
- data/lib/contrast/components/base.rb +3 -3
- data/lib/contrast/components/config/sources.rb +13 -9
- data/lib/contrast/components/config.rb +2 -2
- data/lib/contrast/components/protect.rb +2 -2
- data/lib/contrast/components/sampling.rb +6 -4
- data/lib/contrast/components/settings.rb +10 -1
- data/lib/contrast/config/certification_configuration.rb +1 -1
- data/lib/contrast/config/configuration_files.rb +47 -0
- data/lib/contrast/config/diagnostics/command_line.rb +24 -0
- data/lib/contrast/config/{config.rb → diagnostics/config.rb} +21 -6
- data/lib/contrast/config/diagnostics/contrast_ui.rb +24 -0
- data/lib/contrast/config/diagnostics/effective_config.rb +28 -0
- data/lib/contrast/config/diagnostics/effective_config_value.rb +14 -0
- data/lib/contrast/config/diagnostics/environment_variables.rb +51 -0
- data/lib/contrast/config/{diagnostics.rb → diagnostics/monitor.rb} +10 -10
- data/lib/contrast/config/diagnostics/source_config_value.rb +55 -0
- data/lib/contrast/config/diagnostics/tools.rb +188 -0
- data/lib/contrast/config/diagnostics/user_configuration_file.rb +44 -0
- data/lib/contrast/config/request_audit_configuration.rb +1 -1
- data/lib/contrast/config/server_configuration.rb +1 -1
- data/lib/contrast/config/validate.rb +2 -2
- data/lib/contrast/configuration.rb +82 -57
- data/lib/contrast/framework/grape/support.rb +1 -2
- data/lib/contrast/framework/manager.rb +17 -8
- data/lib/contrast/framework/rack/support.rb +99 -1
- data/lib/contrast/framework/rails/support.rb +1 -2
- data/lib/contrast/framework/sinatra/support.rb +1 -2
- data/lib/contrast/logger/aliased_logging.rb +18 -9
- data/lib/contrast/utils/hash_utils.rb +62 -0
- data/lib/contrast/utils/json.rb +46 -0
- data/lib/contrast/utils/net_http_base.rb +75 -26
- data/lib/contrast/utils/request_utils.rb +14 -0
- data/resources/assess/policy.json +11 -0
- metadata +20 -8
- data/lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb +0 -27
- data/lib/contrast/config/diagnostics_tools.rb +0 -99
- data/lib/contrast/config/effective_config.rb +0 -131
- data/lib/contrast/config/effective_config_value.rb +0 -32
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'net/http'
|
5
|
+
require 'resolv'
|
5
6
|
require 'contrast/components/logger'
|
6
7
|
require 'contrast/utils/object_share'
|
7
8
|
require 'socket'
|
@@ -10,8 +11,25 @@ module Contrast
|
|
10
11
|
module Utils
|
11
12
|
# This module creates a Net::HTTP client base to be used by different services
|
12
13
|
# All HTTP clients reporting to Telemetry or TS should inherit from this
|
13
|
-
class NetHttpBase
|
14
|
+
class NetHttpBase # rubocop:disable Metrics/ClassLength
|
14
15
|
include Contrast::Components::Logger::InstanceMethods
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Last recorded error
|
19
|
+
# @return [StandardError]
|
20
|
+
def last_error
|
21
|
+
@_last_error
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [StandardError]
|
25
|
+
def last_error= error
|
26
|
+
@_last_error = error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :client_name
|
32
|
+
|
15
33
|
# This method initializes the Net::HTTP client we'll need. it will validate
|
16
34
|
# the connection and make the first request. If connection is valid and response
|
17
35
|
# is available then the open connection is returned.
|
@@ -23,29 +41,22 @@ module Contrast
|
|
23
41
|
# self signed certificates provided by config [default = false]
|
24
42
|
# @return [Net::HTTP, nil] Return open connection or nil
|
25
43
|
def initialize_connection service_name, url, use_proxy: false, use_custom_cert: false
|
26
|
-
|
27
|
-
|
28
|
-
addr =
|
29
|
-
return
|
30
|
-
return
|
31
|
-
|
32
|
-
# the proxy is enabled only if there is provided url even if the enable is set to true
|
33
|
-
proxy_addr = URI(Contrast::API.proxy_url) if proxy_enabled?
|
34
|
-
net_http_client = initialize_client(addr, proxy_addr, use_proxy, use_custom_cert)
|
35
|
-
return if net_http_client.nil?
|
36
|
-
|
37
|
-
net_http_client.start
|
38
|
-
return unless net_http_client.started?
|
44
|
+
Contrast::Utils::NetHttpBase.last_error = nil
|
45
|
+
@client_name = service_name
|
46
|
+
return unless (addr = retrieve_address(url))
|
47
|
+
return unless (net_http_client = configure_new_client(addr, use_proxy, use_custom_cert))
|
48
|
+
return unless client_started?(net_http_client)
|
39
49
|
|
40
|
-
logger.debug("Starting #{
|
50
|
+
logger.debug("Starting #{ client_name } connection test")
|
41
51
|
return unless connection_verified?(net_http_client, url)
|
42
52
|
|
43
|
-
logger.debug('Client verified', service:
|
53
|
+
logger.debug('Client verified', service: client_name, url: url)
|
44
54
|
net_http_client
|
45
55
|
rescue StandardError => e
|
46
|
-
|
47
|
-
|
48
|
-
|
56
|
+
Contrast::Utils::NetHttpBase.last_error = e
|
57
|
+
return if client_name == Contrast::Agent::Telemetry::Client::SERVICE_NAME
|
58
|
+
|
59
|
+
logger.error('Connection failed', e, service: client_name, url: url)
|
49
60
|
nil
|
50
61
|
end
|
51
62
|
|
@@ -74,14 +85,51 @@ module Contrast
|
|
74
85
|
Errno::ETIMEDOUT, Errno::ESHUTDOWN, Errno::EHOSTDOWN, Errno::EHOSTUNREACH, Errno::EISCONN,
|
75
86
|
Errno::ECONNABORTED, Errno::ENETRESET, Errno::ENETUNREACH => e
|
76
87
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
88
|
+
Contrast::Utils::NetHttpBase.last_error = e
|
89
|
+
unless client_name == Contrast::Agent::Telemetry::Client::SERVICE_NAME
|
90
|
+
logger.error("#{ client_name } connection failed", e.message)
|
91
|
+
end
|
92
|
+
@_connection_verified = false
|
81
93
|
end
|
82
94
|
|
83
95
|
private
|
84
96
|
|
97
|
+
# Starts connection and return started status.
|
98
|
+
#
|
99
|
+
# @param client [Net::HTTP] client instance.
|
100
|
+
# @return [Boolean] status indicates whether connection has started.
|
101
|
+
def client_started? client
|
102
|
+
return false unless client
|
103
|
+
|
104
|
+
client.start
|
105
|
+
client.started?
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param url
|
109
|
+
# @return [URI::Generic, nil]
|
110
|
+
def retrieve_address url
|
111
|
+
return unless (addr = URI(url))
|
112
|
+
return if addr.host.nil? || addr.port.nil?
|
113
|
+
return if addr.scheme != 'https' && !addr.host.to_s.include?('localhost')
|
114
|
+
|
115
|
+
addr
|
116
|
+
end
|
117
|
+
|
118
|
+
# Assigns proxy and custom certificates if enabled, and initializes new client.
|
119
|
+
#
|
120
|
+
# @param addr [URI::Generic, nil]
|
121
|
+
# @param use_proxy [Boolean] flag used to indicate proxy connections [default = false]
|
122
|
+
# @param use_custom_cert [Boolean] flag used to indicate whether the client is to use
|
123
|
+
# @return client [Net::HTTP, nil] initialized client.
|
124
|
+
def configure_new_client addr, use_proxy, use_custom_cert
|
125
|
+
# the proxy is enabled only if there is provided url even if the enable is set to true
|
126
|
+
proxy_addr = URI(Contrast::API.proxy_url) if proxy_enabled?
|
127
|
+
net_http_client = initialize_client(addr, proxy_addr, use_proxy, use_custom_cert)
|
128
|
+
return if net_http_client.nil?
|
129
|
+
|
130
|
+
net_http_client
|
131
|
+
end
|
132
|
+
|
85
133
|
# Resolves the address of the assigned domain to array of corresponding IPs (if more than one)
|
86
134
|
# and runs a matcher to see if current connection IP is in the list.
|
87
135
|
# This is called within #verify_connection, if called on it's own there will be no
|
@@ -114,9 +162,10 @@ module Contrast
|
|
114
162
|
client.key = OpenSSL::PKey::RSA.new(File.read(Contrast::API.certification_key_file)).to_s
|
115
163
|
end
|
116
164
|
rescue Errno::ENOENT => e
|
117
|
-
|
118
|
-
|
119
|
-
|
165
|
+
Contrast::Utils::NetHttpBase.last_error = e
|
166
|
+
unless client_name == Contrast::Agent::Telemetry::Client::SERVICE_NAME
|
167
|
+
logger.error('Custom certificates failed', e.message)
|
168
|
+
end
|
120
169
|
end
|
121
170
|
|
122
171
|
# sets default setting for client validation of certificates and
|
@@ -5,6 +5,20 @@ module Contrast
|
|
5
5
|
module Utils
|
6
6
|
# used in Contrast::Agent::Request
|
7
7
|
module RequestUtils
|
8
|
+
# TOKENS:
|
9
|
+
NUM_ = '/{n}/'
|
10
|
+
ID_ = '{ID}'
|
11
|
+
# PATTERNS:
|
12
|
+
NUM_PATTERN = %r{/\d+/}.cs__freeze
|
13
|
+
END_PATTERN = %r{/\d+$}.cs__freeze
|
14
|
+
STATIC_SUFFIXES = /\.(?:js|css|jpeg|jpg|gif|png|ico|woff|svg|pdf|eot|ttf|jar)$/i.cs__freeze
|
15
|
+
UUID_PATTERN = Regexp.new('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}').cs__freeze # rubocop:disable Metrics/LineLength
|
16
|
+
# Regular expression to match any type of hash pattern that is 16 bytes like uuid with no
|
17
|
+
# slashes, md5, sha1, sha256, etc
|
18
|
+
HASH_PATTERN = Regexp.new('([a-fA-F0-9]{2}){16,}').cs__freeze
|
19
|
+
WIN_PATTERN = Regexp.new('S-1-5-((32-\d+)|(21-\d+-\d+-\d+-\d+))').cs__freeze
|
20
|
+
MEDIA_TYPE_MARKERS = %w[image/ text/css text/javascript].cs__freeze
|
21
|
+
|
8
22
|
# Return a flattened hash of params with realized paths for keys, in
|
9
23
|
# addition to a separate, valueless, entry for each nest key.
|
10
24
|
# See RUBY-621 for more details.
|
@@ -1258,6 +1258,17 @@
|
|
1258
1258
|
"tags":["HTML_ENCODED"],
|
1259
1259
|
"untags":["HTML_DECODED"]
|
1260
1260
|
},
|
1261
|
+
{
|
1262
|
+
"class_name": "Rails::HTML::Concern::ComposedSanitize",
|
1263
|
+
"method_name": "sanitize",
|
1264
|
+
"method_visibility": "public",
|
1265
|
+
"instance_method": true,
|
1266
|
+
"source": "P0",
|
1267
|
+
"target": "R",
|
1268
|
+
"action": "REMOVE",
|
1269
|
+
"tags":["HTML_ENCODED"],
|
1270
|
+
"untags":["HTML_DECODED"]
|
1271
|
+
},
|
1261
1272
|
{
|
1262
1273
|
"class_name": "Rails::Html::SafeListSanitizer",
|
1263
1274
|
"method_name": "sanitize",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contrast-agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- galen.palmer@contrastsecurity.com
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: exe
|
15
15
|
cert_chain: []
|
16
|
-
date: 2023-
|
16
|
+
date: 2023-05-31 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: bundler
|
@@ -1051,6 +1051,8 @@ files:
|
|
1051
1051
|
- lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb
|
1052
1052
|
- lib/contrast/agent/reporting/attack_result/response_type.rb
|
1053
1053
|
- lib/contrast/agent/reporting/attack_result/user_input.rb
|
1054
|
+
- lib/contrast/agent/reporting/client/interface.rb
|
1055
|
+
- lib/contrast/agent/reporting/client/interface_base.rb
|
1054
1056
|
- lib/contrast/agent/reporting/connection_status.rb
|
1055
1057
|
- lib/contrast/agent/reporting/details/bot_blocker_details.rb
|
1056
1058
|
- lib/contrast/agent/reporting/details/cmd_injection_details.rb
|
@@ -1069,7 +1071,6 @@ files:
|
|
1069
1071
|
- lib/contrast/agent/reporting/details/xxe_details.rb
|
1070
1072
|
- lib/contrast/agent/reporting/details/xxe_match.rb
|
1071
1073
|
- lib/contrast/agent/reporting/details/xxe_wrapper.rb
|
1072
|
-
- lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb
|
1073
1074
|
- lib/contrast/agent/reporting/input_analysis/details/protect_rule_details.rb
|
1074
1075
|
- lib/contrast/agent/reporting/input_analysis/input_analysis.rb
|
1075
1076
|
- lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb
|
@@ -1079,6 +1080,7 @@ files:
|
|
1079
1080
|
- lib/contrast/agent/reporting/masker/masker_utils.rb
|
1080
1081
|
- lib/contrast/agent/reporting/report.rb
|
1081
1082
|
- lib/contrast/agent/reporting/reporter.rb
|
1083
|
+
- lib/contrast/agent/reporting/reporting_events/agent_effective_config.rb
|
1082
1084
|
- lib/contrast/agent/reporting/reporting_events/agent_startup.rb
|
1083
1085
|
- lib/contrast/agent/reporting/reporting_events/application_activity.rb
|
1084
1086
|
- lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb
|
@@ -1129,6 +1131,7 @@ files:
|
|
1129
1131
|
- lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb
|
1130
1132
|
- lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb
|
1131
1133
|
- lib/contrast/agent/reporting/reporting_utilities/reporting_storage.rb
|
1134
|
+
- lib/contrast/agent/reporting/reporting_utilities/resend.rb
|
1132
1135
|
- lib/contrast/agent/reporting/reporting_utilities/response.rb
|
1133
1136
|
- lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb
|
1134
1137
|
- lib/contrast/agent/reporting/reporting_utilities/response_handler.rb
|
@@ -1180,6 +1183,7 @@ files:
|
|
1180
1183
|
- lib/contrast/agent/telemetry/exception/event.rb
|
1181
1184
|
- lib/contrast/agent/telemetry/exception/message.rb
|
1182
1185
|
- lib/contrast/agent/telemetry/exception/message_exception.rb
|
1186
|
+
- lib/contrast/agent/telemetry/exception/obfuscate.rb
|
1183
1187
|
- lib/contrast/agent/telemetry/exception/stack_frame.rb
|
1184
1188
|
- lib/contrast/agent/telemetry/hash.rb
|
1185
1189
|
- lib/contrast/agent/telemetry/identifier.rb
|
@@ -1224,11 +1228,17 @@ files:
|
|
1224
1228
|
- lib/contrast/config/api_proxy_configuration.rb
|
1225
1229
|
- lib/contrast/config/base_configuration.rb
|
1226
1230
|
- lib/contrast/config/certification_configuration.rb
|
1227
|
-
- lib/contrast/config/
|
1228
|
-
- lib/contrast/config/diagnostics.rb
|
1229
|
-
- lib/contrast/config/
|
1230
|
-
- lib/contrast/config/
|
1231
|
-
- lib/contrast/config/
|
1231
|
+
- lib/contrast/config/configuration_files.rb
|
1232
|
+
- lib/contrast/config/diagnostics/command_line.rb
|
1233
|
+
- lib/contrast/config/diagnostics/config.rb
|
1234
|
+
- lib/contrast/config/diagnostics/contrast_ui.rb
|
1235
|
+
- lib/contrast/config/diagnostics/effective_config.rb
|
1236
|
+
- lib/contrast/config/diagnostics/effective_config_value.rb
|
1237
|
+
- lib/contrast/config/diagnostics/environment_variables.rb
|
1238
|
+
- lib/contrast/config/diagnostics/monitor.rb
|
1239
|
+
- lib/contrast/config/diagnostics/source_config_value.rb
|
1240
|
+
- lib/contrast/config/diagnostics/tools.rb
|
1241
|
+
- lib/contrast/config/diagnostics/user_configuration_file.rb
|
1232
1242
|
- lib/contrast/config/env_variables.rb
|
1233
1243
|
- lib/contrast/config/exception_configuration.rb
|
1234
1244
|
- lib/contrast/config/protect_rule_configuration.rb
|
@@ -1297,12 +1307,14 @@ files:
|
|
1297
1307
|
- lib/contrast/utils/findings.rb
|
1298
1308
|
- lib/contrast/utils/hash_digest.rb
|
1299
1309
|
- lib/contrast/utils/hash_digest_extend.rb
|
1310
|
+
- lib/contrast/utils/hash_utils.rb
|
1300
1311
|
- lib/contrast/utils/head_dump_utils_extend.rb
|
1301
1312
|
- lib/contrast/utils/heap_dump_util.rb
|
1302
1313
|
- lib/contrast/utils/input_classification_base.rb
|
1303
1314
|
- lib/contrast/utils/invalid_configuration_util.rb
|
1304
1315
|
- lib/contrast/utils/io_util.rb
|
1305
1316
|
- lib/contrast/utils/job_servers_running.rb
|
1317
|
+
- lib/contrast/utils/json.rb
|
1306
1318
|
- lib/contrast/utils/log_utils.rb
|
1307
1319
|
- lib/contrast/utils/lru_cache.rb
|
1308
1320
|
- lib/contrast/utils/metrics_hash.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 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/input_analysis/details/protect_rule_details'
|
5
|
-
|
6
|
-
module Contrast
|
7
|
-
module Agent
|
8
|
-
module Reporting
|
9
|
-
# Bot blocker IA result details info.
|
10
|
-
class BotBlockerDetails < ProtectRuleDetails
|
11
|
-
# @return [String]
|
12
|
-
attr_accessor :bot
|
13
|
-
# User agent header value
|
14
|
-
#
|
15
|
-
# @return [String]
|
16
|
-
attr_accessor :user_agent
|
17
|
-
|
18
|
-
def to_controlled_hash
|
19
|
-
{
|
20
|
-
bot: bot,
|
21
|
-
userAgent: user_agent
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'contrast/utils/object_share'
|
5
|
-
require 'contrast/config/effective_config_value'
|
6
|
-
|
7
|
-
module Contrast
|
8
|
-
module Agent
|
9
|
-
module DiagnosticsConfig
|
10
|
-
# Diagnostics tools to be included in config components.
|
11
|
-
module DiagnosticsTools
|
12
|
-
CHECK = 'd'
|
13
|
-
|
14
|
-
# Converts current configuration for array of values to effective config values class and appends them to
|
15
|
-
# EffectiveConfig class. Must be used inside Config Components only.
|
16
|
-
#
|
17
|
-
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
18
|
-
# @param config_values [Array<String>] array of the names of values.
|
19
|
-
# @param canonical_prefix [String] starting of the path to config => api.proxy...
|
20
|
-
# @param name_prefix [String] the name of the config prefix => contrast.api_key, contrast.url
|
21
|
-
def add_effective_config_values effective_config, config_values, canonical_prefix, name_prefix
|
22
|
-
return if config_values.to_s.empty?
|
23
|
-
|
24
|
-
config_values.each do |config|
|
25
|
-
Contrast::Agent::DiagnosticsConfig::EffectiveConfigValue.new.tap do |value|
|
26
|
-
next if (config_val = send(config.to_sym)).to_s.empty?
|
27
|
-
|
28
|
-
config_name = assign_name(config)
|
29
|
-
value.canonical_name = "#{ canonical_prefix }.#{ config_name }"
|
30
|
-
value.name = "#{ name_prefix }.#{ config_name }"
|
31
|
-
value.value = config_val
|
32
|
-
value.source = Contrast::CONFIG.sources.get(value.canonical_name)
|
33
|
-
if value.source == Contrast::Components::Config::Sources::YAML
|
34
|
-
value.filename = Contrast::CONFIG.config_file_path
|
35
|
-
end
|
36
|
-
effective_config.values << value
|
37
|
-
rescue StandardError => e
|
38
|
-
log_error(e)
|
39
|
-
next
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Converts current configuration for single value to effective config values class and appends them to
|
45
|
-
# EffectiveConfig class. Must be used inside Config Components only.
|
46
|
-
#
|
47
|
-
# @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
|
48
|
-
# @param config_name [String] name of the config.
|
49
|
-
# @param config_value [String, Boolean] value of the config.
|
50
|
-
# @param canonical_prefix [String] starting of the path to config => api.proxy...
|
51
|
-
# @param name_prefix [String] the name of the config prefix => contrast.api_key, contrast.url
|
52
|
-
def add_single_effective_value effective_config, config_name, config_value, canonical_prefix, name_prefix
|
53
|
-
Contrast::Agent::DiagnosticsConfig::EffectiveConfigValue.new.tap do |value|
|
54
|
-
break if config_value.to_s.empty?
|
55
|
-
|
56
|
-
value.value = config_value
|
57
|
-
value.canonical_name = "#{ canonical_prefix }.#{ config_name }"
|
58
|
-
value.name = "#{ name_prefix }.#{ config_name }"
|
59
|
-
value.source = Contrast::CONFIG.sources.get(value.canonical_name)
|
60
|
-
if value.source == Contrast::Components::Config::Sources::YAML
|
61
|
-
value.filename = Contrast::CONFIG.config_file_path
|
62
|
-
end
|
63
|
-
effective_config.values << value
|
64
|
-
rescue StandardError => e
|
65
|
-
log_error(e)
|
66
|
-
next
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
# Assigns a proper name for the config removing '?' out of method names.
|
73
|
-
#
|
74
|
-
# @param config [String] name of the configuration
|
75
|
-
# @return [String]
|
76
|
-
def assign_name config
|
77
|
-
return Contrast::Utils::ObjectShare::EMPTY_STRING unless config
|
78
|
-
|
79
|
-
name = config.dup
|
80
|
-
if name.end_with?(Contrast::Utils::ObjectShare::QUESTION_MARK)
|
81
|
-
# check and remove '?' : start_bundled_service? => start_bundled_service
|
82
|
-
name.delete!(Contrast::Utils::ObjectShare::QUESTION_MARK)
|
83
|
-
name.chop! if name.end_with?(CHECK)
|
84
|
-
name
|
85
|
-
end
|
86
|
-
name
|
87
|
-
end
|
88
|
-
|
89
|
-
# Logs any caught error.
|
90
|
-
#
|
91
|
-
# @param error [StandardError]
|
92
|
-
def log_error error
|
93
|
-
Contrast::CONFIG.proto_logger.warn('Could not write effective config to file: ',
|
94
|
-
error: error, backtrace: error.backtrace)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'contrast/config/effective_config_value'
|
5
|
-
require 'contrast/config/diagnostics_tools'
|
6
|
-
require 'contrast/utils/object_share'
|
7
|
-
|
8
|
-
module Contrast
|
9
|
-
module Agent
|
10
|
-
module DiagnosticsConfig
|
11
|
-
# The current effective config received from all authorized configuration channels.
|
12
|
-
class EffectiveConfig
|
13
|
-
NON_COMMON_ENV = %w[CONTRAST_CONFIG_PATH CONTRAST_AGENT_TELEMETRY_OPTOUT].cs__freeze
|
14
|
-
|
15
|
-
# Value of effective agent configurations
|
16
|
-
#
|
17
|
-
# @return [Array]
|
18
|
-
attr_reader :values
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
@values = []
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_controlled_hash
|
25
|
-
{
|
26
|
-
effective_config: { values: @values&.map(&:to_controlled_hash) },
|
27
|
-
user_configuration_file: yaml_config_settings,
|
28
|
-
environment_variable: environment_settings(ENV).map(&:to_controlled_hash),
|
29
|
-
command_line: command_line_settings.map(&:to_controlled_hash),
|
30
|
-
contrast_ui: contrast_ui_settings.map(&:to_controlled_hash)
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def yaml_config_settings
|
37
|
-
{
|
38
|
-
path: Contrast::CONFIG.config_file_path,
|
39
|
-
values: value_to_s(Contrast::CONFIG.sources.for(Contrast::Components::Config::Sources::YAML))
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
def command_line_settings
|
44
|
-
cli = flatten_settings(Contrast::CONFIG.sources.for(Contrast::Components::Config::Sources::CLI))
|
45
|
-
flat_settings(cli)
|
46
|
-
end
|
47
|
-
|
48
|
-
def contrast_ui_settings
|
49
|
-
ui = flatten_settings(Contrast::CONFIG.sources.for(Contrast::Components::Config::Sources::CONTRASTUI))
|
50
|
-
flat_settings(ui)
|
51
|
-
end
|
52
|
-
|
53
|
-
# @param flats [Array] of flatten configs produced by #flatten_settings
|
54
|
-
# @return [Array]
|
55
|
-
def flat_settings flats
|
56
|
-
ui_settings = []
|
57
|
-
flats.each do |entry|
|
58
|
-
entry.each do |key, value|
|
59
|
-
efc_value = Contrast::Agent::DiagnosticsConfig::EffectiveConfigValue.new.tap do |effective_value|
|
60
|
-
effective_value.canonical_name = Contrast::Utils::ObjectShare::CONTRAST_DOT + key
|
61
|
-
effective_value.name = key
|
62
|
-
effective_value.value = value_to_s(value)
|
63
|
-
end
|
64
|
-
ui_settings << efc_value if efc_value
|
65
|
-
end
|
66
|
-
end
|
67
|
-
ui_settings
|
68
|
-
end
|
69
|
-
|
70
|
-
def flatten_settings data, path = []
|
71
|
-
data.each_with_object([]) do |(k, v), entries|
|
72
|
-
if v.cs__is_a?(Hash)
|
73
|
-
entries.concat(flatten_settings(v, path.dup.append(k.to_sym)))
|
74
|
-
else
|
75
|
-
entries << { "#{ path.join('.') }.#{ k }" => Contrast::CONFIG.config.loaded_config.dig(*path, k).to_s }
|
76
|
-
end
|
77
|
-
end.flatten # rubocop:disable Style/MethodCalledOnDoEndBlock
|
78
|
-
end
|
79
|
-
|
80
|
-
# This method will fill the canonical name for each env var and will check for any uncommon ones.
|
81
|
-
#
|
82
|
-
# @param env [Hash]
|
83
|
-
# @return [Array] array of all the values needed to be written.
|
84
|
-
def environment_settings env
|
85
|
-
env_hash = env.select do |e|
|
86
|
-
e.to_s.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER) || NON_COMMON_ENV.include?(e.to_s)
|
87
|
-
end
|
88
|
-
environment_settings = []
|
89
|
-
env_hash.each do |key, value|
|
90
|
-
efc_value = Contrast::Agent::DiagnosticsConfig::EffectiveConfigValue.new.tap do |effective_value|
|
91
|
-
next unless value
|
92
|
-
|
93
|
-
effective_value.canonical_name = if NON_COMMON_ENV.include?(key)
|
94
|
-
key.gsub(Contrast::Utils::ObjectShare::UNDERSCORE,
|
95
|
-
Contrast::Utils::ObjectShare::PERIOD).downcase
|
96
|
-
else
|
97
|
-
key.gsub(Contrast::Utils::ObjectShare::DOUBLE_UNDERSCORE,
|
98
|
-
Contrast::Utils::ObjectShare::PERIOD).downcase
|
99
|
-
end
|
100
|
-
if effective_value.canonical_name
|
101
|
-
effective_value.name =
|
102
|
-
effective_value.canonical_name.gsub(Contrast::Utils::ObjectShare::CONTRAST_DOT,
|
103
|
-
Contrast::Utils::ObjectShare::EMPTY_STRING)
|
104
|
-
end
|
105
|
-
effective_value.value = value_to_s(value)
|
106
|
-
end
|
107
|
-
environment_settings << efc_value if efc_value
|
108
|
-
end
|
109
|
-
environment_settings
|
110
|
-
end
|
111
|
-
|
112
|
-
# Recursively converts each value to string.
|
113
|
-
#
|
114
|
-
# @param value [Hash]
|
115
|
-
def value_to_s value
|
116
|
-
return value if value.cs__is_a?(String)
|
117
|
-
|
118
|
-
value.each_with_object({}) do |(k, v), m| # rubocop:disable Style/HashTransformValues
|
119
|
-
m[k] = if v.cs__is_a?(Hash)
|
120
|
-
value_to_s(v)
|
121
|
-
elsif v.cs__is_a?(Array)
|
122
|
-
v.map(&:to_s)
|
123
|
-
else
|
124
|
-
v.to_s
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 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 DiagnosticsConfig
|
7
|
-
# All In effect config values stored in a easy to write representation.
|
8
|
-
class EffectiveConfigValue
|
9
|
-
# @return [String] Name of the config starting form root of yaml config.
|
10
|
-
attr_accessor :canonical_name
|
11
|
-
# @return [String] Name of the config.
|
12
|
-
attr_accessor :name
|
13
|
-
# @return [String] Value set for the config.
|
14
|
-
attr_accessor :value
|
15
|
-
# @return [String] The source for the entry in the config.
|
16
|
-
attr_accessor :source
|
17
|
-
# @return [String,nil] The filename for the source of the config, if the source was "yaml".
|
18
|
-
attr_accessor :filename
|
19
|
-
|
20
|
-
def to_controlled_hash
|
21
|
-
{
|
22
|
-
canonical_name: canonical_name,
|
23
|
-
name: name, # rubocop:disable Security/Module/Name
|
24
|
-
value: value&.cs__is_a?(Array) ? value.map(&:to_s) : value.to_s,
|
25
|
-
source: source,
|
26
|
-
filename: filename
|
27
|
-
}.compact
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|