contrast-agent 6.8.0 → 6.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
- data/lib/contrast/agent/assess/property/evented.rb +11 -11
- data/lib/contrast/agent/assess.rb +0 -1
- data/lib/contrast/agent/excluder.rb +1 -1
- data/lib/contrast/agent/middleware.rb +8 -2
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +116 -0
- data/lib/contrast/agent/protect/rule/base.rb +2 -2
- data/lib/contrast/agent/protect/rule/bot_blocker.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +8 -7
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +0 -5
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +0 -5
- data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -3
- data/lib/contrast/agent/protect/rule/sqli.rb +4 -3
- data/lib/contrast/agent/protect/rule/xss.rb +1 -0
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +1 -1
- data/lib/contrast/agent/reporting/report.rb +1 -0
- data/lib/contrast/agent/reporting/reporter.rb +34 -0
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +3 -9
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +12 -7
- data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -1
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +2 -2
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +239 -93
- data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -23
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +10 -9
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -0
- data/lib/contrast/agent/reporting/reporting_events/server_reporting_event.rb +8 -0
- data/lib/contrast/agent/reporting/reporting_events/server_settings.rb +40 -0
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +6 -0
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +43 -1
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +8 -4
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +58 -4
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +4 -3
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +76 -16
- data/lib/contrast/agent/reporting/server_settings_worker.rb +44 -0
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +14 -2
- data/lib/contrast/agent/reporting/settings/helpers.rb +7 -0
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +39 -2
- data/lib/contrast/agent/reporting/settings/rule_definition.rb +3 -0
- data/lib/contrast/agent/reporting/settings/security_logger.rb +77 -0
- data/lib/contrast/agent/reporting/settings/server_features.rb +9 -0
- data/lib/contrast/agent/reporting/settings/syslog.rb +34 -5
- data/lib/contrast/agent/request.rb +1 -0
- data/lib/contrast/agent/request_handler.rb +5 -10
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +1 -1
- data/lib/contrast/agent/thread_watcher.rb +35 -1
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +6 -0
- data/lib/contrast/api/communication/connection_status.rb +15 -0
- data/lib/contrast/components/agent.rb +34 -0
- data/lib/contrast/components/api.rb +23 -0
- data/lib/contrast/components/app_context.rb +23 -3
- data/lib/contrast/components/assess.rb +34 -4
- data/lib/contrast/components/assess_rules.rb +18 -0
- data/lib/contrast/components/base.rb +40 -0
- data/lib/contrast/components/config/sources.rb +95 -0
- data/lib/contrast/components/config.rb +18 -1
- data/lib/contrast/components/heap_dump.rb +10 -0
- data/lib/contrast/components/inventory.rb +15 -2
- data/lib/contrast/components/logger.rb +18 -0
- data/lib/contrast/components/polling.rb +36 -0
- data/lib/contrast/components/protect.rb +48 -1
- data/lib/contrast/components/ruby_component.rb +15 -0
- data/lib/contrast/components/sampling.rb +70 -13
- data/lib/contrast/components/security_logger.rb +13 -0
- data/lib/contrast/components/settings.rb +74 -7
- data/lib/contrast/config/certification_configuration.rb +14 -0
- data/lib/contrast/config/config.rb +46 -0
- data/lib/contrast/config/diagnostics.rb +114 -0
- data/lib/contrast/config/diagnostics_tools.rb +98 -0
- data/lib/contrast/config/effective_config.rb +65 -0
- data/lib/contrast/config/effective_config_value.rb +32 -0
- data/lib/contrast/config/exception_configuration.rb +12 -0
- data/lib/contrast/config/protect_rule_configuration.rb +1 -1
- data/lib/contrast/config/protect_rules_configuration.rb +8 -7
- data/lib/contrast/config/request_audit_configuration.rb +13 -0
- data/lib/contrast/config/server_configuration.rb +41 -2
- data/lib/contrast/configuration.rb +28 -2
- data/lib/contrast/extension/assess/erb.rb +1 -1
- data/lib/contrast/utils/assess/event_limit_utils.rb +31 -9
- data/lib/contrast/utils/assess/trigger_method_utils.rb +5 -4
- data/lib/contrast/utils/hash_digest.rb +2 -2
- data/lib/contrast/utils/input_classification_base.rb +1 -2
- data/lib/contrast/utils/reporting/application_activity_batch_utils.rb +81 -0
- data/lib/contrast/utils/routes_sent.rb +60 -0
- data/lib/contrast/utils/telemetry_client.rb +1 -2
- data/lib/contrast/utils/timer.rb +16 -0
- data/lib/contrast.rb +3 -1
- data/ruby-agent.gemspec +5 -1
- metadata +29 -20
- data/lib/contrast/agent/assess/contrast_event.rb +0 -157
- data/lib/contrast/agent/assess/events/event_factory.rb +0 -34
- data/lib/contrast/agent/assess/events/source_event.rb +0 -46
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -36
@@ -1,157 +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/assess/tracking_util'
|
5
|
-
require 'contrast/utils/class_util'
|
6
|
-
require 'contrast/utils/duck_utils'
|
7
|
-
require 'contrast/utils/object_share'
|
8
|
-
require 'contrast/utils/stack_trace_utils'
|
9
|
-
require 'contrast/utils/string_utils'
|
10
|
-
require 'contrast/utils/timer'
|
11
|
-
require 'contrast/agent/assess/contrast_object'
|
12
|
-
require 'contrast/agent/reporting/reporting_events/finding_event'
|
13
|
-
|
14
|
-
module Contrast
|
15
|
-
module Agent
|
16
|
-
module Assess
|
17
|
-
# This class holds the data about an event in the application We'll use it to build an event that TeamServer can
|
18
|
-
# consume if the object to which this event belongs ends in a trigger.
|
19
|
-
class ContrastEvent
|
20
|
-
# @return [Integer] the atomic id of this event
|
21
|
-
attr_reader :event_id
|
22
|
-
# @return [Contrast::Agent::Assess::Policy::PolicyNode] the node that governs this event.
|
23
|
-
attr_reader :policy_node
|
24
|
-
# @return [Array<String>] the execution stack at the time the method for this event was invoked
|
25
|
-
attr_reader :stack_trace
|
26
|
-
# @return [Integer] the time, in epoch ms, when this event was created
|
27
|
-
attr_reader :time
|
28
|
-
# @return [Integer] the object id of the thread on which this event was generated
|
29
|
-
attr_reader :thread
|
30
|
-
# @return [Contrast::Agent::Assess::ContrastObject] the safe representation of the Object on which the method
|
31
|
-
# was invoked
|
32
|
-
attr_reader :object
|
33
|
-
# @return [Contrast::Agent::Assess::ContrastObject] the safe representation of the Return of the invoked method
|
34
|
-
attr_reader :ret
|
35
|
-
# @return [Array<Contrast::Agent::Assess::ContrastObject, nil>] the safe representation of the Arguments with
|
36
|
-
# which the method was invoked
|
37
|
-
attr_reader :args
|
38
|
-
# @return [Hash<Contrast::Agent::Assess::Tag>]
|
39
|
-
attr_reader :tags
|
40
|
-
|
41
|
-
# We need this to track the parent id's of events to build up a flow chart of the finding
|
42
|
-
@atomic_id = 0
|
43
|
-
@atomic_mutex = Mutex.new
|
44
|
-
def self.next_atomic_id
|
45
|
-
@atomic_mutex.synchronize do
|
46
|
-
@atomic_id += 1
|
47
|
-
# Rollover things
|
48
|
-
rescue StandardError
|
49
|
-
@atomic_id = 1
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# @param event_data [Contrast::Agent::Assess::Events::EventData]
|
54
|
-
def initialize event_data
|
55
|
-
@policy_node = event_data.policy_node
|
56
|
-
@time = Contrast::Utils::Timer.now_ms
|
57
|
-
@thread = Thread.current.object_id
|
58
|
-
|
59
|
-
# These methods rely on the above being set. Don't move them!
|
60
|
-
@event_id = Contrast::Agent::Assess::ContrastEvent.next_atomic_id
|
61
|
-
@tags = Contrast::Agent::Assess::Tracker.properties(event_data.tagged)&.get_tags
|
62
|
-
find_parent_events!(event_data.policy_node, event_data.object, event_data.ret, event_data.args)
|
63
|
-
snapshot!(event_data.object, event_data.ret, event_data.args)
|
64
|
-
capture_stacktrace!
|
65
|
-
end
|
66
|
-
|
67
|
-
# @return [Array<Contrast::Agent::Assess::ContrastEvent>]
|
68
|
-
def parent_events
|
69
|
-
@_parent_events ||= []
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
# Parent events are the events of all the sources of this event which were tracked prior to this event
|
75
|
-
# occurring. Depending on which, if any of the sources were tracked, there may be more than one parent.
|
76
|
-
#
|
77
|
-
# All events except for [Contrast::Agent::Assess::Events::SourceEvent] will have at least one parent.
|
78
|
-
#
|
79
|
-
# We set those events to this event's instance variables.
|
80
|
-
#
|
81
|
-
# @param policy_node [Contrast::Agent::Assess::Policy::PolicyNode] the node that governs this event.
|
82
|
-
# @param object [Object] the Object on which the method was invoked
|
83
|
-
# @param ret [Object] the Return of the invoked method
|
84
|
-
# @param args [Array<Object>] the Arguments with which the method was invoked
|
85
|
-
def find_parent_events! policy_node, object, ret, args
|
86
|
-
policy_node.sources.each do |source_marker|
|
87
|
-
source = value_of_source(source_marker, object, ret, args)
|
88
|
-
next unless source
|
89
|
-
|
90
|
-
event = Contrast::Agent::Assess::Tracker.properties(source)&.event
|
91
|
-
parent_events << event if event
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# @param source [String] the marker for the source type
|
96
|
-
# @param object [Object] the Object on which the method was invoked
|
97
|
-
# @param ret [Object] the Return of the invoked method
|
98
|
-
# @param args [Array<Object>] the Arguments with which the method was invoked
|
99
|
-
# @return [Object,nil] the literal value of the source indicated by the given marker
|
100
|
-
def value_of_source source, object, ret, args
|
101
|
-
case source
|
102
|
-
when Contrast::Utils::ObjectShare::OBJECT_KEY
|
103
|
-
object
|
104
|
-
when Contrast::Utils::ObjectShare::RETURN_KEY
|
105
|
-
ret
|
106
|
-
else
|
107
|
-
args[source]
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# Everything* is mutable in Ruby. As such, to ensure we can accurately report the application state at the time
|
112
|
-
# of this method's invocation, we have to snapshot the given values, making safe representations of them for
|
113
|
-
# our later use. We set those safe values to this event's instance variables.
|
114
|
-
#
|
115
|
-
# @param object [Object] the Object on which the method was invoked
|
116
|
-
# @param ret [Object] the Return of the invoked method
|
117
|
-
# @param args [Array<Object>] the Arguments with which the method was invoked
|
118
|
-
def snapshot! object, ret, args
|
119
|
-
@object = Contrast::Agent::Assess::ContrastObject.new(object) if object
|
120
|
-
@ret = Contrast::Agent::Assess::ContrastObject.new(ret) if ret
|
121
|
-
@args = safe_args_representation(args)
|
122
|
-
self
|
123
|
-
end
|
124
|
-
|
125
|
-
# Given an array of arguments, copy them into a safe, meaning String, format that we can use to send to SR and
|
126
|
-
# TS for rendering.
|
127
|
-
#
|
128
|
-
# @param args [Array<Object>] the arguments to translate
|
129
|
-
# @return [Array<Contrast::Agent::Assess::ContrastObject>] the String forms of those Objects, as determined by
|
130
|
-
# Contrast::Utils::ClassUtil.to_contrast_string
|
131
|
-
def safe_args_representation args
|
132
|
-
return unless args
|
133
|
-
return Contrast::Utils::ObjectShare::EMPTY_ARRAY if args.empty?
|
134
|
-
|
135
|
-
args.map { |arg| arg ? Contrast::Agent::Assess::ContrastObject.new(arg) : nil }
|
136
|
-
end
|
137
|
-
|
138
|
-
# Capture stack traces only as configured. We'll use this to grab the start of the call stack as if the
|
139
|
-
# instrumented method were the caller. This means we'll start at the entry just after the first block of
|
140
|
-
# Contrast code.
|
141
|
-
def capture_stacktrace!
|
142
|
-
# If we're configured to not capture the stacktrace, usually for performance reasons, then don't and return an
|
143
|
-
# empty array instead
|
144
|
-
unless ::Contrast::ASSESS.capture_stacktrace?(policy_node)
|
145
|
-
@stack_trace = Contrast::Utils::ObjectShare::EMPTY_ARRAY
|
146
|
-
return
|
147
|
-
end
|
148
|
-
|
149
|
-
# Otherwise, find where in the stack the application / Ruby code starts
|
150
|
-
start = caller(0, 20)&.find_index { |stack| !stack.include?('/lib/contrast') }
|
151
|
-
# And then use that to build out the reported stacktrace, or a fallback if we couldn't find it.
|
152
|
-
@stack_trace = start ? caller(start + 1, 20) : caller(20, 20)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
@@ -1,34 +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/agent/assess/contrast_event'
|
5
|
-
require 'contrast/agent/assess/events/source_event'
|
6
|
-
require 'contrast/agent/assess/events/event_data'
|
7
|
-
|
8
|
-
module Contrast
|
9
|
-
module Agent
|
10
|
-
module Assess
|
11
|
-
module Events
|
12
|
-
# This module returns the event type appropriate to the given Node
|
13
|
-
module EventFactory
|
14
|
-
# This method returns the event type appropriate to the given Node
|
15
|
-
#
|
16
|
-
# @param event_data [Contrast::Agent::Assess::Events::EventData]
|
17
|
-
# @param source_type [String] the type of this source, from the
|
18
|
-
# source_node, or a KEY_TYPE if invoked for a map,
|
19
|
-
# @param source_name [String, nil] the name of this source, i.e.
|
20
|
-
# the key used to accessed if from a map or nil if a type like,
|
21
|
-
# @return [Contrast::Agent::Assess::Events::SourceEvent, Contrast::Agent::Assess::ContrastEvent]
|
22
|
-
def self.build event_data, source_type = nil, source_name = nil
|
23
|
-
case event_data.policy_node
|
24
|
-
when Contrast::Agent::Assess::Policy::SourceNode
|
25
|
-
Contrast::Agent::Assess::Events::SourceEvent.new(event_data, source_type, source_name)
|
26
|
-
when Contrast::Agent::Assess::Policy::PolicyNode
|
27
|
-
Contrast::Agent::Assess::ContrastEvent.new(event_data)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,46 +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/agent/assess/contrast_event'
|
5
|
-
require 'contrast/agent/reporting/reporting_events/finding_event'
|
6
|
-
require 'contrast/agent/reporting/reporting_events/finding_event_source'
|
7
|
-
require 'contrast/utils/string_utils'
|
8
|
-
|
9
|
-
module Contrast
|
10
|
-
module Agent
|
11
|
-
module Assess
|
12
|
-
module Events
|
13
|
-
# This class holds the data about an event in the application. We'll use it to build an event that TeamServer
|
14
|
-
# can consume if the object to which this event belongs ends in a trigger.
|
15
|
-
class SourceEvent < Contrast::Agent::Assess::ContrastEvent
|
16
|
-
# @return [Contrast::Agent::Request] our wrapper around the Rack::Request at the time this source
|
17
|
-
# was created
|
18
|
-
attr_reader :request
|
19
|
-
# @return [String] the name of the source if it comes from a map-like entity
|
20
|
-
attr_reader :source_name
|
21
|
-
# @return [String] the TeamServer understood type of source; i.e. parameter
|
22
|
-
attr_reader :source_type
|
23
|
-
# @return [Contrast::Agent::Reporting::FindingEventSource] the source of this trace
|
24
|
-
attr_reader :event_source
|
25
|
-
|
26
|
-
# @param event_data [Contrast::Agent::Assess::Events::EventData]
|
27
|
-
# @param source_type [String] the type of this source, from the source_node, or a KEY_TYPE if invoked for a
|
28
|
-
# Hash
|
29
|
-
# @param source_name [String, nil] the name of this source, i.e. the key used to accessed if from a Hash or
|
30
|
-
# nil if a type like
|
31
|
-
def initialize event_data, source_type = nil, source_name = nil
|
32
|
-
super(event_data)
|
33
|
-
@source_type = Contrast::Utils::StringUtils.force_utf8(source_type)
|
34
|
-
@source_name = Contrast::Utils::StringUtils.force_utf8(source_name)
|
35
|
-
@event_source = Contrast::Agent::Reporting::FindingEventSource.new(@source_type, @source_name)
|
36
|
-
@request = Contrast::Agent::REQUEST_TRACKER.current&.request
|
37
|
-
end
|
38
|
-
|
39
|
-
def parent_events
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,36 +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/agent/reporting/reporting_events/server_reporting_event'
|
5
|
-
|
6
|
-
module Contrast
|
7
|
-
module Agent
|
8
|
-
module Reporting
|
9
|
-
# This class will initialize empty ServerActivity body to be send to TS. The server activity endpoint records
|
10
|
-
# actions taken on the server or process as a whole. It currently only reports the number of times a defensive
|
11
|
-
# action was taken and is most likely not populated by most agents. The main purpose of sending this message is
|
12
|
-
# for its response, which contains any updated server feature settings from TeamServer. The new Server Settings
|
13
|
-
# endpoint should let us remove this.
|
14
|
-
class ServerActivity < Contrast::Agent::Reporting::ServerReportingEvent
|
15
|
-
def initialize
|
16
|
-
@event_method = :PUT
|
17
|
-
@event_endpoint = "#{ Contrast::API.api_url }/api/ng/activity/server"
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def file_name
|
22
|
-
'server-activity'
|
23
|
-
end
|
24
|
-
|
25
|
-
# Convert the instance variables on the class, and other information, into the identifiers required for
|
26
|
-
# TeamServer to process the JSON form of this message.
|
27
|
-
#
|
28
|
-
# @return [Hash]
|
29
|
-
# @raise [ArgumentError]
|
30
|
-
def to_controlled_hash
|
31
|
-
{ lastUpdate: since_last_update }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|