contrast-agent 4.6.0 → 4.7.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/.gitmodules +1 -1
- data/Rakefile +1 -2
- data/ext/build_funchook.rb +3 -3
- data/ext/extconf_common.rb +1 -5
- data/lib/contrast/agent/assess.rb +1 -1
- data/lib/contrast/agent/assess/contrast_object.rb +2 -2
- data/lib/contrast/agent/assess/events/event_factory.rb +2 -1
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +6 -3
- data/lib/contrast/agent/assess/policy/patcher.rb +10 -17
- data/lib/contrast/agent/assess/policy/policy_node.rb +25 -33
- data/lib/contrast/agent/assess/policy/preshift.rb +3 -1
- data/lib/contrast/agent/assess/policy/propagation_method.rb +6 -15
- data/lib/contrast/agent/assess/policy/propagation_node.rb +19 -8
- data/lib/contrast/agent/assess/policy/propagator/center.rb +2 -1
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +3 -1
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -1
- data/lib/contrast/agent/assess/policy/propagator/select.rb +2 -12
- data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -7
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -7
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -15
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +6 -3
- data/lib/contrast/agent/assess/policy/source_method.rb +6 -6
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -3
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +5 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +6 -15
- data/lib/contrast/agent/assess/policy/trigger_node.rb +2 -1
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +4 -3
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +1 -2
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +1 -8
- data/lib/contrast/agent/assess/property/evented.rb +8 -5
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +11 -5
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +4 -1
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +3 -5
- data/lib/contrast/agent/class_reopener.rb +3 -1
- data/lib/contrast/agent/disable_reaction.rb +1 -3
- data/lib/contrast/agent/exclusion_matcher.rb +5 -11
- data/lib/contrast/agent/inventory/dependencies.rb +2 -0
- data/lib/contrast/agent/middleware.rb +3 -5
- data/lib/contrast/agent/module_data.rb +3 -3
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +6 -5
- data/lib/contrast/agent/patching/policy/method_policy.rb +6 -2
- data/lib/contrast/agent/patching/policy/module_policy.rb +14 -7
- data/lib/contrast/agent/patching/policy/patch.rb +11 -16
- data/lib/contrast/agent/patching/policy/patch_status.rb +6 -7
- data/lib/contrast/agent/patching/policy/patcher.rb +15 -12
- data/lib/contrast/agent/patching/policy/policy_node.rb +14 -4
- data/lib/contrast/agent/patching/policy/trigger_node.rb +21 -8
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +2 -3
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +5 -9
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +5 -5
- data/lib/contrast/agent/protect/rule/base.rb +13 -16
- data/lib/contrast/agent/protect/rule/base_service.rb +9 -5
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +14 -18
- data/lib/contrast/agent/protect/rule/deserialization.rb +6 -13
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +3 -14
- data/lib/contrast/agent/protect/rule/no_sqli.rb +6 -2
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -3
- data/lib/contrast/agent/protect/rule/path_traversal.rb +5 -5
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
- data/lib/contrast/agent/protect/rule/xss.rb +1 -1
- data/lib/contrast/agent/protect/rule/xxe.rb +5 -12
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +1 -2
- data/lib/contrast/agent/reaction_processor.rb +11 -10
- data/lib/contrast/agent/request.rb +23 -23
- data/lib/contrast/agent/request_context.rb +9 -14
- data/lib/contrast/agent/rewriter.rb +5 -3
- data/lib/contrast/agent/service_heartbeat.rb +2 -3
- data/lib/contrast/agent/tracepoint_hook.rb +1 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/response_processor.rb +2 -4
- data/lib/contrast/api/communication/service_lifecycle.rb +4 -2
- data/lib/contrast/api/communication/socket_client.rb +8 -21
- data/lib/contrast/api/communication/speedracer.rb +3 -7
- data/lib/contrast/api/decorators/application_startup.rb +6 -2
- data/lib/contrast/api/decorators/library.rb +8 -6
- data/lib/contrast/api/decorators/message.rb +3 -3
- data/lib/contrast/api/decorators/trace_event.rb +3 -1
- data/lib/contrast/api/decorators/trace_event_object.rb +1 -3
- data/lib/contrast/api/decorators/trace_taint_range_tags.rb +1 -6
- data/lib/contrast/components/agent.rb +9 -4
- data/lib/contrast/components/app_context.rb +6 -6
- data/lib/contrast/components/config.rb +2 -1
- data/lib/contrast/components/contrast_service.rb +7 -8
- data/lib/contrast/components/interface.rb +3 -2
- data/lib/contrast/components/sampling.rb +8 -2
- data/lib/contrast/components/settings.rb +4 -2
- data/lib/contrast/config/assess_rules_configuration.rb +1 -3
- data/lib/contrast/config/base_configuration.rb +4 -5
- data/lib/contrast/config/exception_configuration.rb +1 -5
- data/lib/contrast/config/heap_dump_configuration.rb +12 -6
- data/lib/contrast/config/logger_configuration.rb +1 -5
- data/lib/contrast/configuration.rb +3 -14
- data/lib/contrast/extension/assess/array.rb +1 -6
- data/lib/contrast/extension/assess/erb.rb +1 -7
- data/lib/contrast/extension/assess/eval_trigger.rb +2 -6
- data/lib/contrast/extension/assess/exec_trigger.rb +3 -9
- data/lib/contrast/extension/assess/fiber.rb +2 -12
- data/lib/contrast/extension/assess/kernel.rb +2 -9
- data/lib/contrast/extension/assess/marshal.rb +2 -6
- data/lib/contrast/extension/assess/regexp.rb +1 -6
- data/lib/contrast/extension/assess/string.rb +3 -1
- data/lib/contrast/extension/kernel.rb +4 -2
- data/lib/contrast/framework/manager.rb +1 -2
- data/lib/contrast/framework/rack/patch/session_cookie.rb +5 -18
- data/lib/contrast/framework/rack/patch/support.rb +6 -4
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +7 -2
- data/lib/contrast/framework/rails/patch/support.rb +4 -2
- data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +4 -1
- data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +2 -0
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +2 -0
- data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +2 -0
- data/lib/contrast/framework/rails/support.rb +2 -2
- data/lib/contrast/framework/sinatra/support.rb +3 -1
- data/lib/contrast/funchook/funchook.rb +1 -5
- data/lib/contrast/logger/application.rb +12 -9
- data/lib/contrast/logger/format.rb +2 -5
- data/lib/contrast/logger/log.rb +4 -3
- data/lib/contrast/logger/request.rb +1 -2
- data/lib/contrast/security_exception.rb +1 -1
- data/lib/contrast/tasks/service.rb +5 -1
- data/lib/contrast/utils/assess/tracking_util.rb +1 -2
- data/lib/contrast/utils/class_util.rb +0 -8
- data/lib/contrast/utils/hash_digest.rb +2 -5
- data/lib/contrast/utils/io_util.rb +1 -1
- data/lib/contrast/utils/job_servers_running.rb +9 -4
- data/lib/contrast/utils/os.rb +2 -1
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -1
- data/ruby-agent.gemspec +13 -14
- data/sonar-project.properties +9 -0
- metadata +37 -36
|
@@ -65,8 +65,7 @@ module Contrast
|
|
|
65
65
|
return true if http && !tmp_id.end_with?(DTD_MARKER)
|
|
66
66
|
|
|
67
67
|
# external if using external protocol
|
|
68
|
-
return true if tmp_id.start_with?(FTP_START, FILE_START,
|
|
69
|
-
JAR_START, GOPHER_START)
|
|
68
|
+
return true if tmp_id.start_with?(FTP_START, FILE_START, JAR_START, GOPHER_START)
|
|
70
69
|
|
|
71
70
|
# external if start with path marker (/ or .)
|
|
72
71
|
return true if tmp_id.start_with?(Contrast::Utils::ObjectShare::SLASH,
|
|
@@ -6,11 +6,9 @@ require 'contrast/components/interface'
|
|
|
6
6
|
|
|
7
7
|
module Contrast
|
|
8
8
|
module Agent
|
|
9
|
-
# Because communication between the Agent/Service and TeamServer can only
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# specific action. This action is referred to as a Reaction. This class is
|
|
13
|
-
# how we handle those Reaction messages.
|
|
9
|
+
# Because communication between the Agent/Service and TeamServer can only be initiated by outbound connections
|
|
10
|
+
# from the Agent/Service, we must provide a mechanism for the TeamServer to direct the Agent to take a specific
|
|
11
|
+
# action. This action is referred to as a Reaction. This class is how we handle those Reaction messages.
|
|
14
12
|
class ReactionProcessor
|
|
15
13
|
include Contrast::Components::Interface
|
|
16
14
|
access_component :logging
|
|
@@ -25,8 +23,12 @@ module Contrast
|
|
|
25
23
|
return unless application_settings&.reactions&.any?
|
|
26
24
|
|
|
27
25
|
application_settings.reactions.each do |reaction|
|
|
28
|
-
#
|
|
29
|
-
level = reaction.log_level.nil?
|
|
26
|
+
# The enums are all uppercase, we need to downcase them before attempting to log.
|
|
27
|
+
level = if reaction.log_level.nil?
|
|
28
|
+
:error
|
|
29
|
+
else
|
|
30
|
+
reaction.log_level.name.downcase # rubocop:disable Security/Module/Name -- ruby logger builtin.
|
|
31
|
+
end
|
|
30
32
|
|
|
31
33
|
logger.with_level(level, reaction.message) if reaction.message
|
|
32
34
|
|
|
@@ -36,9 +38,8 @@ module Contrast
|
|
|
36
38
|
when Contrast::Api::Settings::Reaction::Operation::NOOP
|
|
37
39
|
# NOOP
|
|
38
40
|
else
|
|
39
|
-
logger.warn(
|
|
40
|
-
|
|
41
|
-
operation: reaction.operation)
|
|
41
|
+
logger.warn('ReactionProcessor received a reaction with an unknown operation',
|
|
42
|
+
operation: reaction.operation)
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
end
|
|
@@ -30,7 +30,8 @@ module Contrast
|
|
|
30
30
|
attr_accessor :route, :observed_route
|
|
31
31
|
|
|
32
32
|
# Delegate calls to the following methods to the attribute @rack_request
|
|
33
|
-
def_delegators :@rack_request, :base_url, :content_type, :cookies, :env, :ip, :path, :port, :query_string,
|
|
33
|
+
def_delegators :@rack_request, :base_url, :content_type, :cookies, :env, :ip, :path, :port, :query_string,
|
|
34
|
+
:request_method, :scheme, :url, :user_agent
|
|
34
35
|
|
|
35
36
|
def initialize rack_request
|
|
36
37
|
@rack_request = rack_request
|
|
@@ -56,32 +57,28 @@ module Contrast
|
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
def document_type
|
|
59
|
-
@_document_type ||=
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
end
|
|
67
|
-
end
|
|
60
|
+
@_document_type ||= if /xml/i.match?(content_type) || body&.start_with?('<?xml')
|
|
61
|
+
:XML
|
|
62
|
+
elsif /json/i.match?(content_type) || body&.match?(/\s*[{\[]/)
|
|
63
|
+
:JSON
|
|
64
|
+
else
|
|
65
|
+
:NORMAL
|
|
66
|
+
end
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
# Header keys upcased and any underscores replaced with dashes
|
|
71
70
|
def headers
|
|
72
|
-
@_headers ||=
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
hash[Contrast::Utils::StringUtils.normalized_key(name)] = value
|
|
82
|
-
end
|
|
83
|
-
hash
|
|
71
|
+
@_headers ||= with_contrast_scope do
|
|
72
|
+
hash = {}
|
|
73
|
+
env.each do |key, value|
|
|
74
|
+
next unless key
|
|
75
|
+
|
|
76
|
+
name = key.to_s
|
|
77
|
+
next unless name.start_with?(Contrast::Utils::ObjectShare::HTTP_SCORE)
|
|
78
|
+
|
|
79
|
+
hash[Contrast::Utils::StringUtils.normalized_key(name)] = value
|
|
84
80
|
end
|
|
81
|
+
hash
|
|
85
82
|
end
|
|
86
83
|
end
|
|
87
84
|
|
|
@@ -90,7 +87,10 @@ module Contrast
|
|
|
90
87
|
# (can't use body because it might be nil)
|
|
91
88
|
@_body_read ||= begin
|
|
92
89
|
body = rack_request.body
|
|
93
|
-
if defined?(Rack::Multipart) &&
|
|
90
|
+
if defined?(Rack::Multipart) &&
|
|
91
|
+
defined?(Rack::Multipart::UploadedFile) &&
|
|
92
|
+
body.is_a?(Rack::Multipart::UploadedFile)
|
|
93
|
+
|
|
94
94
|
logger.trace("not parsing uploaded file body :: #{ body.original_filename }::#{ body.content_type }")
|
|
95
95
|
@_body = nil
|
|
96
96
|
else
|
|
@@ -31,15 +31,14 @@ module Contrast
|
|
|
31
31
|
|
|
32
32
|
EMPTY_INPUT_ANALYSIS_PB = Contrast::Api::Settings::InputAnalysis.new
|
|
33
33
|
|
|
34
|
-
attr_reader :activity, :logging_hash, :observed_route, :request, :response, :route, :speedracer_input_analysis,
|
|
34
|
+
attr_reader :activity, :logging_hash, :observed_route, :request, :response, :route, :speedracer_input_analysis,
|
|
35
|
+
:server_activity, :timer
|
|
35
36
|
|
|
36
37
|
def initialize rack_request, app_loaded = true
|
|
37
38
|
with_contrast_scope do
|
|
38
39
|
# all requests get a timer and hash
|
|
39
40
|
@timer = Contrast::Utils::Timer.new
|
|
40
|
-
@logging_hash = {
|
|
41
|
-
request_id: __id__
|
|
42
|
-
}
|
|
41
|
+
@logging_hash = { request_id: __id__ }
|
|
43
42
|
|
|
44
43
|
# instantiate helper for request and response
|
|
45
44
|
@request = Contrast::Agent::Request.new(rack_request)
|
|
@@ -64,7 +63,9 @@ module Contrast
|
|
|
64
63
|
|
|
65
64
|
@sample = true
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
if ASSESS.enabled?
|
|
67
|
+
@sample_request, @sample_response = Contrast::Utils::Assess::SamplingUtil.instance.sample?(@request)
|
|
68
|
+
end
|
|
68
69
|
|
|
69
70
|
@sample_response &&= ASSESS.scan_response?
|
|
70
71
|
|
|
@@ -209,16 +210,10 @@ module Contrast
|
|
|
209
210
|
# special case for rules (like reflected xss)
|
|
210
211
|
# that used to have an infilter / block
|
|
211
212
|
# mode but now are just block at perimeter
|
|
212
|
-
rule.build_attack_with_match(
|
|
213
|
-
|
|
214
|
-
ia_result,
|
|
215
|
-
attack_results_by_rule[rule_id],
|
|
216
|
-
ia_result.value)
|
|
213
|
+
rule.build_attack_with_match(self, ia_result, attack_results_by_rule[rule_id],
|
|
214
|
+
ia_result.value)
|
|
217
215
|
else
|
|
218
|
-
rule.build_attack_without_match(
|
|
219
|
-
self,
|
|
220
|
-
ia_result,
|
|
221
|
-
attack_results_by_rule[rule_id])
|
|
216
|
+
rule.build_attack_without_match(self, ia_result, attack_results_by_rule[rule_id])
|
|
222
217
|
end
|
|
223
218
|
attack_results_by_rule[rule_id] = attack_result
|
|
224
219
|
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
# intentional -- we're using a << operator here
|
|
5
5
|
|
|
6
|
+
return unless RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
|
7
|
+
|
|
6
8
|
require 'contrast/agent/class_reopener'
|
|
7
9
|
require 'contrast/agent/patching/policy/patch_status'
|
|
8
10
|
require 'contrast/components/interface'
|
|
@@ -57,13 +59,13 @@ module Contrast
|
|
|
57
59
|
rescue SyntaxError, StandardError => e
|
|
58
60
|
opener = nil
|
|
59
61
|
mod ||= module_data.mod
|
|
60
|
-
logger.debug('Reopening threw a handled exception - skipping rewriting', e, module: module_data.
|
|
62
|
+
logger.debug('Reopening threw a handled exception - skipping rewriting', e, module: module_data.mod_name)
|
|
61
63
|
status ||= Contrast::Agent::Patching::Policy::PatchStatus.get_status(mod)
|
|
62
64
|
status.failed_rewrite!
|
|
63
65
|
ensure
|
|
64
66
|
opener&.commit_patches
|
|
65
67
|
logger.trace('Rewriting complete',
|
|
66
|
-
module: module_data.
|
|
68
|
+
module: module_data.mod_name,
|
|
67
69
|
result: Contrast::Agent::Patching::Policy::PatchStatus.get_status(
|
|
68
70
|
module_data.mod).rewrite_status)
|
|
69
71
|
end
|
|
@@ -238,7 +240,7 @@ module Contrast
|
|
|
238
240
|
].cs__freeze
|
|
239
241
|
def should_rewrite? module_data
|
|
240
242
|
clazz = module_data.mod
|
|
241
|
-
name = module_data.
|
|
243
|
+
name = module_data.mod_name
|
|
242
244
|
return false unless clazz
|
|
243
245
|
|
|
244
246
|
# Name can be nil for anonymous modules. We won't work on them.
|
|
@@ -21,9 +21,8 @@ module Contrast
|
|
|
21
21
|
@_thread = Contrast::Agent::Thread.new do
|
|
22
22
|
logger.info('Starting heartbeat thread.')
|
|
23
23
|
loop do
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
end
|
|
24
|
+
Contrast::Agent.messaging_queue.send_event_eventually(poll_message)
|
|
25
|
+
|
|
27
26
|
sleep REFRESH_INTERVAL_SEC
|
|
28
27
|
end
|
|
29
28
|
end
|
|
@@ -37,7 +37,7 @@ module Contrast
|
|
|
37
37
|
|
|
38
38
|
Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.associate_file(path) if path
|
|
39
39
|
Contrast::Agent::Patching::Policy::Patcher.patch_specific_module(loaded_module)
|
|
40
|
-
Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolation(loaded_module)
|
|
40
|
+
Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolation(loaded_module) if RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
|
|
41
41
|
Contrast::Agent::Assess::Policy::PolicyScanner.scan(tracepoint_event)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -24,10 +24,8 @@ module Contrast
|
|
|
24
24
|
|
|
25
25
|
Contrast::Logger::Log.instance.update(server_features&.log_file, server_features&.log_level)
|
|
26
26
|
update_features(server_features, app_settings)
|
|
27
|
-
logger.trace(
|
|
28
|
-
|
|
29
|
-
protect_on: PROTECT.enabled?,
|
|
30
|
-
assess_on: ASSESS.enabled?)
|
|
27
|
+
logger.trace('Agent settings updated in response to Service', protect_on: PROTECT.enabled?,
|
|
28
|
+
assess_on: ASSESS.enabled?)
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
private
|
|
@@ -21,12 +21,14 @@ module Contrast
|
|
|
21
21
|
is_service_started
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
# check if there's a zombie service that exists, and wait on it if so.
|
|
25
|
-
#
|
|
24
|
+
# check if there's a zombie service that exists, and wait on it if so. currently, this only happens when trying
|
|
25
|
+
# to initialize speedracer
|
|
26
26
|
def zombie_check
|
|
27
27
|
zombie_pid_list = Contrast::Utils::OS.zombie_pids
|
|
28
28
|
zombie_pid_list.each do |pid|
|
|
29
29
|
Process.wait(pid.to_i)
|
|
30
|
+
rescue Errno::ECHILD => _e
|
|
31
|
+
# Sometimes the zombie process dies between us finding it and killing it
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
|
@@ -52,16 +52,13 @@ module Contrast
|
|
|
52
52
|
end
|
|
53
53
|
# The host & port are set,
|
|
54
54
|
if CONFIG.root.agent.service.host && CONFIG.root.agent.service.port
|
|
55
|
-
logger.info('Connecting to the Contrast Service using a TCP socket',
|
|
56
|
-
|
|
57
|
-
port: CONTRAST_SERVICE.port)
|
|
55
|
+
logger.info('Connecting to the Contrast Service using a TCP socket', host: CONTRAST_SERVICE.host,
|
|
56
|
+
port: CONTRAST_SERVICE.port)
|
|
58
57
|
return
|
|
59
58
|
end
|
|
60
59
|
|
|
61
60
|
# Or something is not set.
|
|
62
|
-
logger.warn(log_connection_error_msg,
|
|
63
|
-
host: CONTRAST_SERVICE.host,
|
|
64
|
-
port: CONTRAST_SERVICE.port)
|
|
61
|
+
logger.warn(log_connection_error_msg, host: CONTRAST_SERVICE.host, port: CONTRAST_SERVICE.port)
|
|
65
62
|
end
|
|
66
63
|
|
|
67
64
|
# If our connection isn't built properly, we need to warn the user. This builds out the context specific
|
|
@@ -87,26 +84,16 @@ module Contrast
|
|
|
87
84
|
def send_message msg
|
|
88
85
|
return unless msg
|
|
89
86
|
|
|
90
|
-
logger.debug('Sending message.',
|
|
91
|
-
msg_id: msg.__id__,
|
|
92
|
-
p_id: msg.pid,
|
|
93
|
-
msg_count: msg.message_count)
|
|
87
|
+
logger.debug('Sending message.', msg_id: msg.__id__, p_id: msg.pid, msg_count: msg.message_count)
|
|
94
88
|
to_service = Contrast::Api::Dtm::Message.encode(msg)
|
|
95
89
|
from_service = send_marshaled(to_service)
|
|
96
90
|
response = Contrast::Api::Settings::AgentSettings.decode(from_service)
|
|
97
|
-
logger.debug('Received response.',
|
|
98
|
-
|
|
99
|
-
p_id: msg.pid,
|
|
100
|
-
msg_count: msg.message_count,
|
|
101
|
-
response_id: response&.__id__)
|
|
91
|
+
logger.debug('Received response.', msg_id: msg.__id__, p_id: msg.pid, msg_count: msg.message_count,
|
|
92
|
+
response_id: response&.__id__)
|
|
102
93
|
response
|
|
103
94
|
rescue StandardError => e
|
|
104
|
-
logger.error('Sending failed for message.',
|
|
105
|
-
|
|
106
|
-
msg_id: msg.__id__,
|
|
107
|
-
p_id: msg.pid,
|
|
108
|
-
msg_count: msg.message_count,
|
|
109
|
-
response_id: response&.__id__)
|
|
95
|
+
logger.error('Sending failed for message.', e, msg_id: msg.__id__, p_id: msg.pid,
|
|
96
|
+
msg_count: msg.message_count, response_id: response&.__id__)
|
|
110
97
|
raise e # reraise to let Speedracer manage the connection
|
|
111
98
|
end
|
|
112
99
|
|
|
@@ -58,16 +58,14 @@ module Contrast
|
|
|
58
58
|
def send_to_speedracer event
|
|
59
59
|
ensure_startup!
|
|
60
60
|
|
|
61
|
-
logger.debug_with_time(event.cs__class.
|
|
61
|
+
logger.debug_with_time(event.cs__class.cs__name) do
|
|
62
62
|
response = socket_client.send_one event
|
|
63
63
|
status.success!
|
|
64
64
|
yield response
|
|
65
65
|
end
|
|
66
66
|
rescue StandardError => e
|
|
67
67
|
status.failure!
|
|
68
|
-
logger.error('Unable to send message.', e,
|
|
69
|
-
event_id: event.__id__,
|
|
70
|
-
event_type: event.cs__class.name)
|
|
68
|
+
logger.error('Unable to send message.', e, event_id: event.__id__, event_type: event.cs__class.cs__name)
|
|
71
69
|
nil
|
|
72
70
|
end
|
|
73
71
|
|
|
@@ -101,9 +99,7 @@ module Contrast
|
|
|
101
99
|
end
|
|
102
100
|
|
|
103
101
|
def log_send_event event
|
|
104
|
-
logger.debug('Immediately sending event.',
|
|
105
|
-
event_id: event.__id__,
|
|
106
|
-
event_type: event.cs__class.name)
|
|
102
|
+
logger.debug('Immediately sending event.', event_id: event.__id__, event_type: event.cs__class.cs__name)
|
|
107
103
|
end
|
|
108
104
|
end
|
|
109
105
|
end
|
|
@@ -41,8 +41,12 @@ module Contrast
|
|
|
41
41
|
#
|
|
42
42
|
# @param msg [Contrast::Api::Dtm::ApplicationCreate]
|
|
43
43
|
def session! msg
|
|
44
|
-
msg.session_id
|
|
45
|
-
|
|
44
|
+
msg.session_id = Contrast::Utils::StringUtils.protobuf_format(
|
|
45
|
+
CONFIG.root.application.session_id,
|
|
46
|
+
truncate: false)
|
|
47
|
+
msg.session_metadata = Contrast::Utils::StringUtils.protobuf_format(
|
|
48
|
+
CONFIG.root.application.session_metadata,
|
|
49
|
+
truncate: false)
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
end
|
|
@@ -10,6 +10,8 @@ module Contrast
|
|
|
10
10
|
module Decorators
|
|
11
11
|
# Used to decorate the Library protobuf model to handle Gem::Specification translation
|
|
12
12
|
module Library
|
|
13
|
+
StringUtils = Contrast::Utils::StringUtils
|
|
14
|
+
|
|
13
15
|
def self.included klass
|
|
14
16
|
klass.extend(ClassMethods)
|
|
15
17
|
end
|
|
@@ -18,13 +20,13 @@ module Contrast
|
|
|
18
20
|
module ClassMethods
|
|
19
21
|
def build digest, gem_specification
|
|
20
22
|
msg = new
|
|
21
|
-
msg.file_path =
|
|
22
|
-
msg.hash_code =
|
|
23
|
-
msg.version =
|
|
24
|
-
msg.manifest =
|
|
23
|
+
msg.file_path = StringUtils.force_utf8(gem_specification.name) # rubocop:disable Security/Module/Name
|
|
24
|
+
msg.hash_code = StringUtils.force_utf8(digest)
|
|
25
|
+
msg.version = StringUtils.force_utf8(gem_specification.version)
|
|
26
|
+
msg.manifest = StringUtils.force_utf8(build_manifest(gem_specification))
|
|
25
27
|
msg.external_ms = date_to_ms(gem_specification.date)
|
|
26
28
|
msg.internal_ms = msg.external_ms
|
|
27
|
-
msg.url =
|
|
29
|
+
msg.url = StringUtils.force_utf8(gem_specification.homepage)
|
|
28
30
|
msg.class_count = file_count(gem_specification.full_gem_path.to_s)
|
|
29
31
|
msg.used_class_count = 0
|
|
30
32
|
msg
|
|
@@ -37,7 +39,7 @@ module Contrast
|
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def build_manifest spec
|
|
40
|
-
|
|
42
|
+
StringUtils.force_utf8(spec.to_yaml.to_s)
|
|
41
43
|
rescue StandardError
|
|
42
44
|
nil
|
|
43
45
|
end
|
|
@@ -38,7 +38,7 @@ module Contrast
|
|
|
38
38
|
when Contrast::Api::Dtm::ObservedRoute
|
|
39
39
|
self.observed_route = event
|
|
40
40
|
else
|
|
41
|
-
logger.error('Unknown event type received. Unsure how to send.', event_type: event.cs__class.
|
|
41
|
+
logger.error('Unknown event type received. Unsure how to send.', event_type: event.cs__class.cs__name)
|
|
42
42
|
return
|
|
43
43
|
end
|
|
44
44
|
logger.debug('Wrapping event in message',
|
|
@@ -46,7 +46,7 @@ module Contrast
|
|
|
46
46
|
p_id: pid,
|
|
47
47
|
msg_count: message_count,
|
|
48
48
|
event_id: event.__id__,
|
|
49
|
-
event_type: event.cs__class.
|
|
49
|
+
event_type: event.cs__class.cs__name)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Used to add class methods to the ApplicationUpdate class on inclusion of the decorator
|
|
@@ -58,7 +58,7 @@ module Contrast
|
|
|
58
58
|
|
|
59
59
|
def build event
|
|
60
60
|
msg = new
|
|
61
|
-
msg.app_name = APP_CONTEXT.
|
|
61
|
+
msg.app_name = APP_CONTEXT.app_name
|
|
62
62
|
msg.app_path = APP_CONTEXT.path
|
|
63
63
|
msg.app_language = Contrast::Utils::ObjectShare::RUBY
|
|
64
64
|
msg.client_id = APP_CONTEXT.client_id
|
|
@@ -106,7 +106,9 @@ module Contrast
|
|
|
106
106
|
event_dtm.thread = Contrast::Utils::StringUtils.force_utf8(contrast_event.thread)
|
|
107
107
|
event_dtm.build_parent_ids!(contrast_event)
|
|
108
108
|
event_dtm.object_id = contrast_event.event_id.to_i
|
|
109
|
-
event_dtm.signature = Contrast::Api::Dtm::TraceEventSignature.build(contrast_event.ret,
|
|
109
|
+
event_dtm.signature = Contrast::Api::Dtm::TraceEventSignature.build(contrast_event.ret,
|
|
110
|
+
contrast_event.policy_node,
|
|
111
|
+
contrast_event.args)
|
|
110
112
|
event_dtm
|
|
111
113
|
end
|
|
112
114
|
end
|