contrast-agent 6.6.5 → 6.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/.gitignore +3 -0
- data/.gitmodules +0 -3
- data/ext/cs__scope/cs__scope.c +1 -1
- data/lib/contrast/agent/assess/contrast_event.rb +2 -24
- data/lib/contrast/agent/assess/events/source_event.rb +7 -61
- data/lib/contrast/agent/assess/finalizers/hash.rb +11 -0
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +0 -55
- data/lib/contrast/agent/assess/policy/policy_node.rb +3 -3
- data/lib/contrast/agent/assess/policy/policy_node_utils.rb +0 -1
- data/lib/contrast/agent/assess/policy/propagation_node.rb +4 -4
- data/lib/contrast/agent/assess/policy/source_method.rb +24 -1
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +7 -5
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +6 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +36 -132
- data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -3
- data/lib/contrast/agent/assess/property/evented.rb +2 -12
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +42 -84
- data/lib/contrast/agent/assess/rule/response/base_rule.rb +11 -27
- data/lib/contrast/agent/assess/rule/response/body_rule.rb +1 -3
- data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +77 -62
- data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +1 -1
- data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +6 -1
- data/lib/contrast/agent/assess/rule/response/header_rule.rb +5 -5
- data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +1 -1
- data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +1 -1
- data/lib/contrast/agent/assess/tracker.rb +1 -7
- data/lib/contrast/agent/excluder.rb +206 -0
- data/lib/contrast/agent/exclusion_matcher.rb +6 -0
- data/lib/contrast/agent/inventory/database_config.rb +6 -10
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +4 -0
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -0
- data/lib/contrast/agent/protect/rule/base.rb +49 -5
- data/lib/contrast/agent/protect/rule/base_service.rb +1 -0
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +18 -105
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +129 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +169 -0
- data/lib/contrast/agent/protect/rule/deserialization.rb +2 -1
- data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +51 -0
- data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +67 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +6 -31
- data/lib/contrast/agent/protect/rule/xxe.rb +2 -0
- data/lib/contrast/agent/protect/rule.rb +3 -1
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +6 -0
- data/lib/contrast/agent/reporting/details/sqli_dangerous_functions.rb +22 -0
- data/lib/contrast/agent/reporting/reporter.rb +1 -2
- data/lib/contrast/agent/reporting/reporting_events/agent_startup.rb +2 -2
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -4
- data/lib/contrast/agent/reporting/reporting_events/application_startup.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +0 -23
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +19 -49
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +12 -9
- data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +23 -21
- data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +5 -18
- data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +1 -0
- data/lib/contrast/{api/decorators/trace_taint_range_tags.rb → agent/reporting/reporting_events/finding_event_taint_range_tags.rb} +7 -6
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +2 -2
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -14
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +11 -0
- data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +3 -1
- data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +11 -23
- data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +8 -26
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/build_preflight.rb +4 -7
- data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +3 -3
- data/lib/contrast/agent/request.rb +2 -2
- data/lib/contrast/agent/request_context.rb +8 -20
- data/lib/contrast/agent/request_context_extend.rb +15 -36
- data/lib/contrast/agent/request_handler.rb +0 -8
- data/lib/contrast/agent/response.rb +0 -18
- data/lib/contrast/agent/telemetry/events/event.rb +1 -1
- data/lib/contrast/agent/telemetry/events/metric_event.rb +1 -1
- data/lib/contrast/agent/telemetry/events/startup_metrics_event.rb +3 -3
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +2 -3
- data/lib/contrast/api/communication/socket_client.rb +4 -4
- data/lib/contrast/api/communication/speedracer.rb +4 -8
- data/lib/contrast/api/decorators/agent_startup.rb +5 -6
- data/lib/contrast/api/decorators/application_settings.rb +2 -1
- data/lib/contrast/api/decorators/application_startup.rb +6 -6
- data/lib/contrast/api/decorators/message.rb +0 -4
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +0 -6
- data/lib/contrast/api/decorators.rb +0 -6
- data/lib/contrast/api/dtm.pb.rb +0 -489
- data/lib/contrast/components/agent.rb +16 -12
- data/lib/contrast/components/api.rb +10 -10
- data/lib/contrast/components/app_context.rb +3 -3
- data/lib/contrast/components/app_context_extend.rb +1 -1
- data/lib/contrast/components/assess.rb +92 -38
- data/lib/contrast/components/assess_rules.rb +36 -0
- data/lib/contrast/components/config.rb +54 -12
- data/lib/contrast/components/contrast_service.rb +8 -8
- data/lib/contrast/components/heap_dump.rb +1 -1
- data/lib/contrast/components/protect.rb +5 -5
- data/lib/contrast/components/ruby_component.rb +81 -0
- data/lib/contrast/components/sampling.rb +1 -1
- data/lib/contrast/components/security_logger.rb +23 -0
- data/lib/contrast/components/service.rb +55 -0
- data/lib/contrast/components/settings.rb +12 -4
- data/lib/contrast/config/base_configuration.rb +1 -1
- data/lib/contrast/config/protect_rules_configuration.rb +17 -3
- data/lib/contrast/config/server_configuration.rb +1 -1
- data/lib/contrast/config.rb +0 -6
- data/lib/contrast/configuration.rb +81 -17
- data/lib/contrast/extension/assess/exec_trigger.rb +3 -1
- data/lib/contrast/extension/assess/marshal.rb +3 -2
- data/lib/contrast/extension/assess/string.rb +0 -1
- data/lib/contrast/extension/extension.rb +1 -1
- data/lib/contrast/framework/base_support.rb +0 -5
- data/lib/contrast/framework/grape/support.rb +1 -23
- data/lib/contrast/framework/manager.rb +0 -10
- data/lib/contrast/framework/rails/support.rb +5 -58
- data/lib/contrast/framework/sinatra/support.rb +2 -21
- data/lib/contrast/logger/cef_log.rb +21 -3
- data/lib/contrast/logger/log.rb +1 -11
- data/lib/contrast/tasks/config.rb +4 -2
- data/lib/contrast/utils/assess/event_limit_utils.rb +5 -8
- data/lib/contrast/utils/assess/trigger_method_utils.rb +10 -18
- data/lib/contrast/utils/findings.rb +6 -5
- data/lib/contrast/utils/hash_digest.rb +9 -24
- data/lib/contrast/utils/hash_digest_extend.rb +6 -6
- data/lib/contrast/utils/invalid_configuration_util.rb +21 -58
- data/lib/contrast/utils/log_utils.rb +32 -8
- data/lib/contrast/utils/net_http_base.rb +2 -2
- data/lib/contrast/utils/patching/policy/patch_utils.rb +3 -2
- data/lib/contrast/utils/stack_trace_utils.rb +0 -25
- data/lib/contrast/utils/string_utils.rb +9 -0
- data/lib/contrast/utils/telemetry_client.rb +13 -7
- data/lib/contrast.rb +5 -10
- metadata +22 -28
- data/lib/contrast/agent/reporting/reporting_events/trace_event_source.rb +0 -30
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -36
- data/lib/contrast/api/decorators/activity.rb +0 -33
- data/lib/contrast/api/decorators/architecture_component.rb +0 -36
- data/lib/contrast/api/decorators/finding.rb +0 -29
- data/lib/contrast/api/decorators/route_coverage.rb +0 -91
- data/lib/contrast/api/decorators/trace_event.rb +0 -120
- data/lib/contrast/api/decorators/trace_event_object.rb +0 -63
- data/lib/contrast/api/decorators/trace_event_signature.rb +0 -69
- data/lib/contrast/api/decorators/trace_taint_range.rb +0 -52
- data/lib/contrast/config/assess_configuration.rb +0 -93
- data/lib/contrast/config/assess_rules_configuration.rb +0 -32
- data/lib/contrast/config/root_configuration.rb +0 -90
- data/lib/contrast/config/ruby_configuration.rb +0 -81
- data/lib/contrast/config/service_configuration.rb +0 -49
- data/lib/contrast/utils/preflight_util.rb +0 -13
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/utils/string_utils'
|
|
5
|
-
|
|
6
|
-
module Contrast
|
|
7
|
-
module Api
|
|
8
|
-
module Decorators
|
|
9
|
-
# Used to decorate the {Contrast::Api::Dtm::RouteCoverage} protobuf model
|
|
10
|
-
# to handle conversion between framework route classes and the dtm.
|
|
11
|
-
module RouteCoverage
|
|
12
|
-
def self.included klass
|
|
13
|
-
klass.extend(ClassMethods)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Class methods for RouteCoverage
|
|
17
|
-
module ClassMethods
|
|
18
|
-
def source_or_string obj
|
|
19
|
-
if obj.cs__is_a?(Regexp)
|
|
20
|
-
obj.source
|
|
21
|
-
elsif obj.cs__respond_to?(:safe_string)
|
|
22
|
-
obj.safe_string
|
|
23
|
-
else
|
|
24
|
-
obj.to_s
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Convert ActionDispatch::Journey::Route to Contrast::Api::Dtm::RouteCoverage
|
|
29
|
-
#
|
|
30
|
-
# @param journey_obj [ActionDispatch::Journey::Route] a rails route
|
|
31
|
-
# @param url [String, nil] use url from string instead of journey object.
|
|
32
|
-
# @return [Contrast::Api::Dtm::RouteCoverage]
|
|
33
|
-
def from_action_dispatch_journey journey_obj, url = nil
|
|
34
|
-
msg = new
|
|
35
|
-
msg.route = "#{ journey_obj.defaults[:controller] }##{ journey_obj.defaults[:action] }"
|
|
36
|
-
|
|
37
|
-
verb = source_or_string(journey_obj.verb)
|
|
38
|
-
msg.verb = Contrast::Utils::StringUtils.force_utf8(verb)
|
|
39
|
-
|
|
40
|
-
url ||= source_or_string(journey_obj.path.spec)
|
|
41
|
-
msg.url = Contrast::Utils::StringUtils.force_utf8(url)
|
|
42
|
-
msg
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Convert Sinatra route data to dtm message.
|
|
46
|
-
#
|
|
47
|
-
# @param controller [::Sinatra::Base] the route's final controller.
|
|
48
|
-
# @param method [String] GET, PUT, POST, etc...
|
|
49
|
-
# @param pattern [::Mustermann::Sinatra] the pattern that was matched in routing.
|
|
50
|
-
# @param url [String, nil] use url from string instead matched pattern.
|
|
51
|
-
# @return [Contrast::Api::Dtm::RouteCoverage]
|
|
52
|
-
def from_sinatra_route controller, method, pattern, url = nil
|
|
53
|
-
safe_pattern = source_or_string(pattern)
|
|
54
|
-
safe_url = source_or_string(url || pattern)
|
|
55
|
-
|
|
56
|
-
msg = new
|
|
57
|
-
msg.route = "#{ controller }##{ method } #{ safe_pattern }"
|
|
58
|
-
msg.verb = Contrast::Utils::StringUtils.force_utf8(method)
|
|
59
|
-
msg.url = Contrast::Utils::StringUtils.force_utf8(safe_url)
|
|
60
|
-
msg
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Convert Grape route data to dtm message.
|
|
64
|
-
#
|
|
65
|
-
# @param controller [::Grape::API] the route's final controller.
|
|
66
|
-
# @param method [String] GET, PUT, POST, etc...
|
|
67
|
-
# @param url [String, nil] use url from string instead matched pattern.
|
|
68
|
-
# @param pattern [String, Grape::Router::Route] the pattern that was matched in routing.
|
|
69
|
-
# @return [Contrast::Api::Dtm::RouteCoverage]
|
|
70
|
-
def from_grape_controller controller, method, pattern, url = nil
|
|
71
|
-
if pattern.cs__is_a?(Grape::Router::Route)
|
|
72
|
-
safe_pattern = pattern.pattern&.path&.to_s
|
|
73
|
-
safe_url = source_or_string(url || safe_pattern)
|
|
74
|
-
else
|
|
75
|
-
safe_pattern = source_or_string(pattern)
|
|
76
|
-
safe_url = source_or_string(url || pattern)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
msg = new
|
|
80
|
-
msg.route = "#{ controller }##{ method } #{ safe_pattern }"
|
|
81
|
-
msg.verb = Contrast::Utils::StringUtils.force_utf8(method)
|
|
82
|
-
msg.url = Contrast::Utils::StringUtils.force_utf8(safe_url)
|
|
83
|
-
msg
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
Contrast::Api::Dtm::RouteCoverage.include(Contrast::Api::Decorators::RouteCoverage)
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/utils/string_utils'
|
|
5
|
-
|
|
6
|
-
module Contrast
|
|
7
|
-
module Api
|
|
8
|
-
module Decorators
|
|
9
|
-
# Used to decorate the {Contrast::Api::Dtm::TraceEvent} protobuf model to
|
|
10
|
-
# convert our {Contrast::Agent::AssessContrastEvent} to the dtm.
|
|
11
|
-
module TraceEvent
|
|
12
|
-
def self.included klass
|
|
13
|
-
klass.extend(ClassMethods)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# The TeamServer uses the Event's type and action to render it in the Details page. These values control the
|
|
17
|
-
# left-hand "What happened" column and the data shown in the right-hand data
|
|
18
|
-
#
|
|
19
|
-
# @param contrast_event [Contrast::Agent::Assess::ContrastEvent]
|
|
20
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
21
|
-
def build_display_params! contrast_event
|
|
22
|
-
self.type = contrast_event.policy_node.node_type
|
|
23
|
-
self.action = contrast_event.policy_node.build_action
|
|
24
|
-
self
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# The TeamServer uses the Event's representation of the data to render the actual data used in the dataflow on
|
|
28
|
-
# the Details page.
|
|
29
|
-
#
|
|
30
|
-
# @param contrast_event [Contrast::Agent::Assess::ContrastEvent]
|
|
31
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
32
|
-
def build_dataflow! contrast_event
|
|
33
|
-
# Figure out what the target of this event was. This can't be pulled into the decorator because SourceEvent
|
|
34
|
-
# has a custom impl :/
|
|
35
|
-
taint_target = contrast_event.determine_taint_target(self)
|
|
36
|
-
truncate_obj = Contrast::Utils::ObjectShare::OBJECT_KEY != taint_target
|
|
37
|
-
self.object = Contrast::Api::Dtm::TraceEventObject.build(contrast_event.object, truncate_obj)
|
|
38
|
-
truncate_ret = Contrast::Utils::ObjectShare::RETURN_KEY != taint_target
|
|
39
|
-
self.ret = Contrast::Api::Dtm::TraceEventObject.build(contrast_event.ret, truncate_ret)
|
|
40
|
-
build_event_args!(contrast_event, taint_target)
|
|
41
|
-
build_taint_ranges!(contrast_event)
|
|
42
|
-
self
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Wrapper around build_event_object for the args array. Handles
|
|
46
|
-
# tainting the correct argument.
|
|
47
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
48
|
-
def build_event_args! contrast_event, taint_target
|
|
49
|
-
contrast_event.args.each_index do |idx|
|
|
50
|
-
truncate_arg = taint_target != idx
|
|
51
|
-
event_arg = Contrast::Api::Dtm::TraceEventObject.build(contrast_event.args[idx], truncate_arg)
|
|
52
|
-
args << event_arg
|
|
53
|
-
end
|
|
54
|
-
self
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# TeamServer only supports one object's taint ranges at a time. We keep
|
|
58
|
-
# those tags on the event directly, so we just need to convert them to
|
|
59
|
-
# their DTM form in order to report this.
|
|
60
|
-
#
|
|
61
|
-
# @param contrast_event [Contrast::Agent::AssessContrastEvent]
|
|
62
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
63
|
-
def build_taint_ranges! contrast_event
|
|
64
|
-
# If there's no taint_target, this isn't a dataflow trace, but a
|
|
65
|
-
# trigger one
|
|
66
|
-
return self unless contrast_event&.tags
|
|
67
|
-
|
|
68
|
-
self.taint_ranges += Contrast::Api::Dtm::TraceTaintRange.build_for_event(contrast_event.tags)
|
|
69
|
-
self
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# For each Parent in the ContrastEvent, capture its id and report it to TeamServer.
|
|
73
|
-
#
|
|
74
|
-
# @param contrast_event [Contrast::Agent::AssessContrastEvent]
|
|
75
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
76
|
-
def build_parent_ids! contrast_event
|
|
77
|
-
contrast_event&.parent_events&.each do |event|
|
|
78
|
-
next unless event
|
|
79
|
-
|
|
80
|
-
parent = Contrast::Api::Dtm::ParentObjectId.new
|
|
81
|
-
parent.id = event.event_id.to_i
|
|
82
|
-
parent_object_ids << parent
|
|
83
|
-
end
|
|
84
|
-
self
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Convert the caller into the Stack DTM TeamServer consumes
|
|
88
|
-
#
|
|
89
|
-
# @param contrast_event [Contrast::Agent::AssessContrastEvent]
|
|
90
|
-
# @return [Contrast::Api::Dtm::TraceEvent]
|
|
91
|
-
def build_stack! contrast_event
|
|
92
|
-
# We delayed doing this as long as possible b/c it's expensive
|
|
93
|
-
stack_dtms = Contrast::Utils::StackTraceUtils.build_assess_stack_array(contrast_event.stack_trace)
|
|
94
|
-
self.stack += stack_dtms
|
|
95
|
-
self
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Class methods for TraceEvent
|
|
99
|
-
module ClassMethods
|
|
100
|
-
def build contrast_event
|
|
101
|
-
event_dtm = new
|
|
102
|
-
event_dtm.build_display_params!(contrast_event)
|
|
103
|
-
event_dtm.build_dataflow!(contrast_event)
|
|
104
|
-
event_dtm.build_stack!(contrast_event)
|
|
105
|
-
event_dtm.timestamp_ms = contrast_event.time.to_i
|
|
106
|
-
event_dtm.thread = Contrast::Utils::StringUtils.force_utf8(contrast_event.thread)
|
|
107
|
-
event_dtm.build_parent_ids!(contrast_event)
|
|
108
|
-
event_dtm.object_id = contrast_event.event_id.to_i
|
|
109
|
-
event_dtm.signature = Contrast::Api::Dtm::TraceEventSignature.build(contrast_event.ret,
|
|
110
|
-
contrast_event.policy_node,
|
|
111
|
-
contrast_event.args)
|
|
112
|
-
event_dtm
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
Contrast::Api::Dtm::TraceEvent.include(Contrast::Api::Decorators::TraceEvent)
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/utils/string_utils'
|
|
5
|
-
require 'contrast/utils/assess/tracking_util'
|
|
6
|
-
require 'base64'
|
|
7
|
-
require 'contrast/components/scope'
|
|
8
|
-
|
|
9
|
-
module Contrast
|
|
10
|
-
module Api
|
|
11
|
-
module Decorators
|
|
12
|
-
# Used to decorate the {Contrast::Api::Dtm::TraceEventObject} protobuf
|
|
13
|
-
# model.
|
|
14
|
-
module TraceEventObject
|
|
15
|
-
def self.included klass
|
|
16
|
-
klass.extend(ClassMethods)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Class methods for TraceEventObject
|
|
20
|
-
module ClassMethods
|
|
21
|
-
include Contrast::Components::Scope::InstanceMethods
|
|
22
|
-
# Build the event object. We were originally going to include taint on
|
|
23
|
-
# each one, but TS doesn't accept / use that, so it is a waste of time.
|
|
24
|
-
#
|
|
25
|
-
# We'll truncate any object that isn't important to the taint ranges of
|
|
26
|
-
# this event, so that we don't murder TeamServer by, for instance,
|
|
27
|
-
# hypothetically sending the entire rendered HTML page >_> <_< >_>
|
|
28
|
-
ELLIPSIS = '...'
|
|
29
|
-
UNTRUNCATED_PORTION_LENGTH = 25
|
|
30
|
-
TRUNCATION_LENGTH = (UNTRUNCATED_PORTION_LENGTH * 2) + ELLIPSIS.length
|
|
31
|
-
|
|
32
|
-
# Convert the given Object into a Contrast::Api::Dtm::TraceEventObject
|
|
33
|
-
#
|
|
34
|
-
# @param contrast_object [Contrast::Agent::Assess::ContrastObject, nil]
|
|
35
|
-
# the thing to convert, if any
|
|
36
|
-
# @param truncate [Boolean] if the converted object can/should be
|
|
37
|
-
# truncated.
|
|
38
|
-
# @return [Contrast::Api::Dtm::TraceEventObject]
|
|
39
|
-
def build contrast_object, truncate
|
|
40
|
-
event_object = new
|
|
41
|
-
with_contrast_scope do
|
|
42
|
-
obj_string = Contrast::Utils::StringUtils.force_utf8(contrast_object&.object)
|
|
43
|
-
obj_string = truncate(obj_string) if truncate && obj_string.length > TRUNCATION_LENGTH
|
|
44
|
-
event_object.value = Base64.encode64(obj_string)
|
|
45
|
-
event_object.tracked = contrast_object&.tracked?
|
|
46
|
-
end
|
|
47
|
-
event_object
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def truncate obj_string
|
|
51
|
-
tmp = []
|
|
52
|
-
tmp << obj_string[0, UNTRUNCATED_PORTION_LENGTH]
|
|
53
|
-
tmp << ELLIPSIS
|
|
54
|
-
tmp << obj_string[obj_string.length - UNTRUNCATED_PORTION_LENGTH, UNTRUNCATED_PORTION_LENGTH]
|
|
55
|
-
tmp.join
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
Contrast::Api::Dtm::TraceEventObject.include(Contrast::Api::Decorators::TraceEventObject)
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/utils/string_utils'
|
|
5
|
-
require 'contrast/utils/assess/tracking_util'
|
|
6
|
-
require 'base64'
|
|
7
|
-
|
|
8
|
-
module Contrast
|
|
9
|
-
module Api
|
|
10
|
-
module Decorators
|
|
11
|
-
# Used to decorate the {Contrast::Api::Dtm::TraceEventSignature} protobuf
|
|
12
|
-
# model.
|
|
13
|
-
module TraceEventSignature
|
|
14
|
-
def self.included klass
|
|
15
|
-
klass.extend(ClassMethods)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Class methods for TraceEventSignature
|
|
19
|
-
module ClassMethods
|
|
20
|
-
# Convert the given composites into components that TeamServer can
|
|
21
|
-
# understand in order to build a representation of the method
|
|
22
|
-
# invoked.
|
|
23
|
-
#
|
|
24
|
-
# @param ret_obj [Contrast::Agent::Assess::ContrastObject, nil] the
|
|
25
|
-
# return value of the method call.
|
|
26
|
-
# @param policy_node [Contrast::Agent::Assess::Policy::PolicyNode]
|
|
27
|
-
# the policy which pertains to the method invoked.
|
|
28
|
-
# @param args [Array<Contrast::Agent::Assess::ContrastObject>, nil]
|
|
29
|
-
# @return [Contrast::Api::Dtm::TraceEventSignature]
|
|
30
|
-
def build ret_obj, policy_node, args
|
|
31
|
-
signature = new
|
|
32
|
-
signature.return_type = Contrast::Utils::StringUtils.force_utf8(type_name(ret_obj))
|
|
33
|
-
signature.class_name = Contrast::Utils::StringUtils.force_utf8(policy_node.class_name)
|
|
34
|
-
signature.method_name = Contrast::Utils::StringUtils.force_utf8(policy_node.method_name)
|
|
35
|
-
if args
|
|
36
|
-
args&.each do |arg|
|
|
37
|
-
signature.arg_types << Contrast::Utils::StringUtils.force_utf8(type_name(arg))
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
signature.constructor = policy_node.method_name == :new
|
|
41
|
-
# if there's a ret, then this method isn't nil. not 100% full proof since you can
|
|
42
|
-
# return nil, but this is the best we've got currently.
|
|
43
|
-
signature.void_method = ret_obj.nil? || ret_obj.object.nil?
|
|
44
|
-
# 8 is STATIC in Java... we have to placate them for now
|
|
45
|
-
# it has been requested that flags be removed since it isn't used
|
|
46
|
-
signature.flags = 8 unless policy_node.instance_method?
|
|
47
|
-
signature
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
# While Ruby signatures do not require neither a return type and can
|
|
53
|
-
# return anything depending on inputs, code paths, etc, nor constant
|
|
54
|
-
# parameter types, TeamServer was designed with strongly typed
|
|
55
|
-
# languages (Java) in mind, so we need types in our signatures.
|
|
56
|
-
#
|
|
57
|
-
# @param contrast_object [Contrast::Agent::Assess::ContrastObject, nil]
|
|
58
|
-
# the object to find the type of
|
|
59
|
-
# @return [String] the name of the module of the ret_obj, or `nil`
|
|
60
|
-
def type_name contrast_object
|
|
61
|
-
contrast_object ? contrast_object.object_type : Contrast::Utils::ObjectShare::NIL_STRING
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
Contrast::Api::Dtm::TraceEventSignature.include(Contrast::Api::Decorators::TraceEventSignature)
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 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/utils/string_utils'
|
|
6
|
-
|
|
7
|
-
module Contrast
|
|
8
|
-
module Api
|
|
9
|
-
module Decorators
|
|
10
|
-
# Used to decorate the {Contrast::Api::Dtm::TraceTaintRange} protobuf
|
|
11
|
-
# model.
|
|
12
|
-
module TraceTaintRange
|
|
13
|
-
def self.included klass
|
|
14
|
-
klass.extend(ClassMethods)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Class methods for TraceEventObject
|
|
18
|
-
module ClassMethods
|
|
19
|
-
# Convert the tags from Contrast::Agent::Assess::Property::Tagged to
|
|
20
|
-
# the form required for their Event's DTM.
|
|
21
|
-
#
|
|
22
|
-
# @param tags [Hash{String => Array<Contrast::Agent::Assess::Tag>}]
|
|
23
|
-
# @return [Array<Contrast::Api::Dtm::TraceTaintRange>]
|
|
24
|
-
def build_for_event tags
|
|
25
|
-
return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless tags&.any?
|
|
26
|
-
|
|
27
|
-
ranges = []
|
|
28
|
-
tags.each_value do |value|
|
|
29
|
-
next if value.empty?
|
|
30
|
-
|
|
31
|
-
value.each { |tag| ranges << build(tag) }
|
|
32
|
-
end
|
|
33
|
-
ranges
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Convert our Tags to their DTM equivalent
|
|
37
|
-
#
|
|
38
|
-
# @param tag [Contrast::Agent::Assess::Tag]
|
|
39
|
-
# @return [Contrast::Api::Dtm::TraceTaintRange]
|
|
40
|
-
def build tag
|
|
41
|
-
range = Contrast::Api::Dtm::TraceTaintRange.new
|
|
42
|
-
range.tag = Contrast::Utils::StringUtils.protobuf_safe_string(tag.label)
|
|
43
|
-
range.range = tag.start_idx.to_s + Contrast::Utils::ObjectShare::COLON + tag.end_idx.to_s
|
|
44
|
-
range
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
Contrast::Api::Dtm::TraceTaintRange.include(Contrast::Api::Decorators::TraceTaintRange)
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/components/sampling'
|
|
5
|
-
|
|
6
|
-
module Contrast
|
|
7
|
-
module Config
|
|
8
|
-
# Common Configuration settings. Those in this section pertain to the
|
|
9
|
-
# assess functionality of the Agent.
|
|
10
|
-
class AssessConfiguration
|
|
11
|
-
include Contrast::Config::BaseConfiguration
|
|
12
|
-
|
|
13
|
-
# @return [String, nil]
|
|
14
|
-
attr_accessor :tags
|
|
15
|
-
# @return [Boolean, nil]
|
|
16
|
-
attr_accessor :enable
|
|
17
|
-
attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces
|
|
18
|
-
|
|
19
|
-
DEFAULT_STACKTRACES = 'ALL'
|
|
20
|
-
DEFAULT_MAX_SOURCE_EVENTS = 50_000
|
|
21
|
-
DEFAULT_MAX_PROPAGATION_EVENTS = 50_000
|
|
22
|
-
DEFAULT_MAX_RULE_REPORTED = 100
|
|
23
|
-
DEFAULT_MAX_RULE_TIME_THRESHOLD = 300_000
|
|
24
|
-
|
|
25
|
-
def initialize hsh = {}
|
|
26
|
-
return unless hsh
|
|
27
|
-
|
|
28
|
-
@enable = hsh[:enable]
|
|
29
|
-
@tags = hsh[:tags]
|
|
30
|
-
@enable_scan_response = hsh[:enable_scan_response]
|
|
31
|
-
@enable_dynamic_sources = hsh[:enable_dynamic_sources]
|
|
32
|
-
@enable_original_object = hsh[:enable_original_object]
|
|
33
|
-
@sampling = Contrast::Components::Sampling::Interface.new(hsh[:sampling])
|
|
34
|
-
@rules = Contrast::Config::AssessRulesConfiguration.new(hsh[:rules])
|
|
35
|
-
@stacktraces = hsh[:stacktraces]
|
|
36
|
-
@max_context_source_events = hsh[:max_context_source_events]
|
|
37
|
-
@max_propagation_events = hsh[:max_propagation_events]
|
|
38
|
-
@max_rule_reported = hsh[:max_rule_reported]
|
|
39
|
-
@time_limit_threshold = hsh[:time_limit_threshold]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @return [Boolean, true]
|
|
43
|
-
def enable_scan_response
|
|
44
|
-
@enable_scan_response.nil? ? true : @enable_scan_response
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# @return [Boolean, true]
|
|
48
|
-
def enable_dynamic_sources
|
|
49
|
-
@enable_dynamic_sources.nil? ? true : @enable_dynamic_sources
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# @return [Boolean, true]
|
|
53
|
-
def enable_original_object
|
|
54
|
-
@enable_original_object.nil? ? true : @enable_original_object
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# @return [Contrast::Components::Sampling::Interface]
|
|
58
|
-
def sampling
|
|
59
|
-
@sampling ||= Contrast::Components::Sampling::Interface.new
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# @return [Contrast::Config::AssessRulesConfiguration]
|
|
63
|
-
def rules
|
|
64
|
-
@rules ||= Contrast::Config::AssessRulesConfiguration.new
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# @return [String] stacktrace level
|
|
68
|
-
def stacktraces
|
|
69
|
-
@stacktraces ||= DEFAULT_STACKTRACES
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# @return [int] max number of context source events in single request
|
|
73
|
-
def max_context_source_events
|
|
74
|
-
@max_context_source_events ||= DEFAULT_MAX_SOURCE_EVENTS
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# @return [int] max number of propagation events in single request
|
|
78
|
-
def max_propagation_events
|
|
79
|
-
@max_propagation_events ||= DEFAULT_MAX_PROPAGATION_EVENTS
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# @return [int] max number of rules reported within time_limit_threshold
|
|
83
|
-
def max_rule_reported
|
|
84
|
-
@max_rule_reported ||= DEFAULT_MAX_RULE_REPORTED
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# @return [int] max ms threshold for reporting rules
|
|
88
|
-
def time_limit_threshold
|
|
89
|
-
@time_limit_threshold ||= DEFAULT_MAX_RULE_TIME_THRESHOLD
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 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 Config
|
|
6
|
-
# Common Configuration settings. Those in this section pertain to the
|
|
7
|
-
# disabled assess rule functionality of the Agent.
|
|
8
|
-
class AssessRulesConfiguration
|
|
9
|
-
include Contrast::Config::BaseConfiguration
|
|
10
|
-
|
|
11
|
-
SPEC_KEY = :disabled_rules.cs__freeze
|
|
12
|
-
# @return [Array, nil] list of disabled assess rules
|
|
13
|
-
attr_accessor :disabled_rules
|
|
14
|
-
|
|
15
|
-
def initialize hsh = {}
|
|
16
|
-
return unless hsh
|
|
17
|
-
|
|
18
|
-
@disabled_rules = cast_disabled_rules(hsh)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def cast_disabled_rules hsh
|
|
24
|
-
return unless hsh
|
|
25
|
-
return unless hsh.key?(SPEC_KEY)
|
|
26
|
-
return hsh[SPEC_KEY] if hsh[SPEC_KEY].cs__is_a?(Array)
|
|
27
|
-
|
|
28
|
-
hsh[SPEC_KEY].split(',').map(&:strip) if hsh[SPEC_KEY].cs__is_a?(String)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'contrast/components/agent'
|
|
5
|
-
require 'contrast/components/inventory'
|
|
6
|
-
require 'contrast/components/protect'
|
|
7
|
-
require 'contrast/components/app_context'
|
|
8
|
-
|
|
9
|
-
module Contrast
|
|
10
|
-
module Config
|
|
11
|
-
# The base of the Common Configuration settings.
|
|
12
|
-
class RootConfiguration
|
|
13
|
-
include Contrast::Config::BaseConfiguration
|
|
14
|
-
|
|
15
|
-
# @return [Contrast::Components::Api::Interface]
|
|
16
|
-
attr_writer :api
|
|
17
|
-
# @return [Contrast::Components::Agent::Interface]
|
|
18
|
-
attr_writer :agent
|
|
19
|
-
# @return [Contrast::Components::AppContext::Interface]
|
|
20
|
-
attr_writer :application
|
|
21
|
-
# @return [Contrast::Config::ServerConfiguration]
|
|
22
|
-
attr_writer :server
|
|
23
|
-
# @return [Contrast::Config::AssessConfiguration]
|
|
24
|
-
attr_writer :assess
|
|
25
|
-
# @return [Contrast::Components::Inventory::Interface]
|
|
26
|
-
attr_writer :inventory
|
|
27
|
-
# @return [Contrast::Components::Protect::Interface]
|
|
28
|
-
attr_writer :protect
|
|
29
|
-
# @return [Contrast::Config::ServiceConfiguration]
|
|
30
|
-
attr_writer :service
|
|
31
|
-
# @return [Boolean, nil]
|
|
32
|
-
attr_accessor :enable
|
|
33
|
-
|
|
34
|
-
# @raise[ArgumentError]
|
|
35
|
-
def initialize hsh = {}
|
|
36
|
-
raise(ArgumentError, 'Expected a hash') unless hsh.is_a?(Hash)
|
|
37
|
-
|
|
38
|
-
@api = Contrast::Components::Api::Interface.new(hsh[:api])
|
|
39
|
-
@enable = hsh[:enable]
|
|
40
|
-
@agent = Contrast::Components::Agent::Interface.new(hsh[:agent])
|
|
41
|
-
@application = Contrast::Components::AppContext::Interface.new(hsh[:application])
|
|
42
|
-
@server = Contrast::Config::ServerConfiguration.new(hsh[:server])
|
|
43
|
-
@assess = Contrast::Config::AssessConfiguration.new(hsh[:assess])
|
|
44
|
-
@inventory = Contrast::Components::Inventory::Interface.new(hsh[:inventory])
|
|
45
|
-
@protect = Contrast::Components::Protect::Interface.new(hsh[:protect])
|
|
46
|
-
@service = Contrast::Config::ServiceConfiguration.new(hsh[:service])
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# @return [Contrast::Components::Api::Interface]
|
|
50
|
-
def api
|
|
51
|
-
@api ||= Contrast::Components::Api::Interface.new
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# @return [Contrast::Components::Agent::Interface]
|
|
55
|
-
def agent
|
|
56
|
-
@agent ||= Contrast::Components::Agent::Interface.new
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# @return [Contrast::Components::AppContext::Interface]
|
|
60
|
-
def application
|
|
61
|
-
@application ||= Contrast::Components::AppContext::Interface.new
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# @return [Contrast::Config::ServerConfiguration]
|
|
65
|
-
def server
|
|
66
|
-
@server ||= Contrast::Config::ServerConfiguration.new
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# @return [Contrast::Config::AssessConfiguration]
|
|
70
|
-
def assess
|
|
71
|
-
@assess ||= Contrast::Config::AssessConfiguration.new
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# @return [Contrast::Components::Inventory::Interface]
|
|
75
|
-
def inventory
|
|
76
|
-
@inventory ||= Contrast::Components::Inventory::Interface.new
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# @return [Contrast::Components::Protect::Interface]
|
|
80
|
-
def protect
|
|
81
|
-
@protect ||= Contrast::Components::Protect::Interface.new
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# @return [Contrast::Config::ServiceConfiguration]
|
|
85
|
-
def service
|
|
86
|
-
@service ||= Contrast::Config::ServiceConfiguration.new
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|