contrast-agent 6.6.3 → 6.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +0 -3
  4. data/ext/cs__scope/cs__scope.c +1 -1
  5. data/lib/contrast/agent/assess/contrast_event.rb +2 -24
  6. data/lib/contrast/agent/assess/events/source_event.rb +7 -61
  7. data/lib/contrast/agent/assess/finalizers/hash.rb +11 -0
  8. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +0 -55
  9. data/lib/contrast/agent/assess/policy/policy_node.rb +3 -3
  10. data/lib/contrast/agent/assess/policy/policy_node_utils.rb +0 -1
  11. data/lib/contrast/agent/assess/policy/propagation_node.rb +4 -4
  12. data/lib/contrast/agent/assess/policy/source_method.rb +24 -1
  13. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +7 -5
  14. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +6 -1
  15. data/lib/contrast/agent/assess/policy/trigger_method.rb +38 -119
  16. data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -3
  17. data/lib/contrast/agent/assess/property/evented.rb +2 -12
  18. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +42 -82
  19. data/lib/contrast/agent/assess/rule/response/base_rule.rb +11 -27
  20. data/lib/contrast/agent/assess/rule/response/body_rule.rb +1 -3
  21. data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +77 -62
  22. data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +1 -1
  23. data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +6 -1
  24. data/lib/contrast/agent/assess/rule/response/header_rule.rb +5 -5
  25. data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +1 -1
  26. data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +1 -1
  27. data/lib/contrast/agent/assess/tracker.rb +1 -7
  28. data/lib/contrast/agent/at_exit_hook.rb +1 -7
  29. data/lib/contrast/agent/excluder.rb +206 -0
  30. data/lib/contrast/agent/exclusion_matcher.rb +6 -0
  31. data/lib/contrast/agent/inventory/database_config.rb +18 -23
  32. data/lib/contrast/agent/middleware.rb +0 -1
  33. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +4 -0
  34. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -0
  35. data/lib/contrast/agent/protect/rule/base.rb +64 -24
  36. data/lib/contrast/agent/protect/rule/base_service.rb +1 -0
  37. data/lib/contrast/agent/protect/rule/cmd_injection.rb +18 -104
  38. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +129 -0
  39. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +169 -0
  40. data/lib/contrast/agent/protect/rule/deserialization.rb +7 -5
  41. data/lib/contrast/agent/protect/rule/path_traversal.rb +9 -7
  42. data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +16 -14
  43. data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +51 -0
  44. data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +67 -0
  45. data/lib/contrast/agent/protect/rule/sqli.rb +6 -31
  46. data/lib/contrast/agent/protect/rule/xxe.rb +11 -6
  47. data/lib/contrast/agent/protect/rule.rb +3 -1
  48. data/lib/contrast/agent/reporting/attack_result/attack_result.rb +8 -0
  49. data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +91 -36
  50. data/lib/contrast/agent/reporting/attack_result/user_input.rb +11 -0
  51. data/lib/contrast/agent/reporting/details/bot_blocker_details.rb +29 -0
  52. data/lib/contrast/agent/reporting/details/cmd_injection_details.rb +30 -0
  53. data/lib/contrast/agent/reporting/details/details.rb +18 -0
  54. data/lib/contrast/agent/reporting/details/http_method_tempering_details.rb +27 -0
  55. data/lib/contrast/agent/reporting/details/ip_denylist_details.rb +27 -0
  56. data/lib/contrast/agent/reporting/details/no_sqli_details.rb +36 -0
  57. data/lib/contrast/agent/reporting/details/path_traversal_details.rb +24 -0
  58. data/lib/contrast/agent/reporting/details/path_traversal_semantic_analysis_details.rb +32 -0
  59. data/lib/contrast/agent/reporting/details/protect_rule_details.rb +17 -0
  60. data/lib/contrast/agent/reporting/details/sqli_dangerous_functions.rb +22 -0
  61. data/lib/contrast/agent/reporting/details/sqli_details.rb +36 -0
  62. data/lib/contrast/agent/reporting/details/untrusted_deserialization_details.rb +27 -0
  63. data/lib/contrast/agent/reporting/details/virtual_patch_details.rb +24 -0
  64. data/lib/contrast/agent/reporting/details/xss_details.rb +33 -0
  65. data/lib/contrast/agent/reporting/details/xss_match.rb +30 -0
  66. data/lib/contrast/agent/reporting/details/xxe_details.rb +36 -0
  67. data/lib/contrast/agent/reporting/details/xxe_match.rb +25 -0
  68. data/lib/contrast/agent/reporting/details/xxe_wrapper.rb +25 -0
  69. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +1 -1
  70. data/lib/contrast/agent/reporting/masker/masker.rb +78 -65
  71. data/lib/contrast/agent/reporting/masker/masker_utils.rb +1 -30
  72. data/lib/contrast/agent/reporting/reporter.rb +1 -2
  73. data/lib/contrast/agent/reporting/reporting_events/agent_startup.rb +2 -2
  74. data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +81 -15
  75. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +13 -25
  76. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_activity.rb +17 -22
  77. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +46 -125
  78. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +5 -16
  79. data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +10 -18
  80. data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +6 -14
  81. data/lib/contrast/agent/reporting/reporting_events/application_startup.rb +1 -1
  82. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +7 -21
  83. data/lib/contrast/agent/reporting/reporting_events/finding.rb +19 -49
  84. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +12 -9
  85. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +1 -1
  86. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +23 -21
  87. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +5 -18
  88. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +1 -0
  89. data/lib/contrast/{api/decorators/trace_taint_range_tags.rb → agent/reporting/reporting_events/finding_event_taint_range_tags.rb} +7 -6
  90. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +45 -10
  91. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +1 -1
  92. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +2 -2
  93. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -14
  94. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +11 -0
  95. data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +3 -1
  96. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +11 -23
  97. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +8 -26
  98. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -1
  99. data/lib/contrast/agent/reporting/reporting_utilities/build_preflight.rb +4 -7
  100. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -1
  101. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +2 -1
  102. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +3 -3
  103. data/lib/contrast/agent/request.rb +4 -2
  104. data/lib/contrast/agent/request_context.rb +12 -15
  105. data/lib/contrast/agent/request_context_extend.rb +67 -69
  106. data/lib/contrast/agent/request_handler.rb +1 -11
  107. data/lib/contrast/agent/response.rb +0 -18
  108. data/lib/contrast/agent/service_heartbeat.rb +1 -1
  109. data/lib/contrast/agent/telemetry/events/event.rb +1 -1
  110. data/lib/contrast/agent/telemetry/events/metric_event.rb +1 -1
  111. data/lib/contrast/agent/telemetry/events/startup_metrics_event.rb +3 -3
  112. data/lib/contrast/agent/version.rb +1 -1
  113. data/lib/contrast/api/communication/messaging_queue.rb +2 -3
  114. data/lib/contrast/api/communication/socket_client.rb +4 -4
  115. data/lib/contrast/api/communication/speedracer.rb +4 -8
  116. data/lib/contrast/api/decorators/agent_startup.rb +5 -6
  117. data/lib/contrast/api/decorators/application_settings.rb +2 -1
  118. data/lib/contrast/api/decorators/application_startup.rb +6 -6
  119. data/lib/contrast/api/decorators/message.rb +0 -4
  120. data/lib/contrast/api/decorators/rasp_rule_sample.rb +0 -6
  121. data/lib/contrast/api/decorators.rb +0 -6
  122. data/lib/contrast/api/dtm.pb.rb +0 -489
  123. data/lib/contrast/components/agent.rb +16 -12
  124. data/lib/contrast/components/api.rb +10 -10
  125. data/lib/contrast/components/app_context.rb +9 -9
  126. data/lib/contrast/components/app_context_extend.rb +1 -1
  127. data/lib/contrast/components/assess.rb +92 -38
  128. data/lib/contrast/components/assess_rules.rb +36 -0
  129. data/lib/contrast/components/config.rb +54 -12
  130. data/lib/contrast/components/contrast_service.rb +8 -8
  131. data/lib/contrast/components/heap_dump.rb +1 -1
  132. data/lib/contrast/components/protect.rb +5 -5
  133. data/lib/contrast/components/ruby_component.rb +81 -0
  134. data/lib/contrast/components/sampling.rb +1 -1
  135. data/lib/contrast/components/security_logger.rb +23 -0
  136. data/lib/contrast/components/service.rb +55 -0
  137. data/lib/contrast/components/settings.rb +12 -4
  138. data/lib/contrast/config/base_configuration.rb +1 -1
  139. data/lib/contrast/config/protect_rules_configuration.rb +17 -3
  140. data/lib/contrast/config/server_configuration.rb +1 -1
  141. data/lib/contrast/config.rb +0 -6
  142. data/lib/contrast/configuration.rb +81 -17
  143. data/lib/contrast/extension/assess/exec_trigger.rb +3 -1
  144. data/lib/contrast/extension/assess/marshal.rb +3 -2
  145. data/lib/contrast/extension/assess/string.rb +0 -1
  146. data/lib/contrast/extension/extension.rb +1 -1
  147. data/lib/contrast/framework/base_support.rb +0 -5
  148. data/lib/contrast/framework/grape/support.rb +1 -23
  149. data/lib/contrast/framework/manager.rb +0 -10
  150. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -6
  151. data/lib/contrast/framework/rails/support.rb +5 -58
  152. data/lib/contrast/framework/sinatra/support.rb +2 -21
  153. data/lib/contrast/logger/cef_log.rb +21 -3
  154. data/lib/contrast/logger/log.rb +1 -11
  155. data/lib/contrast/tasks/config.rb +4 -2
  156. data/lib/contrast/utils/assess/event_limit_utils.rb +28 -12
  157. data/lib/contrast/utils/assess/trigger_method_utils.rb +10 -18
  158. data/lib/contrast/utils/findings.rb +6 -5
  159. data/lib/contrast/utils/hash_digest.rb +9 -24
  160. data/lib/contrast/utils/hash_digest_extend.rb +6 -6
  161. data/lib/contrast/utils/invalid_configuration_util.rb +21 -58
  162. data/lib/contrast/utils/log_utils.rb +47 -17
  163. data/lib/contrast/utils/net_http_base.rb +7 -8
  164. data/lib/contrast/utils/patching/policy/patch_utils.rb +3 -2
  165. data/lib/contrast/utils/stack_trace_utils.rb +0 -25
  166. data/lib/contrast/utils/string_utils.rb +9 -0
  167. data/lib/contrast/utils/telemetry_client.rb +13 -7
  168. data/lib/contrast.rb +5 -10
  169. metadata +39 -28
  170. data/lib/contrast/agent/reporting/reporting_events/trace_event_source.rb +0 -30
  171. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -43
  172. data/lib/contrast/api/decorators/activity.rb +0 -33
  173. data/lib/contrast/api/decorators/architecture_component.rb +0 -36
  174. data/lib/contrast/api/decorators/finding.rb +0 -29
  175. data/lib/contrast/api/decorators/route_coverage.rb +0 -91
  176. data/lib/contrast/api/decorators/trace_event.rb +0 -120
  177. data/lib/contrast/api/decorators/trace_event_object.rb +0 -63
  178. data/lib/contrast/api/decorators/trace_event_signature.rb +0 -69
  179. data/lib/contrast/api/decorators/trace_taint_range.rb +0 -52
  180. data/lib/contrast/config/assess_configuration.rb +0 -93
  181. data/lib/contrast/config/assess_rules_configuration.rb +0 -32
  182. data/lib/contrast/config/root_configuration.rb +0 -90
  183. data/lib/contrast/config/ruby_configuration.rb +0 -81
  184. data/lib/contrast/config/service_configuration.rb +0 -49
  185. data/lib/contrast/utils/preflight_util.rb +0 -13
@@ -13,6 +13,7 @@ require 'contrast/agent/assess/rule/response/x_xss_protection_header_rule'
13
13
  require 'contrast/agent/protect/input_analyzer/input_analyzer'
14
14
  require 'contrast/components/logger'
15
15
  require 'contrast/utils/log_utils'
16
+ require 'contrast/utils/string_utils'
16
17
 
17
18
  module Contrast
18
19
  module Agent
@@ -23,28 +24,12 @@ module Contrast
23
24
  include Contrast::Utils::CEFLogUtils
24
25
  include Contrast::Components::Logger::InstanceMethods
25
26
  BUILD_ATTACK_LOGGER_MESSAGE = 'Building attack result from Contrast Service input analysis result'
26
- # Convert the discovered route for this request to appropriate forms and disseminate it to those locations
27
- # where it is necessary for our route coverage and finding vulnerability discovery features to function.
28
- #
29
- # @param route [Contrast::Api::Dtm::RouteCoverage, nil] the route of the current request, as determined from the
30
- # framework
31
- def append_route_coverage route
32
- return unless route
33
-
34
- # For our findings
35
- @route = route
36
-
37
- # For SR findings
38
- @activity.routes << route
39
-
40
- # For TS routes
41
- @request.route = route
42
- end
27
+ CEF_LOGGING_RULES = %w[bot-blocker virtual-patch ip-denylist].cs__freeze
43
28
 
44
29
  # Convert the discovered route for this request to appropriate forms and disseminate it to those locations
45
30
  # where it is necessary for our route coverage and finding vulnerability discovery features to function.
46
31
  #
47
- # @param route [Contrast::Api::Dtm::RouteCoverage]
32
+ # @param route [Contrast::Agent::Reporting::RouteCoverage]
48
33
  def append_to_observed_route route
49
34
  return unless route
50
35
 
@@ -52,20 +37,10 @@ module Contrast
52
37
  @observed_route.verb = route.verb
53
38
  @observed_route.url = route.url if route.url
54
39
  @request.observed_route = @observed_route
55
- end
56
40
 
57
- # Collect the results for the given rule with the given action
58
- #
59
- # @param rule [String] the id of the rule to which the results apply
60
- # @param response_type [Symbol] the result of the response, matching a value of
61
- # Contrast::Api::Dtm::AttackResult::ResponseType
62
- # @return [Array<Contrast::Api::Dtm::AttackResult>]
63
- def results_for rule, response_type = nil
64
- if response_type.nil?
65
- activity.results.select { |r| r.rule_id == rule }
66
- else
67
- activity.results.select { |r| r.rule_id == rule && r.response == response_type }
68
- end
41
+ observation = Contrast::Agent::Reporting::RouteDiscoveryObservation.new(route.url, route.verb)
42
+ @discovered_route = Contrast::Agent::Reporting::RouteDiscovery.new(route.route, observation)
43
+ @request.discovered_route = @discovered_route
69
44
  end
70
45
 
71
46
  # @raise [Contrast::SecurityException]
@@ -74,7 +49,7 @@ module Contrast
74
49
  return false unless ::Contrast::PROTECT.enabled?
75
50
  return false if @do_not_track
76
51
 
77
- service_response = Contrast::Agent&.messaging_queue&.send_event_immediately(@activity.http_request)
52
+ service_response = Contrast::Agent&.messaging_queue&.send_event_immediately(@activity.request.dtm)
78
53
  return false unless service_response
79
54
 
80
55
  handle_protect_state(service_response)
@@ -112,6 +87,7 @@ module Contrast
112
87
  @do_not_track = true unless state.track_request
113
88
  return unless state.security_exception
114
89
 
90
+ # make sure the activity get send before the error
115
91
  # If Contrast Service has NOT handled the input analysis, handle them here
116
92
  build_attack_results(agent_settings)
117
93
  logger.debug('Contrast Service said to block this request')
@@ -126,28 +102,22 @@ module Contrast
126
102
  @response = Contrast::Agent::Response.new(rack_response)
127
103
  return unless @sample_res
128
104
 
129
- #
130
- # TODO: RUBY-1376 once all rules translated, move this to if/else w/ the enabled
131
- if Contrast::Agent::Reporter.enabled?
132
- Contrast::Agent::Assess::Rule::Response::AutoComplete.new.analyze(@response)
133
- Contrast::Agent::Assess::Rule::Response::CacheControl.new.analyze(@response)
134
- Contrast::Agent::Assess::Rule::Response::ClickJacking.new.analyze(@response)
135
- Contrast::Agent::Assess::Rule::Response::CspHeaderMissing.new.analyze(@response)
136
- Contrast::Agent::Assess::Rule::Response::CspHeaderInsecure.new.analyze(@response)
137
- Contrast::Agent::Assess::Rule::Response::HSTSHeader.new.analyze(@response)
138
- Contrast::Agent::Assess::Rule::Response::ParametersPollution.new.analyze(@response)
139
- Contrast::Agent::Assess::Rule::Response::XContentType.new.analyze(@response)
140
- Contrast::Agent::Assess::Rule::Response::XXssProtection.new.analyze(@response)
141
- else
142
- activity.http_response = @response.dtm
143
- end
105
+ Contrast::Agent::Assess::Rule::Response::AutoComplete.new.analyze(@response)
106
+ Contrast::Agent::Assess::Rule::Response::CacheControl.new.analyze(@response)
107
+ Contrast::Agent::Assess::Rule::Response::ClickJacking.new.analyze(@response)
108
+ Contrast::Agent::Assess::Rule::Response::CspHeaderMissing.new.analyze(@response)
109
+ Contrast::Agent::Assess::Rule::Response::CspHeaderInsecure.new.analyze(@response)
110
+ Contrast::Agent::Assess::Rule::Response::HSTSHeader.new.analyze(@response)
111
+ Contrast::Agent::Assess::Rule::Response::ParametersPollution.new.analyze(@response)
112
+ Contrast::Agent::Assess::Rule::Response::XContentType.new.analyze(@response)
113
+ Contrast::Agent::Assess::Rule::Response::XXssProtection.new.analyze(@response)
144
114
  rescue StandardError => e
145
115
  logger.error('Unable to extract information after request', e)
146
116
  end
147
117
 
148
118
  # This here is for things we don't have implemented
149
119
  def log_to_cef
150
- activity.results.each { |attack_result| logging_logic(attack_result, attack_result.rule_id.downcase) }
120
+ activity.defend.attackers.each { |attacker| logging_logic(attacker.protection_rules) }
151
121
  end
152
122
 
153
123
  # @param input_analysis [Contrast::Api::Settings::InputAnalysis]
@@ -177,7 +147,7 @@ module Contrast
177
147
 
178
148
  results_by_rule.each_pair do |_, attack_result|
179
149
  logger.info('Blocking attack result', rule: attack_result.rule_id)
180
- activity.results << attack_result
150
+ activity.attach_defend(attack_result)
181
151
  end
182
152
  end
183
153
 
@@ -199,28 +169,56 @@ module Contrast
199
169
  end
200
170
  end
201
171
 
202
- def logging_logic result, rule_id
203
- rules = %w[bot_blocker virtual_patch ip_denylist]
204
- return unless rules.include?(rule_id)
205
-
206
- rule_details = Contrast::Api::Dtm::RaspRuleSample.to_controlled_hash(result.samples[0]).fetch(rule_id.to_sym)
207
- outcome = Contrast::Api::Dtm::AttackResult::ResponseType.get_name_by_tag(result.response)
208
- case rule_id
209
- when /bot_blocker/i
210
- blocker_to_json = Contrast::Api::Dtm::BotBlockerDetails.to_controlled_hash(rule_details)
211
- cef_logger.bot_blocking_message(blocker_to_json, outcome)
212
- when /virtual_patch/i
213
- virtual_patch_to_json = Contrast::Api::Dtm::VirtualPatchDetails.to_controlled_hash(rule_details)
214
- cef_logger.virtual_patch_message(virtual_patch_to_json, outcome)
215
- when /ip_denylist/i
216
- sender_ip = extract_sender_ip
217
- ip_denylist_to_json = Contrast::Api::Dtm::IpDenylistDetails.to_controlled_hash(rule_details)
218
- return unless sender_ip
219
- return unless sender_ip.include?(ip_denylist_to_json[:ip])
220
-
221
- cef_logger.ip_denylisted_message(sender_ip, ip_denylist_to_json, outcome)
172
+ # @param protection_rules [Array<rule_id => Contrast::Agent::Reporting::ApplicationDefendAttackActivity>] Array
173
+ # of all protection rules per active attackers of this request life cycle.
174
+ def logging_logic protection_rules
175
+ protection_rules.any? do |rule_id, activity|
176
+ next unless CEF_LOGGING_RULES.include?(rule_id)
177
+
178
+ outcome = activity.response_type
179
+ rule_details = details_builder(outcome, activity)
180
+ case rule_id
181
+ when /bot-blocker/i
182
+ cef_logger.bot_blocking_message(rule_details.to_controlled_hash, outcome) if rule_details
183
+ when /virtual-patch/i
184
+ cef_logger.virtual_patch_message(rule_details.to_controlled_hash, outcome) if rule_details
185
+ when /ip-denylist/i
186
+ sender_ip = extract_sender_ip
187
+ next unless sender_ip
188
+ next unless rule_details && rule_details.ip == sender_ip
189
+
190
+ cef_logger.ip_denylisted_message(sender_ip, rule_details.to_controlled_hash, outcome)
191
+ end
222
192
  end
223
193
  end
194
+
195
+ # @param outcome [Symbol<Contrast::Agent::Reporting::ResponseType>]
196
+ # @param activity [Contrast::Agent::Reporting::ApplicationDefendAttackActivity]
197
+ def details_builder outcome, activity
198
+ case outcome
199
+ when ::Contrast::Agent::Reporting::ResponseType::BLOCKED
200
+ blocked = activity.blocked
201
+ get_details(blocked)
202
+ when ::Contrast::Agent::Reporting::ResponseType::MONITORED
203
+ exploited = activity.exploited
204
+ get_details(exploited)
205
+ when ::Contrast::Agent::Reporting::ResponseType::PROBED
206
+ ineffective = activity.ineffective
207
+ get_details(ineffective)
208
+ when ::Contrast::Agent::Reporting::ResponseType::SUSPICIOUS
209
+ activity.suspicious.samples[0].details
210
+ suspicious = activity.suspicious
211
+ get_details(suspicious)
212
+ end
213
+ end
214
+
215
+ # @param type [Contrast::Agent::Reporting::ApplicationDefendAttackSampleActivity]
216
+ # @return details [Contrast::Agent::Reporting::ProtectRuleDetails] depends on rule
217
+ def get_details type
218
+ sample = nil
219
+ sample = type.samples[0] unless type.samples.empty?
220
+ sample&.details
221
+ end
224
222
  end
225
223
  end
226
224
  end
@@ -4,7 +4,6 @@
4
4
  require 'contrast/components/logger'
5
5
  require 'contrast/components/scope'
6
6
  require 'contrast/agent/reporting/reporter'
7
- require 'contrast/agent/reporting/reporting_utilities/dtm_message'
8
7
  require 'contrast/agent/reporting/masker/masker'
9
8
 
10
9
  module Contrast
@@ -22,13 +21,6 @@ module Contrast
22
21
  @ruleset = ::Contrast::AGENT.ruleset
23
22
  end
24
23
 
25
- # Send Activities messages to TS [Contrast::Api::Dtm::Activity]
26
- # TODO: RUBY-1704
27
- # TODO: RUBY-1438
28
- def send_activity_messages
29
- Contrast::Agent.messaging_queue&.send_event_eventually(context.activity)
30
- end
31
-
32
24
  # reports events[Contrast::Agent::Reporting::ReporterEvent] to TS
33
25
  # This method is used to send our JSON messages directly to TeamServer at the end of each request. As we move
34
26
  # more endpoints over, this method will take the messages originally sent by #send_actiivty_messages. At the end,
@@ -37,11 +29,9 @@ module Contrast
37
29
  return unless (reporter = Contrast::Agent.reporter)
38
30
 
39
31
  reporter.send_event(context.observed_route)
40
- return unless Contrast::Agent::Reporter.enabled?
41
-
42
32
  # Mask Sensitive Data
43
33
  Contrast::Agent::Reporting::Masker.mask(context.activity)
44
- event = Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity)
34
+ event = context.activity
45
35
  reporter.send_event(event)
46
36
  end
47
37
 
@@ -45,24 +45,6 @@ module Contrast
45
45
  end
46
46
  end
47
47
 
48
- # A form of the Rack::Response which we can report to the Service to be sent to TeamServer for processing. B/c
49
- # the response can change, we can't memoize this :(
50
- #
51
- # @return [Contrast::Api::Dtm::HttpResponse]
52
- def dtm
53
- context_response = Contrast::Api::Dtm::HttpResponse.new
54
- context_response.response_code = response_code.to_i
55
- headers&.each_pair do |key, value|
56
- append_pair(context_response.normalized_response_headers, key, value)
57
- end
58
- context_response.response_body_binary = Contrast::Utils::StringUtils.force_utf8(body)
59
-
60
- doc_type = document_type
61
- context_response.document_type = doc_type if doc_type
62
-
63
- context_response
64
- end
65
-
66
48
  # The response code of this response
67
49
  #
68
50
  # @return [Integer]
@@ -19,7 +19,7 @@ module Contrast
19
19
  @_thread = Contrast::Agent::Thread.new do
20
20
  logger.info('Starting heartbeat thread.')
21
21
  loop do
22
- logger.info("Queue Size: #{ Contrast::Agent.messaging_queue.queue&.length }")
22
+ logger.info("Queue Size: #{ Contrast::Agent.messaging_queue&.queue&.length }")
23
23
  Contrast::Agent.messaging_queue&.send_event_eventually(poll_message)
24
24
  clean_properties
25
25
  sleep(REFRESH_INTERVAL_SEC)
@@ -21,7 +21,7 @@ module Contrast
21
21
  ''
22
22
  end
23
23
 
24
- def to_hash **_args
24
+ def to_controlled_hash **_args
25
25
  {
26
26
  tags: @tags,
27
27
  timestamp: @timestamp,
@@ -19,7 +19,7 @@ module Contrast
19
19
  @fields['_filler'] = 0
20
20
  end
21
21
 
22
- def to_hash **_args
22
+ def to_controlled_hash **_args
23
23
  super.merge!({ fields: @fields })
24
24
  end
25
25
  end
@@ -50,7 +50,7 @@ module Contrast
50
50
  def initialize
51
51
  super
52
52
  @settings = []
53
- add_config_keys(::Contrast::CONFIG.root, 'root')
53
+ add_config_keys(::Contrast::CONFIG.config, 'root')
54
54
  @settings << ENV.keys.select { |v| v.starts_with?('CONTRAST') }
55
55
  @settings.flatten
56
56
  add_tags
@@ -70,9 +70,9 @@ module Contrast
70
70
  end
71
71
 
72
72
  def add_config_keys config, nested_key
73
- config.to_hash.reject! { |_k, v| REJECTED_VALUES.include?(v) }
73
+ config.to_contrast_hash.reject! { |_k, v| REJECTED_VALUES.include?(v) }
74
74
 
75
- config.to_hash.each do |k, v|
75
+ config.to_contrast_hash.each do |k, v|
76
76
  unless v.cs__class <= Contrast::Config::BaseConfiguration
77
77
  @settings << "#{ nested_key }.#{ k }"
78
78
  next
@@ -3,6 +3,6 @@
3
3
 
4
4
  module Contrast
5
5
  module Agent
6
- VERSION = '6.6.3'
6
+ VERSION = '6.7.0'
7
7
  end
8
8
  end
@@ -29,8 +29,7 @@ module Contrast
29
29
  # types of events include initial settings/ setup on startup and analysis required to complete before handing
30
30
  # execution from our pre-filter operations to the application code (i.e. Protect's input analysis).
31
31
  #
32
- # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of
33
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
32
+ # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
34
33
  # @return [Contrast::Api::Settings::AgentSettings,nil]
35
34
  def send_event_immediately event
36
35
  if ::Contrast::AGENT.disabled?
@@ -59,7 +58,7 @@ module Contrast
59
58
  # Assess' vulnerability reporting).
60
59
  #
61
60
  # @param event [Contrast::Api::Dtm, Contrast::Api::Dtm::Poll] One of the DTMs valid for the event field of
62
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
61
+ # Contrast::Api::Dtm::Message
63
62
  # @param force [Boolean] if we should always queue this event, even if the service isn't running, in case the
64
63
  # message may be ready before the service has initiated. usually for those events which happen in a separate
65
64
  # thread or which may occur during initialization.
@@ -53,13 +53,13 @@ module Contrast
53
53
  # Log information about the connection being used to communicate between the Agent and SpeedRacer.
54
54
  def log_connection
55
55
  # The socket is set,
56
- if ::Contrast::CONFIG.root.agent.service.socket
56
+ if ::Contrast::CONFIG.agent.service.socket
57
57
  logger.info('Connecting to the Contrast Service using a UnixSocket socket',
58
58
  socket: ::Contrast::CONTRAST_SERVICE.socket_path)
59
59
  return
60
60
  end
61
61
  # The host & port are set,
62
- if ::Contrast::CONFIG.root.agent.service.host && ::Contrast::CONFIG.root.agent.service.port
62
+ if ::Contrast::CONFIG.agent.service.host && ::Contrast::CONFIG.agent.service.port
63
63
  logger.info('Connecting to the Contrast Service using a TCP socket',
64
64
  host: ::Contrast::CONTRAST_SERVICE.host,
65
65
  port: ::Contrast::CONTRAST_SERVICE.port)
@@ -78,11 +78,11 @@ module Contrast
78
78
  #
79
79
  # @return [String]
80
80
  def log_connection_error_msg
81
- if ::Contrast::CONFIG.root.agent.service.host
81
+ if ::Contrast::CONFIG.agent.service.host
82
82
  'Missing a required connection value to the Contrast Service. ' \
83
83
  '`agent.service.port` is not set. ' \
84
84
  'Falling back to default TCP socket port.'
85
- elsif ::Contrast::CONFIG.root.agent.service.port
85
+ elsif ::Contrast::CONFIG.agent.service.port
86
86
  'Missing a required connection value to the Contrast Service. ' \
87
87
  '`agent.service.host` is not set. ' \
88
88
  'Falling back to default TCP socket host.'
@@ -55,8 +55,7 @@ module Contrast
55
55
  # if anything's changed in TeamServer meaning the Agent needs to replace its current settings or there is
56
56
  # Protect analysis information or nil if the current Agent settings do not need updating.
57
57
  #
58
- # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of
59
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
58
+ # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
60
59
  # @return [Contrast::Api::Settings::AgentSettings,nil]
61
60
  def return_response event
62
61
  send_to_speedracer(event) do |response|
@@ -67,8 +66,7 @@ module Contrast
67
66
  # Send the given Event to SpeedRacer and pass the result to our Contrast::Api::Communication::ResponseProcessor
68
67
  # as there is no immediate action required from sending this Event.
69
68
  #
70
- # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of
71
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
69
+ # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
72
70
  def process_internally event
73
71
  send_to_speedracer(event) do |response|
74
72
  response_processor.process(response)
@@ -80,8 +78,7 @@ module Contrast
80
78
  # Ensure there is a running SpeedRacer and then send the given Event to it. It is necessary to ensure the
81
79
  # SpeedRacer is running as, if the process has crashed or restarted, we must rebuild our context there.
82
80
  #
83
- # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of
84
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
81
+ # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
85
82
  # @return [Contrast::Api::Settings::AgentSettings, nil]
86
83
  def send_to_speedracer event
87
84
  ensure_startup!
@@ -131,8 +128,7 @@ module Contrast
131
128
 
132
129
  # Log the startup message we're sending to SpeedRacer
133
130
  #
134
- # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of
135
- # Contrast::Api::Dtm::Message|Contrast::Api::Dtm::Activity
131
+ # @param event [Contrast::Api::Dtm] One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
136
132
  def log_send_event event
137
133
  logger.debug('Immediately sending event.', event_id: event.__id__, event_type: event.cs__class.cs__name)
138
134
  end
@@ -41,12 +41,11 @@ module Contrast
41
41
  #
42
42
  # @param msg [Contrast::Api::Dtm::AgentStartup]
43
43
  def config! msg
44
- msg.version = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.server.version)
45
- msg.server_tags = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.server.tags)
46
- msg.library_tags = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.inventory.tags)
47
- msg.environment = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.server.environment)
48
- msg.application_tags =
49
- Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.application.tags)
44
+ msg.version = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.server.version)
45
+ msg.server_tags = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.server.tags)
46
+ msg.library_tags = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.inventory.tags)
47
+ msg.environment = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.server.environment)
48
+ msg.application_tags = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.application.tags)
50
49
  end
51
50
  end
52
51
  end
@@ -31,7 +31,8 @@ module Contrast
31
31
  {
32
32
  modes_by_id: translated_protection_mode_by_id,
33
33
  exclusion_matchers: translated_exclusions,
34
- disabled_assess_rules: disabled_assess_rules
34
+ disabled_assess_rules: disabled_assess_rules,
35
+ session_id: session_id
35
36
  }
36
37
  end
37
38
  end
@@ -24,12 +24,12 @@ module Contrast
24
24
  # @return [Contrast::Api::Dtm::ApplicationCreate]
25
25
  def build
26
26
  msg = new
27
- msg.code = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.application.code)
28
- msg.group = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.application.group)
29
- msg.metadata = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.application.metadata)
27
+ msg.code = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.application.code)
28
+ msg.group = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.application.group)
29
+ msg.metadata = Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.application.metadata)
30
30
  msg.mode = Contrast::Api::Dtm::InstrumentationMode.build
31
31
  msg.app_version =
32
- Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.root.application.version.to_s) # rubocop:disable Layout/AssignmentIndentation Layout/FirstArgumentIndentation:
32
+ Contrast::Utils::StringUtils.protobuf_format(::Contrast::CONFIG.application.version.to_s) # rubocop:disable Layout/AssignmentIndentation Layout/FirstArgumentIndentation:
33
33
  session!(msg)
34
34
  msg
35
35
  end
@@ -41,10 +41,10 @@ module Contrast
41
41
  # @param msg [Contrast::Api::Dtm::ApplicationCreate]
42
42
  def session! msg
43
43
  msg.session_id = Contrast::Utils::StringUtils.protobuf_format(
44
- ::Contrast::CONFIG.root.application.session_id,
44
+ ::Contrast::CONFIG.application.session_id,
45
45
  truncate: false)
46
46
  msg.session_metadata = Contrast::Utils::StringUtils.protobuf_format(
47
- ::Contrast::CONFIG.root.application.session_metadata,
47
+ ::Contrast::CONFIG.application.session_metadata,
48
48
  truncate: false)
49
49
  end
50
50
  end
@@ -23,12 +23,8 @@ module Contrast
23
23
  self.agent_startup = event
24
24
  when Contrast::Api::Dtm::ApplicationCreate
25
25
  self.application_create = event
26
- when Contrast::Api::Dtm::Activity
27
- self.activity = event
28
26
  when Contrast::Api::Dtm::HttpRequest
29
27
  self.prefilter = event
30
- when Contrast::Api::Dtm::HttpResponse
31
- self.postfilter = event
32
28
  when Contrast::Api::Dtm::Poll
33
29
  self.poll = event
34
30
  else
@@ -26,14 +26,9 @@ module Contrast
26
26
  {
27
27
  timestamp: Time.at(result.timestamp_ms).iso8601,
28
28
  user_input: result.user_input,
29
- brute_force: result.brute_force,
30
29
  bot_blocker: result.bot_blocker,
31
30
  cmdi: result.cmdi,
32
- csrf: result.csrf,
33
- cve: result.cve,
34
31
  untrusted_deserialization: result.untrusted_deserialization,
35
- el_injection: result.el_injection,
36
- mark_of_the_beast: result.mark_of_the_beast,
37
32
  padding_oracle: result.padding_oracle,
38
33
  path_traversal: result.path_traversal,
39
34
  re_dos: result.re_dos,
@@ -45,7 +40,6 @@ module Contrast
45
40
  no_sqli: result.no_sqli,
46
41
  method_tampering: result.method_tampering,
47
42
  path_traversal_semantic: result.path_traversal_semantic,
48
- ssjs: result.ssjs,
49
43
  ip_denylist: result.ip_denylist
50
44
  }
51
45
  end
@@ -12,15 +12,9 @@ end
12
12
  require 'contrast/api/decorators/message'
13
13
  require 'contrast/api/decorators/agent_startup'
14
14
  require 'contrast/api/decorators/application_startup'
15
- require 'contrast/api/decorators/architecture_component'
16
15
  require 'contrast/api/decorators/input_analysis'
17
16
  require 'contrast/api/decorators/application_settings'
18
17
  require 'contrast/api/decorators/server_features'
19
- require 'contrast/api/decorators/route_coverage'
20
- require 'contrast/api/decorators/trace_event_object'
21
- require 'contrast/api/decorators/trace_event_signature'
22
- require 'contrast/api/decorators/trace_taint_range'
23
- require 'contrast/api/decorators/trace_event'
24
18
  require 'contrast/api/decorators/rasp_rule_sample'
25
19
  require 'contrast/api/decorators/user_input'
26
20
  require 'contrast/api/decorators/address'