contrast-agent 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|