datadog 2.12.0 → 2.22.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 (570) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +348 -1
  3. data/README.md +0 -1
  4. data/ext/LIBDATADOG_DEVELOPMENT.md +60 -0
  5. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +63 -56
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_stack.c +263 -76
  8. data/ext/datadog_profiling_native_extension/collectors_stack.h +20 -3
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +78 -26
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  13. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  15. data/ext/datadog_profiling_native_extension/extconf.rb +10 -0
  16. data/ext/datadog_profiling_native_extension/heap_recorder.c +247 -364
  17. data/ext/datadog_profiling_native_extension/heap_recorder.h +4 -6
  18. data/ext/datadog_profiling_native_extension/http_transport.c +60 -94
  19. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  20. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +41 -21
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -4
  23. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  24. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -13
  25. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -11
  26. data/ext/datadog_profiling_native_extension/stack_recorder.c +173 -76
  27. data/ext/libdatadog_api/crashtracker.c +11 -12
  28. data/ext/libdatadog_api/crashtracker.h +5 -0
  29. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  30. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  31. data/ext/libdatadog_api/ddsketch.c +106 -0
  32. data/ext/libdatadog_api/extconf.rb +5 -3
  33. data/ext/libdatadog_api/init.c +18 -0
  34. data/ext/libdatadog_api/library_config.c +172 -0
  35. data/ext/libdatadog_api/library_config.h +25 -0
  36. data/ext/libdatadog_api/process_discovery.c +118 -0
  37. data/ext/libdatadog_api/process_discovery.h +5 -0
  38. data/ext/libdatadog_extconf_helpers.rb +15 -5
  39. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  40. data/lib/datadog/appsec/actions_handler.rb +24 -2
  41. data/lib/datadog/appsec/anonymizer.rb +16 -0
  42. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  43. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
  44. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
  45. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  46. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  47. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  48. data/lib/datadog/appsec/api_security/route_extractor.rb +75 -0
  49. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  50. data/lib/datadog/appsec/api_security.rb +23 -0
  51. data/lib/datadog/appsec/assets/waf_rules/README.md +44 -5
  52. data/lib/datadog/appsec/assets/waf_rules/recommended.json +601 -74
  53. data/lib/datadog/appsec/assets/waf_rules/strict.json +48 -75
  54. data/lib/datadog/appsec/autoload.rb +2 -2
  55. data/lib/datadog/appsec/component.rb +46 -71
  56. data/lib/datadog/appsec/compressed_json.rb +40 -0
  57. data/lib/datadog/appsec/configuration/settings.rb +162 -30
  58. data/lib/datadog/appsec/context.rb +30 -7
  59. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +35 -18
  60. data/lib/datadog/appsec/contrib/active_record/integration.rb +2 -2
  61. data/lib/datadog/appsec/contrib/active_record/patcher.rb +62 -11
  62. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  63. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  64. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  65. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  66. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  67. data/lib/datadog/appsec/contrib/devise/patcher.rb +34 -23
  68. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +103 -0
  69. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +70 -0
  70. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  71. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  72. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  73. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +11 -12
  74. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  75. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +10 -10
  76. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +10 -9
  77. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  78. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  79. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +53 -31
  80. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  81. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -44
  82. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +35 -11
  83. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  84. data/lib/datadog/appsec/contrib/rails/patcher.rb +65 -47
  85. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +27 -0
  86. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +33 -0
  87. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  88. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +12 -12
  89. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +45 -22
  90. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  91. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +8 -18
  92. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +31 -0
  93. data/lib/datadog/appsec/event.rb +91 -147
  94. data/lib/datadog/appsec/ext.rb +4 -2
  95. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +23 -2
  96. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  97. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  98. data/lib/datadog/appsec/metrics/collector.rb +23 -3
  99. data/lib/datadog/appsec/metrics/telemetry.rb +2 -2
  100. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +29 -0
  101. data/lib/datadog/appsec/metrics.rb +1 -0
  102. data/lib/datadog/appsec/monitor/gateway/watcher.rb +49 -14
  103. data/lib/datadog/appsec/processor/rule_loader.rb +30 -33
  104. data/lib/datadog/appsec/remote.rb +43 -59
  105. data/lib/datadog/appsec/response.rb +6 -6
  106. data/lib/datadog/appsec/security_engine/engine.rb +176 -0
  107. data/lib/datadog/appsec/security_engine/result.rb +44 -9
  108. data/lib/datadog/appsec/security_engine/runner.rb +44 -21
  109. data/lib/datadog/appsec/security_event.rb +37 -0
  110. data/lib/datadog/appsec/thread_safe_ref.rb +61 -0
  111. data/lib/datadog/appsec/trace_keeper.rb +24 -0
  112. data/lib/datadog/appsec/utils/hash_coercion.rb +23 -0
  113. data/lib/datadog/appsec/utils.rb +0 -2
  114. data/lib/datadog/appsec.rb +5 -15
  115. data/lib/datadog/auto_instrument_base.rb +2 -1
  116. data/lib/datadog/core/buffer/random.rb +18 -2
  117. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  118. data/lib/datadog/core/configuration/agent_settings_resolver.rb +8 -50
  119. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  120. data/lib/datadog/core/configuration/components.rb +69 -37
  121. data/lib/datadog/core/configuration/components_state.rb +23 -0
  122. data/lib/datadog/core/configuration/config_helper.rb +100 -0
  123. data/lib/datadog/core/configuration/deprecations.rb +36 -0
  124. data/lib/datadog/core/configuration/ext.rb +4 -1
  125. data/lib/datadog/core/configuration/option.rb +117 -77
  126. data/lib/datadog/core/configuration/option_definition.rb +5 -14
  127. data/lib/datadog/core/configuration/options.rb +15 -13
  128. data/lib/datadog/core/configuration/settings.rb +117 -48
  129. data/lib/datadog/core/configuration/stable_config.rb +32 -0
  130. data/lib/datadog/core/configuration/supported_configurations.rb +337 -0
  131. data/lib/datadog/core/configuration.rb +40 -16
  132. data/lib/datadog/core/crashtracking/component.rb +3 -10
  133. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  134. data/lib/datadog/core/ddsketch.rb +21 -0
  135. data/lib/datadog/core/deprecations.rb +2 -2
  136. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  137. data/lib/datadog/core/encoding.rb +1 -1
  138. data/lib/datadog/core/environment/agent_info.rb +4 -3
  139. data/lib/datadog/core/environment/cgroup.rb +10 -12
  140. data/lib/datadog/core/environment/container.rb +38 -40
  141. data/lib/datadog/core/environment/ext.rb +6 -8
  142. data/lib/datadog/core/environment/git.rb +3 -2
  143. data/lib/datadog/core/environment/identity.rb +3 -3
  144. data/lib/datadog/core/environment/platform.rb +3 -3
  145. data/lib/datadog/core/environment/variable_helpers.rb +4 -4
  146. data/lib/datadog/core/environment/yjit.rb +2 -1
  147. data/lib/datadog/core/error.rb +11 -9
  148. data/lib/datadog/core/logger.rb +2 -2
  149. data/lib/datadog/core/metrics/client.rb +29 -29
  150. data/lib/datadog/core/metrics/logging.rb +5 -5
  151. data/lib/datadog/core/pin.rb +4 -8
  152. data/lib/datadog/core/process_discovery/tracer_memfd.rb +13 -0
  153. data/lib/datadog/core/process_discovery.rb +61 -0
  154. data/lib/datadog/core/rate_limiter.rb +4 -2
  155. data/lib/datadog/core/remote/client.rb +44 -35
  156. data/lib/datadog/core/remote/component.rb +12 -17
  157. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  158. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  159. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  160. data/lib/datadog/core/remote/negotiation.rb +9 -9
  161. data/lib/datadog/core/remote/transport/config.rb +4 -3
  162. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  163. data/lib/datadog/core/remote/transport/http/config.rb +27 -37
  164. data/lib/datadog/core/remote/transport/http/negotiation.rb +7 -33
  165. data/lib/datadog/core/remote/transport/http.rb +25 -89
  166. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  167. data/lib/datadog/core/runtime/ext.rb +0 -1
  168. data/lib/datadog/core/runtime/metrics.rb +12 -5
  169. data/lib/datadog/core/tag_builder.rb +56 -0
  170. data/lib/datadog/core/telemetry/component.rb +92 -52
  171. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  172. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  173. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  174. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  175. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  176. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  177. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  178. data/lib/datadog/core/telemetry/event/app_started.rb +287 -0
  179. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  180. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  181. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  182. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  183. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  184. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  185. data/lib/datadog/core/telemetry/event.rb +18 -472
  186. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  187. data/lib/datadog/core/telemetry/logger.rb +5 -4
  188. data/lib/datadog/core/telemetry/logging.rb +11 -5
  189. data/lib/datadog/core/telemetry/metric.rb +8 -8
  190. data/lib/datadog/core/telemetry/request.rb +4 -4
  191. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  192. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  193. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  194. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  195. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  196. data/lib/datadog/core/telemetry/worker.rb +90 -24
  197. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  198. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  199. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  200. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  201. data/lib/datadog/core/transport/http/builder.rb +19 -17
  202. data/lib/datadog/core/transport/http/env.rb +8 -0
  203. data/lib/datadog/core/transport/http.rb +75 -0
  204. data/lib/datadog/core/transport/response.rb +4 -1
  205. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  206. data/lib/datadog/core/utils/duration.rb +32 -32
  207. data/lib/datadog/core/utils/forking.rb +2 -2
  208. data/lib/datadog/core/utils/network.rb +25 -6
  209. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  210. data/lib/datadog/core/utils/time.rb +20 -0
  211. data/lib/datadog/core/utils/truncation.rb +21 -0
  212. data/lib/datadog/core/utils.rb +7 -0
  213. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  214. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  215. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  216. data/lib/datadog/core/worker.rb +1 -1
  217. data/lib/datadog/core/workers/async.rb +29 -12
  218. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  219. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  220. data/lib/datadog/core.rb +10 -0
  221. data/lib/datadog/di/boot.rb +43 -0
  222. data/lib/datadog/di/component.rb +21 -2
  223. data/lib/datadog/di/context.rb +70 -0
  224. data/lib/datadog/di/el/compiler.rb +164 -0
  225. data/lib/datadog/di/el/evaluator.rb +159 -0
  226. data/lib/datadog/di/el/expression.rb +42 -0
  227. data/lib/datadog/di/el.rb +5 -0
  228. data/lib/datadog/di/error.rb +25 -0
  229. data/lib/datadog/di/instrumenter.rb +132 -20
  230. data/lib/datadog/di/probe.rb +35 -15
  231. data/lib/datadog/di/probe_builder.rb +39 -1
  232. data/lib/datadog/di/probe_file_loader/railtie.rb +15 -0
  233. data/lib/datadog/di/probe_file_loader.rb +82 -0
  234. data/lib/datadog/di/probe_manager.rb +3 -2
  235. data/lib/datadog/di/probe_notification_builder.rb +61 -67
  236. data/lib/datadog/di/probe_notifier_worker.rb +25 -17
  237. data/lib/datadog/di/remote.rb +5 -5
  238. data/lib/datadog/di/serializer.rb +160 -8
  239. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  240. data/lib/datadog/di/transport/http/api.rb +2 -12
  241. data/lib/datadog/di/transport/http/client.rb +4 -3
  242. data/lib/datadog/di/transport/http/diagnostics.rb +7 -34
  243. data/lib/datadog/di/transport/http/input.rb +18 -35
  244. data/lib/datadog/di/transport/http.rb +15 -77
  245. data/lib/datadog/di/transport/input.rb +14 -5
  246. data/lib/datadog/di/utils.rb +5 -0
  247. data/lib/datadog/di.rb +0 -34
  248. data/lib/datadog/error_tracking/collector.rb +87 -0
  249. data/lib/datadog/error_tracking/component.rb +167 -0
  250. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  251. data/lib/datadog/error_tracking/configuration.rb +11 -0
  252. data/lib/datadog/error_tracking/ext.rb +18 -0
  253. data/lib/datadog/error_tracking/extensions.rb +16 -0
  254. data/lib/datadog/error_tracking/filters.rb +77 -0
  255. data/lib/datadog/error_tracking.rb +18 -0
  256. data/lib/datadog/kit/appsec/events/v2.rb +196 -0
  257. data/lib/datadog/kit/appsec/events.rb +17 -4
  258. data/lib/datadog/kit/identity.rb +22 -12
  259. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  260. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  261. data/lib/datadog/opentelemetry/api/context.rb +21 -6
  262. data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
  263. data/lib/datadog/opentelemetry/sdk/propagator.rb +4 -4
  264. data/lib/datadog/opentelemetry/sdk/span_processor.rb +8 -8
  265. data/lib/datadog/opentelemetry/sdk/trace/span.rb +15 -11
  266. data/lib/datadog/opentelemetry/trace.rb +4 -4
  267. data/lib/datadog/opentelemetry.rb +2 -1
  268. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  269. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +6 -0
  270. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  271. data/lib/datadog/profiling/collectors/info.rb +44 -0
  272. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  273. data/lib/datadog/profiling/component.rb +8 -9
  274. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  275. data/lib/datadog/profiling/exporter.rb +12 -7
  276. data/lib/datadog/profiling/ext.rb +2 -15
  277. data/lib/datadog/profiling/flush.rb +5 -8
  278. data/lib/datadog/profiling/http_transport.rb +8 -62
  279. data/lib/datadog/profiling/profiler.rb +2 -0
  280. data/lib/datadog/profiling/scheduler.rb +10 -2
  281. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  282. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  283. data/lib/datadog/profiling/tag_builder.rb +7 -41
  284. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  285. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  286. data/lib/datadog/profiling.rb +13 -10
  287. data/lib/datadog/single_step_instrument.rb +9 -0
  288. data/lib/datadog/tracing/analytics.rb +1 -1
  289. data/lib/datadog/tracing/buffer.rb +7 -7
  290. data/lib/datadog/tracing/component.rb +21 -29
  291. data/lib/datadog/tracing/configuration/dynamic.rb +6 -8
  292. data/lib/datadog/tracing/configuration/ext.rb +8 -4
  293. data/lib/datadog/tracing/configuration/settings.rb +50 -12
  294. data/lib/datadog/tracing/context.rb +2 -2
  295. data/lib/datadog/tracing/context_provider.rb +1 -1
  296. data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
  297. data/lib/datadog/tracing/contrib/action_cable/integration.rb +1 -1
  298. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +1 -1
  299. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +19 -4
  300. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  301. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  302. data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
  303. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  304. data/lib/datadog/tracing/contrib/active_job/event.rb +8 -8
  305. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  306. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  307. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  308. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  309. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  310. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  311. data/lib/datadog/tracing/contrib/active_job/integration.rb +1 -1
  312. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  313. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -3
  314. data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +1 -2
  315. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -1
  316. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  317. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +5 -5
  318. data/lib/datadog/tracing/contrib/active_record/integration.rb +2 -2
  319. data/lib/datadog/tracing/contrib/active_record/utils.rb +15 -15
  320. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +17 -8
  321. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  322. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  323. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  324. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +13 -0
  325. data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
  326. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +2 -1
  327. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +7 -9
  328. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -1
  329. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +12 -2
  330. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +8 -2
  331. data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -1
  332. data/lib/datadog/tracing/contrib/aws/service/base.rb +2 -1
  333. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +1 -1
  334. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +1 -1
  335. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +1 -1
  336. data/lib/datadog/tracing/contrib/aws/service/s3.rb +1 -1
  337. data/lib/datadog/tracing/contrib/aws/service/sns.rb +1 -1
  338. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +1 -1
  339. data/lib/datadog/tracing/contrib/aws/service/states.rb +1 -1
  340. data/lib/datadog/tracing/contrib/aws/services.rb +7 -7
  341. data/lib/datadog/tracing/contrib/component.rb +2 -2
  342. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
  343. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
  344. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
  345. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +1 -1
  346. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
  347. data/lib/datadog/tracing/contrib/configurable.rb +6 -6
  348. data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +4 -4
  349. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  350. data/lib/datadog/tracing/contrib/dalli/ext.rb +3 -2
  351. data/lib/datadog/tracing/contrib/dalli/integration.rb +1 -1
  352. data/lib/datadog/tracing/contrib/delayed_job/integration.rb +1 -1
  353. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +3 -2
  354. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +4 -4
  355. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +51 -53
  356. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +5 -5
  357. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +6 -7
  358. data/lib/datadog/tracing/contrib/ethon/ext.rb +3 -2
  359. data/lib/datadog/tracing/contrib/ethon/integration.rb +1 -1
  360. data/lib/datadog/tracing/contrib/excon/ext.rb +3 -2
  361. data/lib/datadog/tracing/contrib/excon/integration.rb +1 -1
  362. data/lib/datadog/tracing/contrib/excon/middleware.rb +7 -5
  363. data/lib/datadog/tracing/contrib/ext.rb +4 -3
  364. data/lib/datadog/tracing/contrib/extensions.rb +9 -9
  365. data/lib/datadog/tracing/contrib/faraday/ext.rb +3 -2
  366. data/lib/datadog/tracing/contrib/faraday/integration.rb +1 -1
  367. data/lib/datadog/tracing/contrib/faraday/middleware.rb +9 -5
  368. data/lib/datadog/tracing/contrib/grape/endpoint.rb +8 -8
  369. data/lib/datadog/tracing/contrib/grape/integration.rb +1 -1
  370. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  371. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  372. data/lib/datadog/tracing/contrib/graphql/integration.rb +1 -1
  373. data/lib/datadog/tracing/contrib/graphql/patcher.rb +2 -2
  374. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +84 -48
  375. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +15 -9
  376. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -3
  377. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
  378. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  379. data/lib/datadog/tracing/contrib/grpc/integration.rb +1 -1
  380. data/lib/datadog/tracing/contrib/hanami/ext.rb +2 -2
  381. data/lib/datadog/tracing/contrib/hanami/integration.rb +1 -1
  382. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -1
  383. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +9 -11
  384. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  385. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +4 -4
  386. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  387. data/lib/datadog/tracing/contrib/http/ext.rb +3 -2
  388. data/lib/datadog/tracing/contrib/http/instrumentation.rb +11 -15
  389. data/lib/datadog/tracing/contrib/httpclient/ext.rb +3 -2
  390. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +9 -19
  391. data/lib/datadog/tracing/contrib/httpclient/integration.rb +1 -1
  392. data/lib/datadog/tracing/contrib/httprb/ext.rb +3 -2
  393. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +11 -19
  394. data/lib/datadog/tracing/contrib/httprb/integration.rb +1 -1
  395. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
  396. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +1 -1
  397. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +1 -1
  398. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +1 -1
  399. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +1 -1
  400. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +1 -1
  401. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +1 -1
  402. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +1 -1
  403. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -1
  404. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -1
  405. data/lib/datadog/tracing/contrib/kafka/integration.rb +1 -1
  406. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  407. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  408. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  409. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  410. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  411. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  412. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  413. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -1
  414. data/lib/datadog/tracing/contrib/lograge/integration.rb +1 -1
  415. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  416. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +9 -1
  417. data/lib/datadog/tracing/contrib/mongodb/ext.rb +2 -1
  418. data/lib/datadog/tracing/contrib/mongodb/integration.rb +1 -1
  419. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
  420. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +23 -6
  421. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -1
  422. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -6
  423. data/lib/datadog/tracing/contrib/mysql2/integration.rb +1 -1
  424. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  425. data/lib/datadog/tracing/contrib/opensearch/ext.rb +12 -2
  426. data/lib/datadog/tracing/contrib/opensearch/integration.rb +1 -2
  427. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +68 -66
  428. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +5 -5
  429. data/lib/datadog/tracing/contrib/patcher.rb +12 -11
  430. data/lib/datadog/tracing/contrib/pg/integration.rb +1 -1
  431. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -1
  432. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  433. data/lib/datadog/tracing/contrib/presto/integration.rb +1 -1
  434. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +1 -1
  435. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  436. data/lib/datadog/tracing/contrib/que/integration.rb +1 -1
  437. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -1
  438. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +2 -2
  439. data/lib/datadog/tracing/contrib/racecar/events/consume.rb +1 -1
  440. data/lib/datadog/tracing/contrib/racecar/events/message.rb +2 -2
  441. data/lib/datadog/tracing/contrib/racecar/integration.rb +1 -1
  442. data/lib/datadog/tracing/contrib/rack/header_collection.rb +1 -1
  443. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +32 -32
  444. data/lib/datadog/tracing/contrib/rack/integration.rb +1 -1
  445. data/lib/datadog/tracing/contrib/rack/middlewares.rb +21 -17
  446. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  447. data/lib/datadog/tracing/contrib/rack/request_queue.rb +4 -3
  448. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +7 -1
  449. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -1
  450. data/lib/datadog/tracing/contrib/rails/ext.rb +2 -1
  451. data/lib/datadog/tracing/contrib/rails/integration.rb +2 -2
  452. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  453. data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
  454. data/lib/datadog/tracing/contrib/rails/patcher.rb +4 -1
  455. data/lib/datadog/tracing/contrib/rails/runner.rb +62 -40
  456. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -4
  457. data/lib/datadog/tracing/contrib/rake/integration.rb +1 -1
  458. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +2 -2
  459. data/lib/datadog/tracing/contrib/redis/ext.rb +3 -2
  460. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -2
  461. data/lib/datadog/tracing/contrib/redis/patcher.rb +4 -4
  462. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  463. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  464. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +4 -4
  465. data/lib/datadog/tracing/contrib/registry.rb +1 -1
  466. data/lib/datadog/tracing/contrib/resque/integration.rb +1 -1
  467. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -1
  468. data/lib/datadog/tracing/contrib/rest_client/ext.rb +3 -2
  469. data/lib/datadog/tracing/contrib/rest_client/integration.rb +1 -1
  470. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +8 -6
  471. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +1 -1
  472. data/lib/datadog/tracing/contrib/roda/integration.rb +1 -1
  473. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -1
  474. data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +1 -1
  475. data/lib/datadog/tracing/contrib/sequel/database.rb +5 -5
  476. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -1
  477. data/lib/datadog/tracing/contrib/sequel/integration.rb +1 -1
  478. data/lib/datadog/tracing/contrib/sequel/utils.rb +1 -1
  479. data/lib/datadog/tracing/contrib/shoryuken/integration.rb +1 -1
  480. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  481. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  482. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  483. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +1 -1
  484. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  485. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  486. data/lib/datadog/tracing/contrib/sinatra/integration.rb +1 -1
  487. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +38 -40
  488. data/lib/datadog/tracing/contrib/sneakers/integration.rb +1 -1
  489. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +1 -1
  490. data/lib/datadog/tracing/contrib/stripe/integration.rb +1 -1
  491. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  492. data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +1 -1
  493. data/lib/datadog/tracing/contrib/support.rb +28 -0
  494. data/lib/datadog/tracing/contrib/trilogy/ext.rb +1 -1
  495. data/lib/datadog/tracing/contrib/trilogy/integration.rb +1 -1
  496. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +11 -11
  497. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +6 -6
  498. data/lib/datadog/tracing/contrib.rb +1 -0
  499. data/lib/datadog/tracing/correlation.rb +9 -2
  500. data/lib/datadog/tracing/diagnostics/environment_logger.rb +8 -2
  501. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  502. data/lib/datadog/tracing/distributed/b3_single.rb +2 -2
  503. data/lib/datadog/tracing/distributed/baggage.rb +196 -0
  504. data/lib/datadog/tracing/distributed/datadog.rb +8 -7
  505. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +11 -13
  506. data/lib/datadog/tracing/distributed/helpers.rb +1 -1
  507. data/lib/datadog/tracing/distributed/none.rb +4 -2
  508. data/lib/datadog/tracing/distributed/propagation.rb +28 -4
  509. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  510. data/lib/datadog/tracing/distributed/trace_context.rb +22 -16
  511. data/lib/datadog/tracing/event.rb +5 -7
  512. data/lib/datadog/tracing/flush.rb +1 -1
  513. data/lib/datadog/tracing/metadata/analytics.rb +1 -1
  514. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  515. data/lib/datadog/tracing/metadata/ext.rb +13 -0
  516. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  517. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  518. data/lib/datadog/tracing/metadata/tagging.rb +4 -4
  519. data/lib/datadog/tracing/metadata.rb +2 -0
  520. data/lib/datadog/tracing/pipeline/span_filter.rb +3 -1
  521. data/lib/datadog/tracing/pipeline/span_processor.rb +3 -1
  522. data/lib/datadog/tracing/pipeline.rb +1 -1
  523. data/lib/datadog/tracing/sampling/ext.rb +0 -2
  524. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  525. data/lib/datadog/tracing/sampling/rule_sampler.rb +30 -30
  526. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  527. data/lib/datadog/tracing/sampling/span/rule_parser.rb +1 -1
  528. data/lib/datadog/tracing/sampling/span/sampler.rb +0 -7
  529. data/lib/datadog/tracing/span.rb +11 -2
  530. data/lib/datadog/tracing/span_event.rb +11 -11
  531. data/lib/datadog/tracing/span_link.rb +12 -12
  532. data/lib/datadog/tracing/span_operation.rb +76 -26
  533. data/lib/datadog/tracing/sync_writer.rb +5 -4
  534. data/lib/datadog/tracing/trace_digest.rb +29 -24
  535. data/lib/datadog/tracing/trace_operation.rb +121 -97
  536. data/lib/datadog/tracing/trace_segment.rb +8 -6
  537. data/lib/datadog/tracing/tracer.rb +90 -43
  538. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  539. data/lib/datadog/tracing/transport/http/client.rb +6 -5
  540. data/lib/datadog/tracing/transport/http/traces.rb +15 -43
  541. data/lib/datadog/tracing/transport/http.rb +13 -75
  542. data/lib/datadog/tracing/transport/io/client.rb +5 -5
  543. data/lib/datadog/tracing/transport/io/traces.rb +4 -4
  544. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  545. data/lib/datadog/tracing/transport/statistics.rb +1 -1
  546. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  547. data/lib/datadog/tracing/transport/traces.rb +31 -14
  548. data/lib/datadog/tracing/utils.rb +1 -1
  549. data/lib/datadog/tracing/workers/trace_writer.rb +16 -16
  550. data/lib/datadog/tracing/workers.rb +2 -2
  551. data/lib/datadog/tracing/writer.rb +4 -4
  552. data/lib/datadog/tracing.rb +16 -3
  553. data/lib/datadog/version.rb +1 -1
  554. data/lib/datadog.rb +8 -2
  555. metadata +115 -24
  556. data/ext/libdatadog_api/macos_development.md +0 -26
  557. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  558. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  559. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  560. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  561. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  562. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  563. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  564. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  565. data/lib/datadog/appsec/processor.rb +0 -107
  566. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  567. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  568. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  569. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  570. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../utils/hash_coercion'
4
+ require_relative '../../../instrumentation/gateway/argument'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module Rails
10
+ module Patches
11
+ # A patch targeting `AbstractController::Rendering#render_to_body`
12
+ # method to capture JSON response body right before it is serialized.
13
+ module RenderToBodyPatch
14
+ def render_to_body(options = {})
15
+ return super unless options.key?(:json)
16
+
17
+ context = request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
18
+ return super unless context
19
+
20
+ data = Utils::HashCoercion.coerce(options[:json])
21
+ return super unless data
22
+
23
+ container = Instrumentation::Gateway::DataContainer.new(data, context: context)
24
+ Instrumentation.gateway.push('rails.response.body.json', container)
25
+
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ 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
- # rubocop:disable Naming/FileName
2
1
  # frozen_string_literal: true
3
2
 
3
+ require_relative '../../event'
4
+ require_relative '../../trace_keeper'
5
+ require_relative '../../security_event'
6
+
4
7
  module Datadog
5
8
  module AppSec
6
9
  module Contrib
@@ -12,24 +15,21 @@ 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(context, result)
23
+ TraceKeeper.keep!(context.trace) if result.keep?
20
24
 
21
- context.events << {
22
- waf_result: result,
23
- trace: context.trace,
24
- span: context.span,
25
- request_url: url,
26
- actions: result.actions
27
- }
25
+ context.events.push(
26
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
27
+ )
28
28
 
29
- ActionsHandler.handle(result.actions)
29
+ AppSec::ActionsHandler.handle(result.actions)
30
30
  end
31
31
 
32
- super(&block)
32
+ super
33
33
  end
34
34
  end
35
35
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
4
3
  require_relative '../../../event'
4
+ require_relative '../../../trace_keeper'
5
+ require_relative '../../../security_event'
6
+ require_relative '../../../instrumentation/gateway'
5
7
 
6
8
  module Datadog
7
9
  module AppSec
@@ -16,11 +18,12 @@ module Datadog
16
18
 
17
19
  watch_request_dispatch(gateway)
18
20
  watch_request_routed(gateway)
21
+ watch_response_body_json(gateway)
19
22
  end
20
23
 
21
24
  def watch_request_dispatch(gateway = Instrumentation.gateway)
22
25
  gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request|
23
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
26
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
24
27
 
25
28
  persistent_data = {
26
29
  'server.request.body' => gateway_request.form_hash
@@ -28,18 +31,17 @@ module Datadog
28
31
 
29
32
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
30
33
 
31
- if result.match?
32
- Datadog::AppSec::Event.tag_and_keep!(context, result)
34
+ if result.match? || !result.attributes.empty?
35
+ context.events.push(
36
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
37
+ )
38
+ end
33
39
 
34
- context.events << {
35
- waf_result: result,
36
- trace: context.trace,
37
- span: context.span,
38
- request: gateway_request,
39
- actions: result.actions
40
- }
40
+ if result.match?
41
+ AppSec::Event.tag(context, result)
42
+ TraceKeeper.keep!(context.trace) if result.keep?
41
43
 
42
- Datadog::AppSec::ActionsHandler.handle(result.actions)
44
+ AppSec::ActionsHandler.handle(result.actions)
43
45
  end
44
46
 
45
47
  stack.call(gateway_request.request)
@@ -48,7 +50,7 @@ module Datadog
48
50
 
49
51
  def watch_request_routed(gateway = Instrumentation.gateway)
50
52
  gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)|
51
- context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
53
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
52
54
 
53
55
  persistent_data = {
54
56
  'server.request.path_params' => gateway_route_params.params
@@ -57,22 +59,43 @@ module Datadog
57
59
  result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
58
60
 
59
61
  if result.match?
60
- Datadog::AppSec::Event.tag_and_keep!(context, result)
62
+ AppSec::Event.tag(context, result)
63
+ TraceKeeper.keep!(context.trace) if result.keep?
61
64
 
62
- context.events << {
63
- waf_result: result,
64
- trace: context.trace,
65
- span: context.span,
66
- request: gateway_request,
67
- actions: result.actions
68
- }
65
+ context.events.push(
66
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
67
+ )
69
68
 
70
- Datadog::AppSec::ActionsHandler.handle(result.actions)
69
+ AppSec::ActionsHandler.handle(result.actions)
71
70
  end
72
71
 
73
72
  stack.call(gateway_request.request)
74
73
  end
75
74
  end
75
+
76
+ def watch_response_body_json(gateway = Instrumentation.gateway)
77
+ gateway.watch('sinatra.response.body.json', :appsec) do |stack, container|
78
+ context = container.context
79
+
80
+ persistent_data = {
81
+ 'server.response.body' => container.data
82
+ }
83
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
84
+
85
+ if result.match?
86
+ context.events.push(
87
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
88
+ )
89
+
90
+ AppSec::Event.tag(context, result)
91
+ TraceKeeper.keep!(context.trace) if result.keep?
92
+
93
+ AppSec::ActionsHandler.handle(result.actions)
94
+ end
95
+
96
+ stack.call(container)
97
+ end
98
+ end
76
99
  end
77
100
  end
78
101
  end
@@ -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?
@@ -8,6 +8,7 @@ require_relative 'framework'
8
8
  require_relative 'gateway/watcher'
9
9
  require_relative 'gateway/route_params'
10
10
  require_relative 'gateway/request'
11
+ require_relative 'patches/json_patch'
11
12
  require_relative '../../../tracing/contrib/sinatra/framework'
12
13
 
13
14
  module Datadog
@@ -51,7 +52,6 @@ module Datadog
51
52
  module DispatchPatch
52
53
  def dispatch!
53
54
  env = @request.env
54
-
55
55
  context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
56
56
 
57
57
  return super unless context
@@ -59,7 +59,6 @@ module Datadog
59
59
  # TODO: handle exceptions, except for super
60
60
 
61
61
  gateway_request = Gateway::Request.new(env)
62
-
63
62
  request_return, _gateway_request = Instrumentation.gateway.push('sinatra.request.dispatch', gateway_request) do
64
63
  super
65
64
  end
@@ -113,27 +112,18 @@ module Datadog
113
112
 
114
113
  def patch
115
114
  Gateway::Watcher.watch
116
- patch_default_middlewares
117
- patch_dispatch
118
- patch_route
119
- setup_security
120
- Patcher.instance_variable_set(:@patched, true)
121
- end
122
-
123
- def setup_security
124
- ::Sinatra::Base.singleton_class.prepend(AppSecSetupPatch)
125
- end
126
115
 
127
- def patch_default_middlewares
128
116
  ::Sinatra::Base.singleton_class.prepend(DefaultMiddlewarePatch)
129
- end
130
-
131
- def patch_dispatch
132
117
  ::Sinatra::Base.prepend(DispatchPatch)
118
+ ::Sinatra::Base.prepend(RoutePatch)
119
+ ::Sinatra::Base.prepend(Patches::JsonPatch) if patch_json?
120
+ ::Sinatra::Base.singleton_class.prepend(AppSecSetupPatch)
121
+
122
+ Patcher.instance_variable_set(:@patched, true)
133
123
  end
134
124
 
135
- def patch_route
136
- ::Sinatra::Base.prepend(RoutePatch)
125
+ def patch_json?
126
+ defined?(::Sinatra::JSON) && ::Sinatra::Base < ::Sinatra::JSON
137
127
  end
138
128
  end
139
129
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../utils/hash_coercion'
4
+ require_relative '../../../instrumentation/gateway/argument'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module Sinatra
10
+ module Patches
11
+ # A patch targeting `Sinatra::JSON#json` method to capture JSON response
12
+ # body right before it is serialized.
13
+ module JsonPatch
14
+ def json(object, options = {})
15
+ context = @request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
16
+ return super unless context
17
+
18
+ data = Utils::HashCoercion.coerce(object)
19
+ return super unless data
20
+
21
+ container = Instrumentation::Gateway::DataContainer.new(data, context: context)
22
+ Instrumentation.gateway.push('sinatra.response.body.json', container)
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,193 +1,137 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require 'zlib'
5
-
6
4
  require_relative 'rate_limiter'
7
- require_relative '../core/utils/base64'
5
+ require_relative 'trace_keeper'
6
+ require_relative 'compressed_json'
8
7
 
9
8
  module Datadog
10
9
  module AppSec
11
10
  # AppSec event
12
11
  module Event
12
+ ATTRIBUTES_SCHEMA_KEY_PREFIX = '_dd.appsec.s.'
13
+ ATTRIBUTES_SCHEMA_MAX_COMPRESSED_SIZE = 25000
13
14
  ALLOWED_REQUEST_HEADERS = %w[
14
- X-Forwarded-For
15
- X-Client-IP
16
- X-Real-IP
17
- X-Forwarded
18
- X-Cluster-Client-IP
19
- Forwarded-For
20
- Forwarded
21
- Via
22
- True-Client-IP
23
- Content-Length
24
- Content-Type
25
- Content-Encoding
26
- Content-Language
27
- Host
28
- User-Agent
29
- Accept
30
- Accept-Encoding
31
- Accept-Language
32
- ].map!(&:downcase).freeze
15
+ x-forwarded-for
16
+ x-client-ip
17
+ x-real-ip
18
+ x-forwarded
19
+ x-cluster-client-ip
20
+ forwarded-for
21
+ forwarded
22
+ via
23
+ true-client-ip
24
+ content-length
25
+ content-type
26
+ content-encoding
27
+ content-language
28
+ host
29
+ user-agent
30
+ accept
31
+ accept-encoding
32
+ accept-language
33
+ ].freeze
33
34
 
34
35
  ALLOWED_RESPONSE_HEADERS = %w[
35
- Content-Length
36
- Content-Type
37
- Content-Encoding
38
- Content-Language
39
- ].map!(&:downcase).freeze
40
-
41
- MAX_ENCODED_SCHEMA_SIZE = 25000
42
- # For more information about this number
43
- # please check https://github.com/DataDog/dd-trace-rb/pull/3177#issuecomment-1747221082
44
- MIN_SCHEMA_SIZE_FOR_COMPRESSION = 260
45
-
46
- # Record events for a trace
47
- #
48
- # This is expected to be called only once per trace for the rate limiter
49
- # to properly apply
36
+ content-length
37
+ content-type
38
+ content-encoding
39
+ content-language
40
+ ].freeze
41
+
50
42
  class << self
51
- def record(span, *events)
52
- # ensure rate limiter is called only when there are events to record
53
- return if events.empty? || span.nil?
43
+ def tag(context, waf_result)
44
+ return if context.span.nil?
54
45
 
55
- Datadog::AppSec::RateLimiter.thread_local.limit do
56
- record_via_span(span, *events)
46
+ if waf_result.actions.key?('block_request') || waf_result.actions.key?('redirect_request')
47
+ context.span.set_tag('appsec.blocked', 'true')
57
48
  end
58
- end
59
-
60
- def record_via_span(span, *events)
61
- events.group_by { |e| e[:trace] }.each do |trace, event_group|
62
- unless trace
63
- Datadog.logger.debug { "{ error: 'no trace: cannot record', event_group: #{event_group.inspect}}" }
64
- next
65
- end
66
49
 
67
- trace.keep!
68
- trace.set_tag(
69
- Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
70
- Datadog::Tracing::Sampling::Ext::Decision::ASM
71
- )
72
-
73
- # prepare and gather tags to apply
74
- service_entry_tags = build_service_entry_tags(event_group)
75
-
76
- # apply tags to service entry span
77
- service_entry_tags.each do |key, value|
78
- span.set_tag(key, value)
79
- end
80
- end
50
+ context.span.set_tag('appsec.event', 'true')
81
51
  end
82
52
 
83
- # rubocop:disable Metrics/MethodLength
84
- def build_service_entry_tags(event_group)
85
- waf_events = []
86
- entry_tags = event_group.each_with_object({ '_dd.origin' => 'appsec' }) do |event, tags|
87
- # TODO: assume HTTP request context for now
88
- if (request = event[:request])
89
- request.headers.each do |header, value|
90
- tags["http.request.headers.#{header}"] = value if ALLOWED_REQUEST_HEADERS.include?(header.downcase)
53
+ def record(context, request: nil, response: nil)
54
+ return if context.events.empty? || context.span.nil?
55
+
56
+ Datadog::AppSec::RateLimiter.thread_local.limit do
57
+ context.events.group_by(&:trace).each do |trace, event_group|
58
+ unless trace
59
+ next Datadog.logger.debug do
60
+ "AppSec: Cannot record event group with #{event_group.count} events because it has no trace"
61
+ end
91
62
  end
92
63
 
93
- tags['http.host'] = request.host
94
- tags['http.useragent'] = request.user_agent
95
- tags['network.client.ip'] = request.remote_addr
96
- end
64
+ if event_group.any? { |event| event.keep? || event.schema? }
65
+ TraceKeeper.keep!(trace)
97
66
 
98
- if (response = event[:response])
99
- response.headers.each do |header, value|
100
- tags["http.response.headers.#{header}"] = value if ALLOWED_RESPONSE_HEADERS.include?(header.downcase)
67
+ context.span['_dd.origin'] = 'appsec'
68
+ context.span.set_tags(request_tags(request)) if request
69
+ context.span.set_tags(response_tags(response)) if response
101
70
  end
71
+
72
+ context.span.set_tags(waf_tags(event_group))
102
73
  end
74
+ end
75
+ end
103
76
 
104
- waf_result = event[:waf_result]
105
- # accumulate triggers
106
- waf_events += waf_result.events
77
+ private
107
78
 
108
- waf_result.derivatives.each do |key, value|
109
- parsed_value = json_parse(value)
110
- next unless parsed_value
79
+ def request_tags(request)
80
+ tags = {}
111
81
 
112
- parsed_value_size = parsed_value.size
82
+ tags['http.host'] = request.host if request.host
83
+ tags['http.useragent'] = request.user_agent if request.user_agent
84
+ tags['network.client.ip'] = request.remote_addr if request.remote_addr
113
85
 
114
- schema_value = if parsed_value_size >= MIN_SCHEMA_SIZE_FOR_COMPRESSION
115
- compressed_and_base64_encoded(parsed_value)
116
- else
117
- parsed_value
118
- end
119
- next unless schema_value
86
+ request.headers.each_with_object(tags) do |(name, value), memo|
87
+ next unless ALLOWED_REQUEST_HEADERS.include?(name)
120
88
 
121
- if schema_value.size >= MAX_ENCODED_SCHEMA_SIZE
122
- Datadog.logger.debug do
123
- "Schema key: #{key} exceeds the max size value. It will not be included as part of the span tags"
124
- end
125
- next
126
- end
89
+ memo["http.request.headers.#{name}"] = value
90
+ end
91
+ end
127
92
 
128
- tags[key] = schema_value
129
- end
93
+ def response_tags(response)
94
+ response.headers.each_with_object({}) do |(name, value), memo|
95
+ next unless ALLOWED_RESPONSE_HEADERS.include?(name)
130
96
 
131
- tags
97
+ memo["http.response.headers.#{name}"] = value
132
98
  end
133
-
134
- appsec_events = json_parse({ triggers: waf_events })
135
- entry_tags['_dd.appsec.json'] = appsec_events if appsec_events
136
- entry_tags
137
99
  end
138
- # rubocop:enable Metrics/MethodLength
139
100
 
140
- def tag_and_keep!(context, waf_result)
141
- # We want to keep the trace in case of security event
142
- context.trace.keep! if context.trace
101
+ def waf_tags(security_events)
102
+ triggers = []
143
103
 
144
- if context.span
145
- context.span.set_tag('appsec.blocked', 'true') if waf_result.actions.key?('block_request')
146
- context.span.set_tag('appsec.event', 'true')
147
- end
104
+ tags = security_events.each_with_object({}) do |security_event, memo|
105
+ triggers.concat(security_event.waf_result.events)
148
106
 
149
- add_distributed_tags(context.trace)
150
- end
107
+ security_event.waf_result.attributes.each do |key, value|
108
+ next memo[key] = value unless key.start_with?(ATTRIBUTES_SCHEMA_KEY_PREFIX)
151
109
 
152
- private
110
+ value = CompressedJson.dump(value)
111
+ next if value.nil?
153
112
 
154
- def compressed_and_base64_encoded(value)
155
- Datadog::Core::Utils::Base64.strict_encode64(gzip(value))
156
- rescue TypeError => e
157
- Datadog.logger.debug do
158
- "Failed to compress and encode value when populating AppSec::Event. Error: #{e.message}"
159
- end
160
- nil
161
- end
113
+ if value.size >= ATTRIBUTES_SCHEMA_MAX_COMPRESSED_SIZE
114
+ Datadog.logger.debug { "AppSec: Schema key '#{key}' will not be included into span tags due to it's size" }
115
+ next
116
+ end
162
117
 
163
- def json_parse(value)
164
- JSON.dump(value)
165
- rescue ArgumentError => e
166
- Datadog.logger.debug do
167
- "Failed to parse value to JSON when populating AppSec::Event. Error: #{e.message}"
118
+ memo[key] = value
119
+ end
168
120
  end
169
- nil
170
- end
171
121
 
172
- def gzip(value)
173
- sio = StringIO.new
174
- # For an in depth comparison of Zlib options check https://github.com/DataDog/dd-trace-rb/pull/3177#issuecomment-1747215473
175
- gz = Zlib::GzipWriter.new(sio, Zlib::BEST_SPEED, Zlib::DEFAULT_STRATEGY)
176
- gz.write(value)
177
- gz.close
178
- sio.string
122
+ tags['_dd.appsec.json'] = json_parse({triggers: triggers}) unless triggers.empty?
123
+ tags
179
124
  end
180
125
 
181
- # Propagate to downstream services the information that the current distributed trace is
182
- # containing at least one ASM security event.
183
- def add_distributed_tags(trace)
184
- return unless trace
126
+ # NOTE: Handling of Encoding::UndefinedConversionError is added as a quick fix to
127
+ # the issue between Ruby encoded strings and libddwaf produced events and now
128
+ # is under investigation.
129
+ def json_parse(value)
130
+ JSON.dump(value)
131
+ rescue ArgumentError, Encoding::UndefinedConversionError, JSON::JSONError => e
132
+ AppSec.telemetry.report(e, description: 'AppSec: Failed to convert value into JSON')
185
133
 
186
- trace.set_tag(
187
- Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
188
- Datadog::Tracing::Sampling::Ext::Decision::ASM
189
- )
190
- trace.set_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT, '1')
134
+ nil
191
135
  end
192
136
  end
193
137
  end
@@ -7,13 +7,15 @@ module Datadog
7
7
  RASP_LFI = 'lfi'
8
8
  RASP_SSRF = 'ssrf'
9
9
 
10
+ PRODUCT_BIT = 0b00000010
11
+
10
12
  INTERRUPT = :datadog_appsec_interrupt
11
13
  CONTEXT_KEY = 'datadog.appsec.context'
12
14
  ACTIVE_CONTEXT_KEY = :datadog_appsec_active_context
15
+ EXPLOIT_PREVENTION_EVENT_CATEGORY = 'exploit'
13
16
 
14
17
  TAG_APPSEC_ENABLED = '_dd.appsec.enabled'
15
- TAG_APM_ENABLED = '_dd.apm.enabled'
16
- TAG_DISTRIBUTED_APPSEC_EVENT = '_dd.p.appsec'
18
+ TAG_METASTRUCT_STACK_TRACE = '_dd.stack'
17
19
 
18
20
  TELEMETRY_METRICS_NAMESPACE = 'appsec'
19
21
  end
@@ -8,12 +8,33 @@ module Datadog
8
8
  class Argument; end # rubocop:disable Lint/EmptyClass
9
9
 
10
10
  # Gateway User argument
11
+ # NOTE: This class is a subject of elimination and will be removed when
12
+ # the event system is refactored.
11
13
  class User < Argument
12
- attr_reader :id
14
+ attr_reader :id, :login, :session_id
13
15
 
14
- def initialize(id)
16
+ def initialize(id = nil, login = nil, session_id = nil)
15
17
  super()
18
+
16
19
  @id = id
20
+ @login = login
21
+ @session_id = session_id
22
+ end
23
+ end
24
+
25
+ # This class is used to pass arbitrary data to the event system with an
26
+ # option to tie it to a context.
27
+ #
28
+ # NOTE: This class is a subject of elimination and will be removed when
29
+ # the event system is refactored.
30
+ class DataContainer < Argument
31
+ attr_reader :data, :context
32
+
33
+ def initialize(data, context:)
34
+ super()
35
+
36
+ @data = data
37
+ @context = context
17
38
  end
18
39
  end
19
40
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module Instrumentation
6
+ class Gateway
7
+ # NOTE: This class extracted as-is and will be deprecated
8
+ # Instrumentation gateway middleware
9
+ class Middleware
10
+ attr_reader :key, :block
11
+
12
+ def initialize(key, &block)
13
+ @key = key
14
+ @block = block
15
+ end
16
+
17
+ def call(stack, env)
18
+ @block.call(stack, env)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end