contrast-agent 6.8.0 → 6.9.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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
  3. data/lib/contrast/agent/assess/property/evented.rb +11 -11
  4. data/lib/contrast/agent/assess.rb +0 -1
  5. data/lib/contrast/agent/excluder.rb +1 -1
  6. data/lib/contrast/agent/middleware.rb +8 -2
  7. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +116 -0
  8. data/lib/contrast/agent/protect/rule/base.rb +2 -2
  9. data/lib/contrast/agent/protect/rule/bot_blocker.rb +1 -1
  10. data/lib/contrast/agent/protect/rule/cmd_injection.rb +8 -7
  11. data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +0 -5
  12. data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +0 -5
  13. data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -3
  14. data/lib/contrast/agent/protect/rule/sqli.rb +4 -3
  15. data/lib/contrast/agent/protect/rule/xss.rb +1 -0
  16. data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +1 -1
  17. data/lib/contrast/agent/reporting/report.rb +1 -0
  18. data/lib/contrast/agent/reporting/reporter.rb +34 -0
  19. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +3 -9
  20. data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -1
  21. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +12 -7
  22. data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -1
  23. data/lib/contrast/agent/reporting/reporting_events/finding.rb +2 -2
  24. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +239 -93
  25. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -23
  26. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +10 -9
  27. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -0
  28. data/lib/contrast/agent/reporting/reporting_events/server_reporting_event.rb +8 -0
  29. data/lib/contrast/agent/reporting/reporting_events/server_settings.rb +40 -0
  30. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +6 -0
  31. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +43 -1
  32. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +8 -4
  33. data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +58 -4
  34. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +4 -3
  35. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +76 -16
  36. data/lib/contrast/agent/reporting/server_settings_worker.rb +44 -0
  37. data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +14 -2
  38. data/lib/contrast/agent/reporting/settings/helpers.rb +7 -0
  39. data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +39 -2
  40. data/lib/contrast/agent/reporting/settings/rule_definition.rb +3 -0
  41. data/lib/contrast/agent/reporting/settings/security_logger.rb +77 -0
  42. data/lib/contrast/agent/reporting/settings/server_features.rb +9 -0
  43. data/lib/contrast/agent/reporting/settings/syslog.rb +34 -5
  44. data/lib/contrast/agent/request.rb +1 -0
  45. data/lib/contrast/agent/request_handler.rb +5 -10
  46. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +1 -1
  47. data/lib/contrast/agent/thread_watcher.rb +35 -1
  48. data/lib/contrast/agent/version.rb +1 -1
  49. data/lib/contrast/agent.rb +6 -0
  50. data/lib/contrast/api/communication/connection_status.rb +15 -0
  51. data/lib/contrast/components/agent.rb +34 -0
  52. data/lib/contrast/components/api.rb +23 -0
  53. data/lib/contrast/components/app_context.rb +23 -3
  54. data/lib/contrast/components/assess.rb +34 -4
  55. data/lib/contrast/components/assess_rules.rb +18 -0
  56. data/lib/contrast/components/base.rb +40 -0
  57. data/lib/contrast/components/config/sources.rb +95 -0
  58. data/lib/contrast/components/config.rb +18 -1
  59. data/lib/contrast/components/heap_dump.rb +10 -0
  60. data/lib/contrast/components/inventory.rb +15 -2
  61. data/lib/contrast/components/logger.rb +18 -0
  62. data/lib/contrast/components/polling.rb +36 -0
  63. data/lib/contrast/components/protect.rb +48 -1
  64. data/lib/contrast/components/ruby_component.rb +15 -0
  65. data/lib/contrast/components/sampling.rb +70 -13
  66. data/lib/contrast/components/security_logger.rb +13 -0
  67. data/lib/contrast/components/settings.rb +74 -7
  68. data/lib/contrast/config/certification_configuration.rb +14 -0
  69. data/lib/contrast/config/config.rb +46 -0
  70. data/lib/contrast/config/diagnostics.rb +114 -0
  71. data/lib/contrast/config/diagnostics_tools.rb +98 -0
  72. data/lib/contrast/config/effective_config.rb +65 -0
  73. data/lib/contrast/config/effective_config_value.rb +32 -0
  74. data/lib/contrast/config/exception_configuration.rb +12 -0
  75. data/lib/contrast/config/protect_rule_configuration.rb +1 -1
  76. data/lib/contrast/config/protect_rules_configuration.rb +8 -7
  77. data/lib/contrast/config/request_audit_configuration.rb +13 -0
  78. data/lib/contrast/config/server_configuration.rb +41 -2
  79. data/lib/contrast/configuration.rb +28 -2
  80. data/lib/contrast/extension/assess/erb.rb +1 -1
  81. data/lib/contrast/utils/assess/event_limit_utils.rb +31 -9
  82. data/lib/contrast/utils/assess/trigger_method_utils.rb +5 -4
  83. data/lib/contrast/utils/hash_digest.rb +2 -2
  84. data/lib/contrast/utils/input_classification_base.rb +1 -2
  85. data/lib/contrast/utils/reporting/application_activity_batch_utils.rb +81 -0
  86. data/lib/contrast/utils/routes_sent.rb +60 -0
  87. data/lib/contrast/utils/telemetry_client.rb +1 -2
  88. data/lib/contrast/utils/timer.rb +16 -0
  89. data/lib/contrast.rb +3 -1
  90. data/ruby-agent.gemspec +5 -1
  91. metadata +29 -20
  92. data/lib/contrast/agent/assess/contrast_event.rb +0 -157
  93. data/lib/contrast/agent/assess/events/event_factory.rb +0 -34
  94. data/lib/contrast/agent/assess/events/source_event.rb +0 -46
  95. 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