datadog 2.12.1 → 2.17.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 (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +154 -2
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +16 -14
  4. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  5. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  6. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  7. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
  9. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  11. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
  12. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  13. data/ext/datadog_profiling_native_extension/stack_recorder.c +23 -23
  14. data/ext/libdatadog_api/crashtracker.c +11 -12
  15. data/ext/libdatadog_api/crashtracker.h +5 -0
  16. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  17. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  18. data/ext/libdatadog_api/init.c +15 -0
  19. data/ext/libdatadog_api/library_config.c +122 -0
  20. data/ext/libdatadog_api/library_config.h +19 -0
  21. data/ext/libdatadog_api/macos_development.md +3 -3
  22. data/ext/libdatadog_api/process_discovery.c +117 -0
  23. data/ext/libdatadog_api/process_discovery.h +5 -0
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  26. data/lib/datadog/appsec/actions_handler.rb +24 -2
  27. data/lib/datadog/appsec/anonymizer.rb +16 -0
  28. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  29. data/lib/datadog/appsec/api_security.rb +9 -0
  30. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  31. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  32. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  33. data/lib/datadog/appsec/autoload.rb +1 -1
  34. data/lib/datadog/appsec/component.rb +29 -20
  35. data/lib/datadog/appsec/compressed_json.rb +40 -0
  36. data/lib/datadog/appsec/configuration/settings.rb +93 -28
  37. data/lib/datadog/appsec/context.rb +1 -1
  38. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  39. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  40. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  41. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  42. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  43. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  44. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  45. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  46. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  47. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  48. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  49. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  50. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  51. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  52. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  53. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  54. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  55. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  56. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  57. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  58. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +49 -32
  59. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  60. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +19 -18
  61. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  62. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  63. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  64. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  65. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  66. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  67. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  68. data/lib/datadog/appsec/event.rb +96 -135
  69. data/lib/datadog/appsec/ext.rb +4 -2
  70. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  71. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  72. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  73. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  74. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  75. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  76. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  77. data/lib/datadog/appsec/processor.rb +1 -1
  78. data/lib/datadog/appsec/remote.rb +23 -11
  79. data/lib/datadog/appsec/response.rb +6 -6
  80. data/lib/datadog/appsec/security_engine/runner.rb +3 -3
  81. data/lib/datadog/appsec/security_event.rb +39 -0
  82. data/lib/datadog/appsec/utils.rb +0 -2
  83. data/lib/datadog/appsec.rb +1 -1
  84. data/lib/datadog/core/buffer/random.rb +18 -2
  85. data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
  86. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  87. data/lib/datadog/core/configuration/components.rb +50 -31
  88. data/lib/datadog/core/configuration/components_state.rb +23 -0
  89. data/lib/datadog/core/configuration/ext.rb +4 -0
  90. data/lib/datadog/core/configuration/option.rb +79 -43
  91. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  92. data/lib/datadog/core/configuration/options.rb +3 -3
  93. data/lib/datadog/core/configuration/settings.rb +68 -35
  94. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  95. data/lib/datadog/core/configuration.rb +40 -16
  96. data/lib/datadog/core/crashtracking/component.rb +3 -10
  97. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  98. data/lib/datadog/core/encoding.rb +1 -1
  99. data/lib/datadog/core/environment/agent_info.rb +4 -3
  100. data/lib/datadog/core/environment/cgroup.rb +10 -12
  101. data/lib/datadog/core/environment/container.rb +38 -40
  102. data/lib/datadog/core/environment/ext.rb +6 -6
  103. data/lib/datadog/core/environment/git.rb +1 -0
  104. data/lib/datadog/core/environment/identity.rb +3 -3
  105. data/lib/datadog/core/environment/platform.rb +3 -3
  106. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  107. data/lib/datadog/core/error.rb +11 -9
  108. data/lib/datadog/core/logger.rb +2 -2
  109. data/lib/datadog/core/metrics/client.rb +20 -21
  110. data/lib/datadog/core/metrics/logging.rb +5 -5
  111. data/lib/datadog/core/process_discovery.rb +32 -0
  112. data/lib/datadog/core/rate_limiter.rb +4 -2
  113. data/lib/datadog/core/remote/client.rb +40 -32
  114. data/lib/datadog/core/remote/component.rb +6 -9
  115. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  116. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  117. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  118. data/lib/datadog/core/remote/negotiation.rb +9 -9
  119. data/lib/datadog/core/remote/transport/config.rb +4 -3
  120. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  121. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  122. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  123. data/lib/datadog/core/remote/transport/http.rb +22 -57
  124. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  125. data/lib/datadog/core/runtime/metrics.rb +12 -5
  126. data/lib/datadog/core/telemetry/component.rb +78 -53
  127. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  128. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  129. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  130. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  131. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  132. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  133. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  134. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  135. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  136. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  137. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  138. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  139. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  140. data/lib/datadog/core/telemetry/event.rb +17 -472
  141. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  142. data/lib/datadog/core/telemetry/logger.rb +1 -1
  143. data/lib/datadog/core/telemetry/metric.rb +8 -8
  144. data/lib/datadog/core/telemetry/request.rb +4 -4
  145. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  146. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  147. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  148. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  149. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  150. data/lib/datadog/core/telemetry/worker.rb +90 -24
  151. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  152. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  153. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  154. data/lib/datadog/core/transport/http/builder.rb +18 -16
  155. data/lib/datadog/core/transport/http.rb +39 -2
  156. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  157. data/lib/datadog/core/utils/duration.rb +32 -32
  158. data/lib/datadog/core/utils/forking.rb +2 -2
  159. data/lib/datadog/core/utils/network.rb +6 -6
  160. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  161. data/lib/datadog/core/utils/time.rb +20 -0
  162. data/lib/datadog/core/utils/truncation.rb +21 -0
  163. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  164. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  165. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  166. data/lib/datadog/core/worker.rb +1 -1
  167. data/lib/datadog/core/workers/async.rb +29 -12
  168. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  169. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  170. data/lib/datadog/core.rb +8 -0
  171. data/lib/datadog/di/boot.rb +34 -0
  172. data/lib/datadog/di/component.rb +0 -2
  173. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  174. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  175. data/lib/datadog/di/remote.rb +2 -0
  176. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  177. data/lib/datadog/di/transport/http/api.rb +2 -12
  178. data/lib/datadog/di/transport/http/client.rb +4 -3
  179. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  180. data/lib/datadog/di/transport/http/input.rb +7 -34
  181. data/lib/datadog/di/transport/http.rb +14 -62
  182. data/lib/datadog/di/transport/input.rb +4 -3
  183. data/lib/datadog/di/utils.rb +5 -0
  184. data/lib/datadog/di.rb +5 -32
  185. data/lib/datadog/error_tracking/collector.rb +87 -0
  186. data/lib/datadog/error_tracking/component.rb +167 -0
  187. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  188. data/lib/datadog/error_tracking/configuration.rb +11 -0
  189. data/lib/datadog/error_tracking/ext.rb +18 -0
  190. data/lib/datadog/error_tracking/extensions.rb +16 -0
  191. data/lib/datadog/error_tracking/filters.rb +77 -0
  192. data/lib/datadog/error_tracking.rb +18 -0
  193. data/lib/datadog/kit/appsec/events.rb +12 -0
  194. data/lib/datadog/kit/identity.rb +5 -1
  195. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  196. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  197. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  198. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  199. data/lib/datadog/opentelemetry.rb +2 -1
  200. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  201. data/lib/datadog/profiling/collectors/info.rb +3 -0
  202. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  203. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  204. data/lib/datadog/profiling/exporter.rb +3 -4
  205. data/lib/datadog/profiling/ext.rb +0 -2
  206. data/lib/datadog/profiling/flush.rb +5 -8
  207. data/lib/datadog/profiling/http_transport.rb +5 -59
  208. data/lib/datadog/profiling/scheduler.rb +8 -1
  209. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  210. data/lib/datadog/profiling/tag_builder.rb +1 -5
  211. data/lib/datadog/profiling.rb +6 -2
  212. data/lib/datadog/tracing/analytics.rb +1 -1
  213. data/lib/datadog/tracing/component.rb +15 -12
  214. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  215. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  216. data/lib/datadog/tracing/context_provider.rb +1 -1
  217. data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
  218. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
  219. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  220. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  221. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  222. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  223. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  224. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  225. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  226. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  227. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  228. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  229. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  230. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  231. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  232. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  233. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  234. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  235. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  236. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  237. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  238. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  239. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  240. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  241. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  242. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  243. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  244. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  245. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  246. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  247. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  248. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  249. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  250. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  251. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  252. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  253. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  254. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  255. data/lib/datadog/tracing/contrib/support.rb +28 -0
  256. data/lib/datadog/tracing/contrib.rb +1 -0
  257. data/lib/datadog/tracing/correlation.rb +9 -2
  258. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  259. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  260. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  261. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  262. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  263. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  264. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  265. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  266. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  267. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  268. data/lib/datadog/tracing/metadata.rb +2 -0
  269. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  270. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  271. data/lib/datadog/tracing/span.rb +10 -1
  272. data/lib/datadog/tracing/span_event.rb +1 -1
  273. data/lib/datadog/tracing/span_operation.rb +46 -16
  274. data/lib/datadog/tracing/sync_writer.rb +1 -2
  275. data/lib/datadog/tracing/trace_digest.rb +9 -2
  276. data/lib/datadog/tracing/trace_operation.rb +44 -24
  277. data/lib/datadog/tracing/trace_segment.rb +6 -4
  278. data/lib/datadog/tracing/tracer.rb +45 -5
  279. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  280. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  281. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  282. data/lib/datadog/tracing/transport/http.rb +11 -44
  283. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  284. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  285. data/lib/datadog/tracing/transport/traces.rb +26 -9
  286. data/lib/datadog/tracing/utils.rb +1 -1
  287. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  288. data/lib/datadog/tracing/writer.rb +2 -6
  289. data/lib/datadog/tracing.rb +16 -3
  290. data/lib/datadog/version.rb +2 -2
  291. data/lib/datadog.rb +2 -3
  292. metadata +80 -19
  293. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  294. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  295. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  296. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  297. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  298. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  299. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  300. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  301. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  302. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
3
+ require_relative '../ext'
4
4
  require_relative '../../../event'
5
+ require_relative '../../../security_event'
6
+ require_relative '../../../instrumentation/gateway'
5
7
 
6
8
  module Datadog
7
9
  module AppSec
@@ -17,11 +19,12 @@ module Datadog
17
19
  watch_request(gateway)
18
20
  watch_response(gateway)
19
21
  watch_request_body(gateway)
22
+ watch_request_finish(gateway)
20
23
  end
21
24
 
22
25
  def watch_request(gateway = Instrumentation.gateway)
23
26
  gateway.watch('rack.request', :appsec) do |stack, gateway_request|
24
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
27
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
25
28
 
26
29
  persistent_data = {
27
30
  'server.request.cookies' => gateway_request.cookies,
@@ -35,18 +38,15 @@ module Datadog
35
38
 
36
39
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
37
40
 
38
- if result.match?
39
- Datadog::AppSec::Event.tag_and_keep!(context, result)
40
-
41
- context.events << {
42
- waf_result: result,
43
- trace: context.trace,
44
- span: context.span,
45
- request: gateway_request,
46
- actions: result.actions
47
- }
41
+ if result.match? || !result.derivatives.empty?
42
+ context.events.push(
43
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
44
+ )
45
+ end
48
46
 
49
- Datadog::AppSec::ActionsHandler.handle(result.actions)
47
+ if result.match?
48
+ AppSec::Event.tag_and_keep!(context, result)
49
+ AppSec::ActionsHandler.handle(result.actions)
50
50
  end
51
51
 
52
52
  stack.call(gateway_request.request)
@@ -66,17 +66,13 @@ module Datadog
66
66
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
67
67
 
68
68
  if result.match?
69
- Datadog::AppSec::Event.tag_and_keep!(context, result)
69
+ AppSec::Event.tag_and_keep!(context, result)
70
70
 
71
- context.events << {
72
- waf_result: result,
73
- trace: context.trace,
74
- span: context.span,
75
- response: gateway_response,
76
- actions: result.actions
77
- }
71
+ context.events.push(
72
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
73
+ )
78
74
 
79
- Datadog::AppSec::ActionsHandler.handle(result.actions)
75
+ AppSec::ActionsHandler.handle(result.actions)
80
76
  end
81
77
 
82
78
  stack.call(gateway_response.response)
@@ -85,7 +81,7 @@ module Datadog
85
81
 
86
82
  def watch_request_body(gateway = Instrumentation.gateway)
87
83
  gateway.watch('rack.request.body', :appsec) do |stack, gateway_request|
88
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
84
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
89
85
 
90
86
  persistent_data = {
91
87
  'server.request.body' => gateway_request.form_hash
@@ -94,17 +90,38 @@ module Datadog
94
90
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
95
91
 
96
92
  if result.match?
97
- Datadog::AppSec::Event.tag_and_keep!(context, result)
93
+ AppSec::Event.tag_and_keep!(context, result)
94
+
95
+ context.events.push(
96
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
97
+ )
98
+
99
+ AppSec::ActionsHandler.handle(result.actions)
100
+ end
101
+
102
+ stack.call(gateway_request.request)
103
+ end
104
+ end
105
+
106
+ # NOTE: In the current state we unable to substibe twice to the same
107
+ # event within the same group. Ideally this code should live
108
+ # somewhere closer to identity related monitor.
109
+ # WARNING: The Gateway is a subject of refactoring
110
+ def watch_request_finish(gateway = Instrumentation.gateway)
111
+ gateway.watch('rack.request.finish', :appsec) do |stack, gateway_request|
112
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
113
+
114
+ if context.span.nil? || !gateway.pushed?('appsec.events.user_lifecycle')
115
+ next stack.call(gateway_request.request)
116
+ end
98
117
 
99
- context.events << {
100
- waf_result: result,
101
- trace: context.trace,
102
- span: context.span,
103
- request: gateway_request,
104
- actions: result.actions
105
- }
118
+ gateway_request.headers.each do |name, value|
119
+ if !Ext::COLLECTABLE_REQUEST_HEADERS.include?(name) &&
120
+ !Ext::IDENTITY_COLLECTABLE_REQUEST_HEADERS.include?(name)
121
+ next
122
+ end
106
123
 
107
- Datadog::AppSec::ActionsHandler.handle(result.actions)
124
+ context.span["http.request.headers.#{name}"] ||= value
108
125
  end
109
126
 
110
127
  stack.call(gateway_request.request)
@@ -19,7 +19,7 @@ module Datadog
19
19
  register_as :rack, auto_patch: false
20
20
 
21
21
  def self.version
22
- Gem.loaded_specs['rack'] && Gem.loaded_specs['rack'].version
22
+ Gem.loaded_specs['rack']&.version
23
23
  end
24
24
 
25
25
  def self.loaded?
@@ -4,9 +4,12 @@ require 'json'
4
4
 
5
5
  require_relative 'gateway/request'
6
6
  require_relative 'gateway/response'
7
- require_relative '../../instrumentation/gateway'
8
- require_relative '../../processor'
7
+
8
+ require_relative '../../event'
9
9
  require_relative '../../response'
10
+ require_relative '../../processor'
11
+ require_relative '../../security_event'
12
+ require_relative '../../instrumentation/gateway'
10
13
 
11
14
  require_relative '../../../tracing/client_ip'
12
15
  require_relative '../../../tracing/contrib/rack/header_collection'
@@ -36,7 +39,7 @@ module Datadog
36
39
  @rack_headers = {}
37
40
  end
38
41
 
39
- # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
42
+ # rubocop:disable Metrics/MethodLength
40
43
  def call(env)
41
44
  return @app.call(env) unless Datadog::AppSec.enabled?
42
45
 
@@ -77,6 +80,8 @@ module Datadog
77
80
  gateway_response = nil
78
81
 
79
82
  interrupt_params = catch(::Datadog::AppSec::Ext::INTERRUPT) do
83
+ # TODO: This event should be renamed into `rack.request.start` to
84
+ # reflect that it's the beginning of the request-cycle
80
85
  http_response, _gateway_request = Instrumentation.gateway.push('rack.request', gateway_request) do
81
86
  @app.call(env)
82
87
  end
@@ -85,6 +90,7 @@ module Datadog
85
90
  http_response[2], http_response[0], http_response[1], context: ctx
86
91
  )
87
92
 
93
+ Instrumentation.gateway.push('rack.request.finish', gateway_request)
88
94
  Instrumentation.gateway.push('rack.response', gateway_response)
89
95
 
90
96
  nil
@@ -94,20 +100,13 @@ module Datadog
94
100
  http_response = AppSec::Response.from_interrupt_params(interrupt_params, env['HTTP_ACCEPT']).to_rack
95
101
  end
96
102
 
97
- if AppSec.api_security_enabled?
98
- ctx.events << {
99
- trace: ctx.trace,
100
- span: ctx.span,
101
- waf_result: ctx.extract_schema,
102
- }
103
- end
104
-
105
- ctx.events.each do |e|
106
- e[:response] ||= gateway_response
107
- e[:request] ||= gateway_request
103
+ if AppSec.perform_api_security_check?
104
+ ctx.events.push(
105
+ AppSec::SecurityEvent.new(ctx.extract_schema, trace: ctx.trace, span: ctx.span)
106
+ )
108
107
  end
109
108
 
110
- AppSec::Event.record(ctx.span, *ctx.events)
109
+ AppSec::Event.record(ctx, request: gateway_request, response: gateway_response)
111
110
 
112
111
  http_response
113
112
  ensure
@@ -116,7 +115,7 @@ module Datadog
116
115
  Datadog::AppSec::Context.deactivate
117
116
  end
118
117
  end
119
- # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
118
+ # rubocop:enable Metrics/MethodLength
120
119
 
121
120
  private
122
121
 
@@ -140,6 +139,7 @@ module Datadog
140
139
  Datadog::Tracing.active_span
141
140
  end
142
141
 
142
+ # standard:disable Metrics/MethodLength
143
143
  def add_appsec_tags(processor, context)
144
144
  span = context.span
145
145
  trace = context.trace
@@ -147,8 +147,6 @@ module Datadog
147
147
  return unless trace && span
148
148
 
149
149
  span.set_metric(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1)
150
- # We add this tag when ASM standalone is enabled to make sure we don't bill APM
151
- span.set_metric(Datadog::AppSec::Ext::TAG_APM_ENABLED, 0) if Datadog.configuration.appsec.standalone.enabled
152
150
  span.set_tag('_dd.runtime_family', 'ruby')
153
151
  span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)
154
152
 
@@ -176,7 +174,9 @@ module Datadog
176
174
  end
177
175
  end
178
176
  end
177
+ # standard:enable Metrics/MethodLength
179
178
 
179
+ # standard:disable Metrics/MethodLength
180
180
  def add_request_tags(context, env)
181
181
  span = context.span
182
182
 
@@ -199,6 +199,7 @@ module Datadog
199
199
  )
200
200
  end
201
201
  end
202
+ # standard:enable Metrics/MethodLength
202
203
 
203
204
  def to_rack_header(header)
204
205
  @rack_headers[header] ||= Datadog::Tracing::Contrib::Rack::Header.to_rack_header(header)
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
4
3
  require_relative '../../../event'
4
+ require_relative '../../../security_event'
5
+ require_relative '../../../instrumentation/gateway'
5
6
 
6
7
  module Datadog
7
8
  module AppSec
@@ -19,7 +20,7 @@ module Datadog
19
20
 
20
21
  def watch_request_action(gateway = Instrumentation.gateway)
21
22
  gateway.watch('rails.request.action', :appsec) do |stack, gateway_request|
22
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
23
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
23
24
 
24
25
  persistent_data = {
25
26
  'server.request.body' => gateway_request.parsed_body,
@@ -28,18 +29,15 @@ module Datadog
28
29
 
29
30
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
30
31
 
31
- if result.match?
32
- Datadog::AppSec::Event.tag_and_keep!(context, result)
33
-
34
- context.events << {
35
- waf_result: result,
36
- trace: context.trace,
37
- span: context.span,
38
- request: gateway_request,
39
- actions: result.actions
40
- }
32
+ if result.match? || !result.derivatives.empty?
33
+ context.events.push(
34
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
35
+ )
36
+ end
41
37
 
42
- Datadog::AppSec::ActionsHandler.handle(result.actions)
38
+ if result.match?
39
+ AppSec::Event.tag_and_keep!(context, result)
40
+ AppSec::ActionsHandler.handle(result.actions)
43
41
  end
44
42
 
45
43
  stack.call(gateway_request.request)
@@ -18,7 +18,7 @@ module Datadog
18
18
  register_as :rails, auto_patch: false
19
19
 
20
20
  def self.version
21
- Gem.loaded_specs['railties'] && Gem.loaded_specs['railties'].version
21
+ Gem.loaded_specs['railties']&.version
22
22
  end
23
23
 
24
24
  def self.loaded?
@@ -96,27 +96,27 @@ module Datadog
96
96
  # find tracer middleware reference in Rails::Configuration::MiddlewareStackProxy
97
97
  app.middleware.instance_variable_get(:@operations).each do |operation|
98
98
  args = case operation
99
- when Array
100
- # rails 5.2
101
- _op, args = operation
102
- args
103
- when Proc
104
- if operation.binding.local_variables.include?(:args)
105
- # rails 6.0, 6.1
106
- operation.binding.local_variable_get(:args)
107
- else
108
- # rails 7.0 uses ... to pass args
109
- args_getter = Class.new do
110
- def method_missing(_op, *args) # rubocop:disable Style/MissingRespondToMissing
111
- args
112
- end
113
- end.new
114
- operation.call(args_getter)
115
- end
116
- else
117
- # unknown, pass through
118
- []
119
- end
99
+ when Array
100
+ # rails 5.2
101
+ _op, args = operation
102
+ args
103
+ when Proc
104
+ if operation.binding.local_variables.include?(:args)
105
+ # rails 6.0, 6.1
106
+ operation.binding.local_variable_get(:args)
107
+ else
108
+ # rails 7.0 uses ... to pass args
109
+ args_getter = Class.new do
110
+ def method_missing(_op, *args) # standard:disable Style/MissingRespondToMissing
111
+ args
112
+ end
113
+ end.new
114
+ operation.call(args_getter)
115
+ end
116
+ else
117
+ # unknown, pass through
118
+ []
119
+ end
120
120
 
121
121
  found = true if args.include?(middleware)
122
122
  end
@@ -20,7 +20,7 @@ module Datadog
20
20
  end
21
21
 
22
22
  def self.version
23
- Gem.loaded_specs['rest-client'] && Gem.loaded_specs['rest-client'].version
23
+ Gem.loaded_specs['rest-client']&.version
24
24
  end
25
25
 
26
26
  def self.loaded?
@@ -1,6 +1,9 @@
1
1
  # rubocop:disable Naming/FileName
2
2
  # frozen_string_literal: true
3
3
 
4
+ require_relative '../../event'
5
+ require_relative '../../security_event'
6
+
4
7
  module Datadog
5
8
  module AppSec
6
9
  module Contrib
@@ -12,24 +15,20 @@ module Datadog
12
15
 
13
16
  context = AppSec.active_context
14
17
 
15
- ephemeral_data = { 'server.io.net.url' => url }
18
+ ephemeral_data = {'server.io.net.url' => url}
16
19
  result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
17
20
 
18
21
  if result.match?
19
- Datadog::AppSec::Event.tag_and_keep!(context, result)
22
+ AppSec::Event.tag_and_keep!(context, result)
20
23
 
21
- context.events << {
22
- waf_result: result,
23
- trace: context.trace,
24
- span: context.span,
25
- request_url: url,
26
- actions: result.actions
27
- }
24
+ context.events.push(
25
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
26
+ )
28
27
 
29
- ActionsHandler.handle(result.actions)
28
+ AppSec::ActionsHandler.handle(result.actions)
30
29
  end
31
30
 
32
- super(&block)
31
+ super
33
32
  end
34
33
  end
35
34
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
4
3
  require_relative '../../../event'
4
+ require_relative '../../../security_event'
5
+ require_relative '../../../instrumentation/gateway'
5
6
 
6
7
  module Datadog
7
8
  module AppSec
@@ -20,7 +21,7 @@ module Datadog
20
21
 
21
22
  def watch_request_dispatch(gateway = Instrumentation.gateway)
22
23
  gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request|
23
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
24
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
24
25
 
25
26
  persistent_data = {
26
27
  'server.request.body' => gateway_request.form_hash
@@ -28,18 +29,15 @@ module Datadog
28
29
 
29
30
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
30
31
 
31
- if result.match?
32
- Datadog::AppSec::Event.tag_and_keep!(context, result)
33
-
34
- context.events << {
35
- waf_result: result,
36
- trace: context.trace,
37
- span: context.span,
38
- request: gateway_request,
39
- actions: result.actions
40
- }
32
+ if result.match? || !result.derivatives.empty?
33
+ context.events.push(
34
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
35
+ )
36
+ end
41
37
 
42
- Datadog::AppSec::ActionsHandler.handle(result.actions)
38
+ if result.match?
39
+ AppSec::Event.tag_and_keep!(context, result)
40
+ AppSec::ActionsHandler.handle(result.actions)
43
41
  end
44
42
 
45
43
  stack.call(gateway_request.request)
@@ -48,7 +46,7 @@ module Datadog
48
46
 
49
47
  def watch_request_routed(gateway = Instrumentation.gateway)
50
48
  gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)|
51
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
49
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
52
50
 
53
51
  persistent_data = {
54
52
  'server.request.path_params' => gateway_route_params.params
@@ -57,17 +55,13 @@ module Datadog
57
55
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
58
56
 
59
57
  if result.match?
60
- Datadog::AppSec::Event.tag_and_keep!(context, result)
58
+ AppSec::Event.tag_and_keep!(context, result)
61
59
 
62
- context.events << {
63
- waf_result: result,
64
- trace: context.trace,
65
- span: context.span,
66
- request: gateway_request,
67
- actions: result.actions
68
- }
60
+ context.events.push(
61
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
62
+ )
69
63
 
70
- Datadog::AppSec::ActionsHandler.handle(result.actions)
64
+ AppSec::ActionsHandler.handle(result.actions)
71
65
  end
72
66
 
73
67
  stack.call(gateway_request.request)
@@ -18,7 +18,7 @@ module Datadog
18
18
  register_as :sinatra
19
19
 
20
20
  def self.version
21
- Gem.loaded_specs['sinatra'] && Gem.loaded_specs['sinatra'].version
21
+ Gem.loaded_specs['sinatra']&.version
22
22
  end
23
23
 
24
24
  def self.loaded?