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.
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