contrast-agent 7.1.0 → 7.2.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/ext/extconf_common.rb +88 -14
  3. data/lib/contrast/agent/assess/policy/source_method.rb +13 -4
  4. data/lib/contrast/agent/assess/policy/trigger_method.rb +12 -18
  5. data/lib/contrast/agent/excluder/excluder.rb +64 -31
  6. data/lib/contrast/agent/protect/rule/base.rb +4 -6
  7. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker.rb +1 -1
  8. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +2 -2
  9. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +1 -1
  10. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
  11. data/lib/contrast/agent/protect/rule/deserialization/deserialization.rb +2 -2
  12. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +1 -1
  13. data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +1 -1
  14. data/lib/contrast/agent/protect/rule/utils/filters.rb +6 -6
  15. data/lib/contrast/agent/protect/rule/xxe/xxe.rb +1 -1
  16. data/lib/contrast/agent/reporting/client/interface.rb +132 -0
  17. data/lib/contrast/agent/reporting/client/interface_base.rb +27 -0
  18. data/lib/contrast/agent/reporting/connection_status.rb +0 -1
  19. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +6 -4
  20. data/lib/contrast/agent/reporting/reporter.rb +11 -26
  21. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
  22. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
  23. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +47 -6
  24. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +40 -31
  25. data/lib/contrast/agent/reporting/reporting_utilities/resend.rb +144 -0
  26. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +35 -13
  27. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +14 -1
  28. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +11 -11
  29. data/lib/contrast/agent/request/request.rb +27 -12
  30. data/lib/contrast/agent/telemetry/base.rb +18 -19
  31. data/lib/contrast/agent/telemetry/exception/obfuscate.rb +97 -0
  32. data/lib/contrast/agent/telemetry/exception.rb +1 -0
  33. data/lib/contrast/agent/version.rb +1 -1
  34. data/lib/contrast/components/config/sources.rb +6 -5
  35. data/lib/contrast/components/settings.rb +9 -0
  36. data/lib/contrast/config/diagnostics/source_config_value.rb +5 -1
  37. data/lib/contrast/config/diagnostics/tools.rb +4 -4
  38. data/lib/contrast/config/validate.rb +2 -2
  39. data/lib/contrast/configuration.rb +11 -19
  40. data/lib/contrast/framework/grape/support.rb +1 -2
  41. data/lib/contrast/framework/manager.rb +17 -8
  42. data/lib/contrast/framework/rack/support.rb +99 -1
  43. data/lib/contrast/framework/rails/support.rb +1 -2
  44. data/lib/contrast/framework/sinatra/support.rb +1 -2
  45. data/lib/contrast/logger/aliased_logging.rb +18 -9
  46. data/lib/contrast/utils/hash_utils.rb +21 -2
  47. data/lib/contrast/utils/request_utils.rb +14 -0
  48. data/resources/assess/policy.json +11 -0
  49. metadata +6 -3
  50. data/lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb +0 -27
@@ -0,0 +1,132 @@
1
+ # Copyright (c) 2023 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/client/interface_base'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Client
10
+ # Interface to safely manage connections across threads.
11
+ class Interface < Contrast::Agent::Reporting::Client::InterfaceBase
12
+ # Execute startup routine and
13
+ def startup
14
+ with_monitor { reporter_client.startup!(reporting_connection) }
15
+ end
16
+
17
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
18
+ # @return [Net::HTTPResponse]
19
+ def send_event event
20
+ with_monitor { reporter_client.send_event(event, reporting_connection) }
21
+ end
22
+
23
+ # return [Boolean]
24
+ def sleep?
25
+ with_monitor { reporter_client.sleep? }
26
+ end
27
+
28
+ # Retry once than discard the event. This is trigger on too many events of
29
+ # same kind error.
30
+ #
31
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
32
+ def handle_resend event
33
+ with_monitor do
34
+ reporter_client.handle_resend(event, reporting_connection)
35
+ end
36
+ end
37
+
38
+ # Check to see if client exists and there is connection
39
+ #
40
+ # @return [Boolean
41
+ def connected?
42
+ with_monitor do
43
+ return true if reporter_client && reporting_connection
44
+
45
+ false
46
+ end
47
+ end
48
+
49
+ # Check to see if statup connections are sent or not
50
+ def startup_messages_sent?
51
+ with_monitor { reporter_client.status.startup_messages_sent? }
52
+ end
53
+
54
+ # Check to see if event need to be resend
55
+ #
56
+ # @return [Boolean, nil]
57
+ def resending?
58
+ with_monitor { reporter_client.mode.status == reporter_client.mode.resending }
59
+ end
60
+
61
+ # Return timeout in ms
62
+ def timeout
63
+ with_monitor { reporter_client.timeout } || Contrast::Agent::Reporting::ResponseHandler::TIMEOUT
64
+ end
65
+
66
+ # @return headers [Contrast::Agent::Reporting::Headers]
67
+ def headers
68
+ with_monitor { reporter_client.headers }
69
+ end
70
+
71
+ # Response_handler
72
+ #
73
+ # @return [Contrast::Agent::Reporting::ResponseHandler]
74
+ def response_handler
75
+ with_monitor { reporter_client.response_handler }
76
+ end
77
+
78
+ def status
79
+ with_monitor { reporter_client.status }
80
+ end
81
+
82
+ private
83
+
84
+ # @return [Contrast::Agent::Reporting::ReporterClient]
85
+ def reporter_client
86
+ @_reporter_client ||= Contrast::Agent::Reporting::ReporterClient.new
87
+ end
88
+
89
+ # @return [Net::HTTP, nil] Return open connection or nil
90
+ def reporting_connection
91
+ @_reporting_connection ||= reporter_client.initialize_connection
92
+ end
93
+ end
94
+ end
95
+
96
+ module Telemetry
97
+ # Interface to safely manage connections across threads.
98
+ class Interface < Contrast::Agent::Reporting::Client::InterfaceBase
99
+ URL = 'https://telemetry.ruby.contrastsecurity.com/'
100
+
101
+ # Check to see if client exists and there is connection
102
+ #
103
+ # @return [Boolean
104
+ def connected?
105
+ with_monitor do
106
+ return true if telemetry_client && telemetry_connection
107
+
108
+ false
109
+ end
110
+ end
111
+
112
+ # Starts telemetry request.
113
+ def request_with_response event
114
+ with_monitor do
115
+ telemetry_client.handle_response(telemetry_client.send_request(event, telemetry_connection))
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def telemetry_client
122
+ @_telemetry_client ||= Contrast::Agent::Telemetry::Client.new
123
+ end
124
+
125
+ def telemetry_connection
126
+ @_telemetry_connection ||= telemetry_client.initialize_connection(URL)
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'monitor'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Client
10
+ # Common methods for Client interface.
11
+ class InterfaceBase
12
+ # Execute calls to connection with thread safety.
13
+ def with_monitor &block
14
+ monitor.synchronize(&block)
15
+ end
16
+
17
+ private
18
+
19
+ # @return [Monitor]
20
+ def monitor
21
+ @_monitor ||= Monitor.new
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -10,7 +10,6 @@ module Contrast
10
10
  @last_success = nil
11
11
  @last_failure = nil
12
12
  @startup_messages_sent = false
13
- @_startup_server_message_sent = false
14
13
  end
15
14
 
16
15
  # Whether we have sent startup message to TeamServer. True after successfully sending startup messages to
@@ -4,7 +4,7 @@
4
4
  require 'contrast/utils/object_share'
5
5
  require 'contrast/agent/reporting/input_analysis/input_type'
6
6
  require 'contrast/agent/reporting/input_analysis/score_level'
7
- require 'contrast/agent/reporting/input_analysis/details/protect_rule_details'
7
+ require 'contrast/agent/reporting/details/protect_rule_details'
8
8
 
9
9
  module Contrast
10
10
  module Agent
@@ -112,14 +112,16 @@ module Contrast
112
112
 
113
113
  # Additional per rule details containing more specific info.
114
114
  #
115
- # @param protect_rule_details [Contrast::Agent::Reporting::ProtectRuleDetails]
115
+ # @param protect_rule_details [Contrast::Agent::Reporting::Details::ProtectRuleDetails]
116
116
  def details= protect_rule_details
117
- @_details = protect_rule_details if protect_rule_details.is_a?(Contrast::Agent::Reporting::ProtectRuleDetails)
117
+ return unless protect_rule_details.is_a?(Contrast::Agent::Reporting::Details::ProtectRuleDetails)
118
+
119
+ @_details = protect_rule_details
118
120
  end
119
121
 
120
122
  # Additional per rule details containing more specific info.
121
123
  #
122
- # @return [Contrast::Agent::Reporting::ProtectRuleDetails, nil]
124
+ # @return [Contrast::Agent::Reporting::Details::ProtectRuleDetails, nil]
123
125
  def details
124
126
  @_details
125
127
  end
@@ -6,6 +6,7 @@ require 'contrast/agent/reporting/report'
6
6
  require 'contrast/components/logger'
7
7
  require 'contrast/agent/reporting/reporting_events/agent_startup'
8
8
  require 'contrast/agent/telemetry/exception'
9
+ require 'contrast/agent/reporting/client/interface'
9
10
 
10
11
  module Contrast
11
12
  module Agent
@@ -29,11 +30,7 @@ module Contrast
29
30
  end
30
31
 
31
32
  def client
32
- @_client ||= Contrast::Agent::Reporting::ReporterClient.new
33
- end
34
-
35
- def connection
36
- @_connection ||= client.initialize_connection
33
+ @_client ||= Contrast::Agent::Reporting::Client::Interface.new
37
34
  end
38
35
 
39
36
  def start_thread!
@@ -41,13 +38,12 @@ module Contrast
41
38
  return if running?
42
39
 
43
40
  @connection_attempts = 0
44
-
45
- client.startup!(connection)
46
41
  @_thread = Contrast::Agent::Thread.new do
47
42
  logger.debug('[Reporter] Starting background Reporter thread.')
43
+ client.startup
48
44
  loop do
49
- next unless connected?
50
45
  break unless attempt_to_start?
46
+ next unless connected?
51
47
 
52
48
  process_event(queue.pop)
53
49
  rescue StandardError => e
@@ -61,12 +57,7 @@ module Contrast
61
57
  #
62
58
  # @param event [Contrast::Agent::Reporting::ReportingEvent] Freshly pop-ed event.
63
59
  def handle_resend event
64
- sleep(client.timeout) if client.sleep?
65
- # Retry once than discard the event. This is trigger on too many events of
66
- # same kind error.
67
- client.send_event(event, connection) if client.mode.status == client.mode.resending
68
- client.mode.reset_mode
69
- client.wake_up
60
+ client.handle_resend(event)
70
61
  end
71
62
 
72
63
  # @param event [Contrast::Agent::Reporting::ReportingEvent]
@@ -99,8 +90,9 @@ module Contrast
99
90
  return
100
91
  end
101
92
  return unless event
93
+ return unless connected?
102
94
 
103
- client.send_event(event, connection)
95
+ client.send_event(event)
104
96
  rescue StandardError => e
105
97
  logger.error('[Reporter] Could not send message to TeamServer from reporting queue.', e)
106
98
  end
@@ -124,17 +116,9 @@ module Contrast
124
116
  @_queue ||= Queue.new
125
117
  end
126
118
 
127
- # TODO: RUBY-99999
128
- # The client and connection are being used in multiple threads/ concurrently, and that's not okay. We need
129
- # to figure out why that is and lock it so that it isn't.
130
- #
131
119
  # @return [Boolean]
132
120
  def connected?
133
- if client && connection
134
- # Try to resend startup messages now with connection:
135
- client.startup!(connection) unless client.status.startup_messages_sent?
136
- return true
137
- end
121
+ return true if client.connected?
138
122
 
139
123
  logger.debug('[Reporter] No client/connection; sleeping...')
140
124
  @connection_attempts += 1
@@ -148,8 +132,8 @@ module Contrast
148
132
 
149
133
  # @param event [Contrast::Agent::Reporting::ReportingEvent]
150
134
  def process_event event
151
- client.send_event(event, connection)
152
- handle_resend(event) if client.mode.status == client.mode.resending
135
+ client.send_event(event)
136
+ handle_resend(event) if client.resending?
153
137
  rescue StandardError => e
154
138
  logger.error('[Reporter] Could not send message to TeamServer from reporting queue.', e)
155
139
  end
@@ -171,6 +155,7 @@ module Contrast
171
155
  stack_trace[1].path.delete_prefix(Dir.pwd)
172
156
  end
173
157
  stack_frame_function = stack_trace.nil? || stack_trace[1].nil? ? 'none' : stack_trace[1].label
158
+ stack_frame_type = Contrast::Agent::Telemetry::Exception::Obfuscate.obfuscate_path(stack_frame_type)
174
159
  Contrast::Agent::Telemetry::Exception::StackFrame.build(stack_frame_function, stack_frame_type, nil)
175
160
  end
176
161
  end
@@ -81,7 +81,7 @@ module Contrast
81
81
  safe_url = source_or_string(url || pattern)
82
82
 
83
83
  msg = new
84
- msg.signature = "#{ controller }##{ method } #{ safe_pattern }"
84
+ msg.signature = "#{ controller }##{ method } #{ safe_pattern }" # rubocop:disable [Security/Object/Method]
85
85
  msg.verb = Contrast::Utils::StringUtils.force_utf8(method)
86
86
  msg.url = Contrast::Utils::StringUtils.force_utf8(safe_url)
87
87
  msg
@@ -55,17 +55,24 @@ module Contrast
55
55
  # @param event_name [String] the type portion of the file to which to write
56
56
  # @param data [any] The data to be written to the file
57
57
  def write_to_file type, event_name, data = nil
58
- time = Time.now.to_i
58
+ time = Contrast::Utils::Timer.now_ms
59
59
  destination = type == :request ? path_for_requests : path_for_responses
60
60
  # If the feature is disabled or we have yet to create the directory structure, then we could have a nil
61
61
  # destination. In that case, take no action
62
62
  return unless destination
63
63
 
64
- filename = "#{ time }_#{ Thread.current.object_id }_#{ event_name.gsub('::', '-') }_teamserver_#{ type }.json"
64
+ # Get process id and thread id to make sure we don't overwrite files
65
+ process_id = Process.pid
66
+ thread_id = Thread.current.object_id
67
+ event_title = event_name.gsub('::', '-')
68
+ filename = "#{ time }_#{ thread_id }_#{ process_id }_#{ event_title }_teamserver_#{ type }.json"
65
69
  filepath = File.join(destination, filename)
66
70
  logger.debug('Writing to file', eventname: event_name, filename: filename, filepath: filepath)
67
71
  # Here is use append mode, because of a slightly possibility of overwriting an existing file
68
- File.open(filepath, 'a') { |f| f.write(Contrast::Utils::StringUtils.force_utf8(data)) }
72
+ File.open(filepath, 'a') do |f|
73
+ f.write(Contrast::Utils::StringUtils.force_utf8(data))
74
+ f.close
75
+ end
69
76
  rescue StandardError => e
70
77
  logger.warn('Saving audit failed', e: e)
71
78
  end
@@ -14,6 +14,7 @@ require 'contrast/agent/reporting/reporting_utilities/response_handler'
14
14
  require 'contrast/agent/reporting/reporting_events/application_settings'
15
15
  require 'contrast/agent/reporting/reporting_events/agent_effective_config'
16
16
  require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
17
+ require 'contrast/agent/reporting/reporting_utilities/resend'
17
18
 
18
19
  module Contrast
19
20
  module Agent
@@ -72,17 +73,17 @@ module Contrast
72
73
  def send_event event, connection
73
74
  return unless connection
74
75
 
76
+ response = nil
75
77
  logger.debug('[Reporter] Preparing to send reporting event', event_class: event.cs__class)
76
-
77
78
  request = build_request(event)
78
79
  response = connection.request(request)
79
- audit&.audit_event(event, response) if ::Contrast::API.request_audit_enable
80
+ audit.audit_event(event, response) if ::Contrast::API.request_audit_enable
80
81
  process_settings_response(response, event)
81
- report_configuration(response, event)
82
82
  process_preflight_response(event, response, connection)
83
+ report_configuration(response, event)
83
84
  response
84
85
  rescue StandardError => e
85
- handle_error(event, e)
86
+ handle_response_error(event, connection, e)
86
87
  end
87
88
 
88
89
  # Write effective config to file:
@@ -103,6 +104,9 @@ module Contrast
103
104
  diagnostics.write_to_file
104
105
  config_event = Contrast::Agent::Reporting::AgentEffectiveConfig.new(diagnostics)
105
106
  Contrast::Agent.reporter.send_event(config_event)
107
+ rescue StandardError => e
108
+ # Don't let this error bubble up and stop the agent reporting, with resending triggered.
109
+ logger.error('[Reporter] Error while reporting configuration', error: e, event_type: event&.cs__class)
106
110
  end
107
111
 
108
112
  def status
@@ -117,10 +121,47 @@ module Contrast
117
121
  @_diagnostics ||= Contrast::Config::Diagnostics::Monitor.new(Contrast::LOGGER.path)
118
122
  end
119
123
 
124
+ # Compress data with Zlib
125
+ #
126
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
127
+ # @param level [Integer] compression level
128
+ # @param strategy [Integer] compression strategy
129
+ # @return [String] compressed data
130
+ def compress_event event, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY
131
+ compressed_data = StringIO.new.set_encoding(STRING_ENCODING)
132
+ gzip = Zlib::GzipWriter.new(compressed_data, level, strategy)
133
+ gzip.write(event.event_json)
134
+ gzip.close
135
+ gzip = nil
136
+ compressed_event = compressed_data.string.dup
137
+ compressed_data.close
138
+ compressed_data = nil
139
+ compressed_event
140
+ ensure
141
+ gzip&.close
142
+ compressed_data&.close
143
+ compressed_event
144
+ end
145
+
146
+ # Reads compressed data
147
+ #
148
+ # @param compresed_data [String]
149
+ def decompress compresed_data
150
+ Zlib::GzipReader.wrap(StringIO.new(compresed_data), &:read)
151
+ end
152
+
153
+ ##############
154
+ # Forwarders #
155
+ ##############
156
+
120
157
  def sleep?
121
158
  response_handler.sleep?
122
159
  end
123
160
 
161
+ def put_to_sleep
162
+ response_handler.put_to_sleep
163
+ end
164
+
124
165
  def timeout
125
166
  response_handler.timeout
126
167
  end
@@ -129,8 +170,8 @@ module Contrast
129
170
  response_handler.mode
130
171
  end
131
172
 
132
- def reset_mode
133
- response_handler.reset_mode
173
+ def enter_run_mode
174
+ response_handler.enter_run_mode
134
175
  end
135
176
 
136
177
  def wake_up
@@ -8,16 +8,20 @@ require 'contrast/components/scope'
8
8
  require 'contrast/agent/reporting/reporting_events/application_startup'
9
9
  require 'contrast/agent/reporting/reporting_utilities/reporter_client'
10
10
  require 'contrast/agent/reporting/reporting_utilities/endpoints'
11
+ require 'contrast/agent/reporting/reporting_utilities/resend'
11
12
 
12
13
  module Contrast
13
14
  module Agent
14
15
  module Reporting
15
16
  # This module holds utilities required by the reporting service client
16
17
  module ReporterClientUtils
18
+ include Contrast::Agent::Reporting::Resend
17
19
  include Contrast::Components::Logger::InstanceMethods
18
20
  include Contrast::Components::Scope::InstanceMethods
19
21
  include Contrast::Agent::Reporting::Endpoints
20
22
 
23
+ STRING_ENCODING = 'BINARY'
24
+
21
25
  # List the events that need to be sent when agent starts up.
22
26
  # The order here matters -- DO NOT CHANGE IT!!! >_< - HM
23
27
  #
@@ -33,19 +37,37 @@ module Contrast
33
37
 
34
38
  private
35
39
 
36
- # Send Agent Startup event
40
+ # Send Agent Startup event. If error occurs, it will try to resend the message.
37
41
  #
38
42
  # @param connection [Net::HTTP] open connection
39
43
  def send_agent_startup connection
40
- logger.debug('Preparing to send startup messages')
44
+ logger.debug('[Reporter] Preparing to send startup messages')
45
+ STARTUP_EVENTS.each { |event| send_event(event.new, connection) }
46
+ logger.debug('[Reporter] Startup messages sent.') if status.startup_messages_sent?
47
+ end
41
48
 
42
- STARTUP_EVENTS.each do |event|
43
- startup_event = event.new
44
- send_event(startup_event, connection)
45
- rescue StandardError => e
46
- handle_error(startup_event, e)
47
- end
48
- logger.debug('Startup messages sent')
49
+ # Disable reporting and log the error
50
+ #
51
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
52
+ # @param error [StandardError]
53
+ def disable_reporting event, error
54
+ status.failure!
55
+ mode.resend.reset_rescue_attempts
56
+ mode.status = mode.disabled
57
+ message = '[Reporter] Unable to send message.'
58
+ response_handler.stop_reporting(message,
59
+ application: Contrast::APP_CONTEXT.name, # rubocop:disable Security/Module/Name
60
+ connection_error: error,
61
+ client: Contrast::Agent::Reporting::ReporterClient::SERVICE_NAME,
62
+ event_id: event&.__id__,
63
+ event_type: event&.cs__class&.cs__name)
64
+ nil
65
+ end
66
+
67
+ def response_success!
68
+ status.success!
69
+ mode.enter_run_mode
70
+ mode.resend.reset_rescue_attempts
49
71
  end
50
72
 
51
73
  # This method will build headers of the request required for TS communication
@@ -65,29 +87,18 @@ module Contrast
65
87
  request
66
88
  end
67
89
 
68
- # Handles standard error case, logs and set status for failure
69
- #
70
- # @param event [Contrast::Agent::Reporting::ReportingEvent]
71
- # One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
72
- # @param error_msg [StandardError]
73
- # @return nil [NilClass] to be passed as response
74
- def handle_error event, error_msg
75
- status.failure!
76
- logger.error('Unable to send message.',
77
- error_msg,
78
- client: Contrast::Agent::Reporting::ReporterClient::SERVICE_NAME,
79
- event_id: event&.__id__,
80
- event_type: event&.cs__class&.cs__name)
81
- nil
82
- end
83
-
84
90
  # Handles response processing and sets status
85
91
  #
86
92
  # @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
87
93
  # @param response [Net::HTTP::Response]
88
94
  def process_settings_response response, event
89
95
  res = response_handler.process(response, event)
90
- status.success! if res
96
+ if res
97
+ status.success!
98
+ mode.resend.reset_rescue_attempts
99
+ else
100
+ status.failure!
101
+ end
91
102
  res
92
103
  end
93
104
 
@@ -104,6 +115,7 @@ module Contrast
104
115
  return unless response&.body && connection
105
116
 
106
117
  findings_to_return = response.body.split(',').delete_if { |el| el.include?('*') }
118
+ mode.resend.reset_rescue_attempts
107
119
  findings_to_return.each do |index|
108
120
  preflight_message = event.messages[index.to_i]
109
121
  corresponding_finding = Contrast::Agent::Reporting::ReportingStorage.delete(preflight_message.data)
@@ -112,7 +124,7 @@ module Contrast
112
124
  send_event(corresponding_finding, connection)
113
125
  end
114
126
  rescue StandardError => e
115
- logger.error('Unable to handle response', e)
127
+ logger.error('[Reporter] Unable to handle preflight response', e)
116
128
  end
117
129
 
118
130
  # Convert the given event into an appropriate Net::HTTPRequest object, setting the request headers and
@@ -133,10 +145,7 @@ module Contrast
133
145
  end
134
146
  build_headers(request)
135
147
  event.attach_headers(request)
136
- # compress:
137
- gzip = Zlib::GzipWriter.new(StringIO.new)
138
- gzip << event.event_json
139
- request.body = gzip.close.string
148
+ request.body = compress_event(event)
140
149
  request
141
150
  end
142
151
  end