datadog 2.7.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 (417) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +310 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
  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 +7 -8
  16. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  18. data/ext/datadog_profiling_native_extension/heap_recorder.c +61 -174
  19. data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
  20. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
  23. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  24. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  25. data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
  26. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  27. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  28. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  29. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  30. data/ext/libdatadog_api/crashtracker.c +17 -15
  31. data/ext/libdatadog_api/crashtracker.h +5 -0
  32. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  33. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  34. data/ext/libdatadog_api/init.c +15 -0
  35. data/ext/libdatadog_api/library_config.c +122 -0
  36. data/ext/libdatadog_api/library_config.h +19 -0
  37. data/ext/libdatadog_api/macos_development.md +3 -3
  38. data/ext/libdatadog_api/process_discovery.c +117 -0
  39. data/ext/libdatadog_api/process_discovery.h +5 -0
  40. data/ext/libdatadog_extconf_helpers.rb +1 -1
  41. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  42. data/lib/datadog/appsec/actions_handler.rb +49 -0
  43. data/lib/datadog/appsec/anonymizer.rb +16 -0
  44. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  45. data/lib/datadog/appsec/api_security.rb +9 -0
  46. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  47. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  49. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  50. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/component.rb +41 -33
  53. data/lib/datadog/appsec/compressed_json.rb +40 -0
  54. data/lib/datadog/appsec/configuration/settings.rb +152 -25
  55. data/lib/datadog/appsec/context.rb +74 -0
  56. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  57. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  58. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  59. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  60. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  61. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  62. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  63. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  64. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  65. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  66. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  67. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  68. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  69. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  70. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  71. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  72. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  73. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  74. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  75. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  76. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  77. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  78. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  79. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  80. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  81. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  82. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  83. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  84. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  87. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
  88. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  89. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  91. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  92. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  93. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  94. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  95. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  96. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  97. data/lib/datadog/appsec/event.rb +96 -135
  98. data/lib/datadog/appsec/ext.rb +12 -3
  99. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  100. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  101. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  102. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  103. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  104. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  105. data/lib/datadog/appsec/metrics.rb +13 -0
  106. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  107. data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
  108. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  109. data/lib/datadog/appsec/processor.rb +5 -4
  110. data/lib/datadog/appsec/remote.rb +26 -12
  111. data/lib/datadog/appsec/response.rb +19 -85
  112. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  113. data/lib/datadog/appsec/security_engine/runner.rb +88 -0
  114. data/lib/datadog/appsec/security_engine.rb +9 -0
  115. data/lib/datadog/appsec/security_event.rb +39 -0
  116. data/lib/datadog/appsec/utils.rb +0 -2
  117. data/lib/datadog/appsec.rb +23 -10
  118. data/lib/datadog/auto_instrument.rb +3 -0
  119. data/lib/datadog/core/buffer/random.rb +18 -2
  120. data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
  121. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  122. data/lib/datadog/core/configuration/components.rb +76 -32
  123. data/lib/datadog/core/configuration/components_state.rb +23 -0
  124. data/lib/datadog/core/configuration/ext.rb +5 -1
  125. data/lib/datadog/core/configuration/option.rb +79 -43
  126. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  127. data/lib/datadog/core/configuration/options.rb +3 -3
  128. data/lib/datadog/core/configuration/settings.rb +100 -41
  129. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  130. data/lib/datadog/core/configuration.rb +43 -11
  131. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  132. data/lib/datadog/core/crashtracking/component.rb +4 -13
  133. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  134. data/lib/datadog/core/encoding.rb +17 -1
  135. data/lib/datadog/core/environment/agent_info.rb +78 -0
  136. data/lib/datadog/core/environment/cgroup.rb +10 -12
  137. data/lib/datadog/core/environment/container.rb +38 -40
  138. data/lib/datadog/core/environment/ext.rb +6 -6
  139. data/lib/datadog/core/environment/git.rb +1 -0
  140. data/lib/datadog/core/environment/identity.rb +3 -3
  141. data/lib/datadog/core/environment/platform.rb +3 -3
  142. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  143. data/lib/datadog/core/error.rb +11 -9
  144. data/lib/datadog/core/logger.rb +2 -2
  145. data/lib/datadog/core/metrics/client.rb +27 -27
  146. data/lib/datadog/core/metrics/logging.rb +5 -5
  147. data/lib/datadog/core/process_discovery.rb +32 -0
  148. data/lib/datadog/core/rate_limiter.rb +4 -2
  149. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  150. data/lib/datadog/core/remote/client.rb +107 -92
  151. data/lib/datadog/core/remote/component.rb +18 -19
  152. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  153. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  154. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  155. data/lib/datadog/core/remote/negotiation.rb +9 -9
  156. data/lib/datadog/core/remote/transport/config.rb +4 -3
  157. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  158. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  159. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  160. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  161. data/lib/datadog/core/remote/transport/http.rb +25 -94
  162. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  163. data/lib/datadog/core/remote/worker.rb +10 -7
  164. data/lib/datadog/core/runtime/metrics.rb +12 -5
  165. data/lib/datadog/core/telemetry/component.rb +84 -49
  166. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  167. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  168. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  169. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  170. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  171. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  172. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  173. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  174. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  175. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  176. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  177. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  178. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  179. data/lib/datadog/core/telemetry/event.rb +17 -383
  180. data/lib/datadog/core/telemetry/ext.rb +1 -0
  181. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  182. data/lib/datadog/core/telemetry/logger.rb +1 -1
  183. data/lib/datadog/core/telemetry/logging.rb +2 -2
  184. data/lib/datadog/core/telemetry/metric.rb +28 -6
  185. data/lib/datadog/core/telemetry/request.rb +4 -4
  186. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  187. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  188. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  189. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  190. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  191. data/lib/datadog/core/telemetry/worker.rb +128 -25
  192. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  193. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  194. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  195. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  196. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  197. data/lib/datadog/core/transport/http.rb +75 -0
  198. data/lib/datadog/core/transport/response.rb +4 -0
  199. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  200. data/lib/datadog/core/utils/duration.rb +32 -32
  201. data/lib/datadog/core/utils/forking.rb +2 -2
  202. data/lib/datadog/core/utils/network.rb +6 -6
  203. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  204. data/lib/datadog/core/utils/time.rb +20 -0
  205. data/lib/datadog/core/utils/truncation.rb +21 -0
  206. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  207. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  208. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  209. data/lib/datadog/core/worker.rb +1 -1
  210. data/lib/datadog/core/workers/async.rb +29 -12
  211. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  212. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  213. data/lib/datadog/core.rb +8 -0
  214. data/lib/datadog/di/base.rb +115 -0
  215. data/lib/datadog/di/boot.rb +34 -0
  216. data/lib/datadog/di/code_tracker.rb +26 -15
  217. data/lib/datadog/di/component.rb +23 -14
  218. data/lib/datadog/di/configuration/settings.rb +25 -1
  219. data/lib/datadog/di/contrib/active_record.rb +1 -0
  220. data/lib/datadog/di/contrib/railtie.rb +15 -0
  221. data/lib/datadog/di/contrib.rb +28 -0
  222. data/lib/datadog/di/error.rb +5 -0
  223. data/lib/datadog/di/instrumenter.rb +111 -20
  224. data/lib/datadog/di/logger.rb +30 -0
  225. data/lib/datadog/di/preload.rb +18 -0
  226. data/lib/datadog/di/probe.rb +14 -7
  227. data/lib/datadog/di/probe_builder.rb +1 -0
  228. data/lib/datadog/di/probe_manager.rb +11 -5
  229. data/lib/datadog/di/probe_notification_builder.rb +34 -8
  230. data/lib/datadog/di/probe_notifier_worker.rb +52 -26
  231. data/lib/datadog/di/redactor.rb +0 -1
  232. data/lib/datadog/di/remote.rb +147 -0
  233. data/lib/datadog/di/serializer.rb +14 -7
  234. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  235. data/lib/datadog/di/transport/http/api.rb +42 -0
  236. data/lib/datadog/di/transport/http/client.rb +47 -0
  237. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  238. data/lib/datadog/di/transport/http/input.rb +67 -0
  239. data/lib/datadog/di/transport/http.rb +57 -0
  240. data/lib/datadog/di/transport/input.rb +62 -0
  241. data/lib/datadog/di/utils.rb +103 -0
  242. data/lib/datadog/di.rb +14 -76
  243. data/lib/datadog/error_tracking/collector.rb +87 -0
  244. data/lib/datadog/error_tracking/component.rb +167 -0
  245. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  246. data/lib/datadog/error_tracking/configuration.rb +11 -0
  247. data/lib/datadog/error_tracking/ext.rb +18 -0
  248. data/lib/datadog/error_tracking/extensions.rb +16 -0
  249. data/lib/datadog/error_tracking/filters.rb +77 -0
  250. data/lib/datadog/error_tracking.rb +18 -0
  251. data/lib/datadog/kit/appsec/events.rb +15 -3
  252. data/lib/datadog/kit/identity.rb +9 -5
  253. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  254. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  255. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  256. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  257. data/lib/datadog/opentelemetry.rb +2 -1
  258. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  259. data/lib/datadog/profiling/collectors/info.rb +3 -0
  260. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  261. data/lib/datadog/profiling/component.rb +60 -76
  262. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  263. data/lib/datadog/profiling/exporter.rb +3 -4
  264. data/lib/datadog/profiling/ext.rb +0 -2
  265. data/lib/datadog/profiling/flush.rb +5 -8
  266. data/lib/datadog/profiling/http_transport.rb +6 -85
  267. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  268. data/lib/datadog/profiling/scheduler.rb +8 -1
  269. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  270. data/lib/datadog/profiling/tag_builder.rb +1 -5
  271. data/lib/datadog/profiling.rb +6 -2
  272. data/lib/datadog/tracing/analytics.rb +1 -1
  273. data/lib/datadog/tracing/component.rb +16 -12
  274. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  275. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  276. data/lib/datadog/tracing/context_provider.rb +1 -1
  277. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  278. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  279. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  280. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  281. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  282. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  283. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  284. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  285. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  286. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  287. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  288. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  289. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  290. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  291. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  292. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  293. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  294. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  295. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  296. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  297. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  298. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  299. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  300. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  301. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  302. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  303. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  304. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  305. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  306. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  307. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  308. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  309. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  310. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  311. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  313. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  314. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  315. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  316. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  317. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  318. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  319. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  320. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  321. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  322. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  323. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  324. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  325. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  326. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  327. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  328. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  329. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  331. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  332. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  334. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  335. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  336. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  337. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  338. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  339. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  340. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  341. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  342. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  343. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  344. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  345. data/lib/datadog/tracing/contrib/support.rb +28 -0
  346. data/lib/datadog/tracing/contrib.rb +1 -0
  347. data/lib/datadog/tracing/correlation.rb +9 -2
  348. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  349. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  350. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  351. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  352. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  353. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  354. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  355. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  356. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  357. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  358. data/lib/datadog/tracing/metadata.rb +2 -0
  359. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  360. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  361. data/lib/datadog/tracing/span.rb +22 -5
  362. data/lib/datadog/tracing/span_event.rb +124 -4
  363. data/lib/datadog/tracing/span_operation.rb +52 -16
  364. data/lib/datadog/tracing/sync_writer.rb +9 -5
  365. data/lib/datadog/tracing/trace_digest.rb +9 -2
  366. data/lib/datadog/tracing/trace_operation.rb +44 -24
  367. data/lib/datadog/tracing/trace_segment.rb +6 -4
  368. data/lib/datadog/tracing/tracer.rb +60 -12
  369. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  370. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  371. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  372. data/lib/datadog/tracing/transport/http.rb +13 -70
  373. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  374. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  375. data/lib/datadog/tracing/transport/traces.rb +47 -13
  376. data/lib/datadog/tracing/utils.rb +1 -1
  377. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  378. data/lib/datadog/tracing/workers.rb +5 -4
  379. data/lib/datadog/tracing/writer.rb +10 -6
  380. data/lib/datadog/tracing.rb +16 -3
  381. data/lib/datadog/version.rb +2 -2
  382. data/lib/datadog.rb +2 -0
  383. metadata +143 -50
  384. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  385. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  386. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  387. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  388. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  389. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  390. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  391. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  392. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  393. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  394. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  395. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  396. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  397. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  398. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  399. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  400. data/lib/datadog/appsec/processor/actions.rb +0 -49
  401. data/lib/datadog/appsec/processor/context.rb +0 -107
  402. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  403. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  404. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  405. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  406. data/lib/datadog/appsec/scope.rb +0 -58
  407. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  408. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  409. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  410. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  411. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  412. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  413. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  414. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  415. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  416. data/lib/datadog/di/transport.rb +0 -81
  417. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -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/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
42
+ # rubocop:disable Metrics/MethodLength
40
43
  def call(env)
41
44
  return @app.call(env) unless Datadog::AppSec.enabled?
42
45
 
@@ -45,19 +48,22 @@ module Datadog
45
48
 
46
49
  processor = nil
47
50
  ready = false
48
- scope = nil
51
+ ctx = nil
49
52
 
50
53
  # For a given request, keep using the first Rack stack scope for
51
54
  # nested apps. Don't set `context` local variable so that on popping
52
55
  # out of this nested stack we don't finalize the parent's context
53
- return @app.call(env) if active_scope(env)
56
+ return @app.call(env) if active_context(env)
54
57
 
55
58
  Datadog::AppSec.reconfigure_lock do
56
59
  processor = Datadog::AppSec.processor
57
60
 
58
61
  if !processor.nil? && processor.ready?
59
- scope = Datadog::AppSec::Scope.activate_scope(active_trace, active_span, processor)
60
- env[Datadog::AppSec::Ext::SCOPE_KEY] = scope
62
+ ctx = Datadog::AppSec::Context.activate(
63
+ Datadog::AppSec::Context.new(active_trace, active_span, processor)
64
+ )
65
+
66
+ env[Datadog::AppSec::Ext::CONTEXT_KEY] = ctx
61
67
  ready = true
62
68
  end
63
69
  end
@@ -66,66 +72,55 @@ module Datadog
66
72
 
67
73
  return @app.call(env) unless ready
68
74
 
69
- gateway_request = Gateway::Request.new(env)
75
+ add_appsec_tags(processor, ctx)
76
+ add_request_tags(ctx, env)
70
77
 
71
- add_appsec_tags(processor, scope)
72
- add_request_tags(scope, env)
78
+ http_response = nil
79
+ gateway_request = Gateway::Request.new(env)
80
+ gateway_response = nil
73
81
 
74
- request_return, request_response = catch(::Datadog::AppSec::Ext::INTERRUPT) do
75
- Instrumentation.gateway.push('rack.request', gateway_request) do
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
85
+ http_response, _gateway_request = Instrumentation.gateway.push('rack.request', gateway_request) do
76
86
  @app.call(env)
77
87
  end
78
- end
79
-
80
- if request_response
81
- blocked_event = request_response.find { |action, _options| action == :block }
82
- request_return = AppSec::Response.negotiate(env, blocked_event.last[:actions]).to_rack if blocked_event
83
- end
84
-
85
- gateway_response = Gateway::Response.new(
86
- request_return[2],
87
- request_return[0],
88
- request_return[1],
89
- scope: scope,
90
- )
91
88
 
92
- _response_return, response_response = Instrumentation.gateway.push('rack.response', gateway_response)
89
+ gateway_response = Gateway::Response.new(
90
+ http_response[2], http_response[0], http_response[1], context: ctx
91
+ )
93
92
 
94
- result = scope.processor_context.extract_schema
93
+ Instrumentation.gateway.push('rack.request.finish', gateway_request)
94
+ Instrumentation.gateway.push('rack.response', gateway_response)
95
95
 
96
- if result
97
- scope.processor_context.events << {
98
- trace: scope.trace,
99
- span: scope.service_entry_span,
100
- waf_result: result,
101
- }
96
+ nil
102
97
  end
103
98
 
104
- scope.processor_context.events.each do |e|
105
- e[:response] ||= gateway_response
106
- e[:request] ||= gateway_request
99
+ if interrupt_params
100
+ http_response = AppSec::Response.from_interrupt_params(interrupt_params, env['HTTP_ACCEPT']).to_rack
107
101
  end
108
102
 
109
- AppSec::Event.record(scope.service_entry_span, *scope.processor_context.events)
110
-
111
- if response_response
112
- blocked_event = response_response.find { |action, _options| action == :block }
113
- request_return = AppSec::Response.negotiate(env, blocked_event.last[:actions]).to_rack if blocked_event
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
+ )
114
107
  end
115
108
 
116
- request_return
109
+ AppSec::Event.record(ctx, request: gateway_request, response: gateway_response)
110
+
111
+ http_response
117
112
  ensure
118
- if scope
119
- add_waf_runtime_tags(scope)
120
- Datadog::AppSec::Scope.deactivate_scope
113
+ if ctx
114
+ ctx.export_metrics
115
+ Datadog::AppSec::Context.deactivate
121
116
  end
122
117
  end
123
- # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
118
+ # rubocop:enable Metrics/MethodLength
124
119
 
125
120
  private
126
121
 
127
- def active_scope(env)
128
- env[Datadog::AppSec::Ext::SCOPE_KEY]
122
+ def active_context(env)
123
+ env[Datadog::AppSec::Ext::CONTEXT_KEY]
129
124
  end
130
125
 
131
126
  def active_trace
@@ -144,15 +139,14 @@ module Datadog
144
139
  Datadog::Tracing.active_span
145
140
  end
146
141
 
147
- def add_appsec_tags(processor, scope)
148
- span = scope.service_entry_span
149
- trace = scope.trace
142
+ # standard:disable Metrics/MethodLength
143
+ def add_appsec_tags(processor, context)
144
+ span = context.span
145
+ trace = context.trace
150
146
 
151
147
  return unless trace && span
152
148
 
153
149
  span.set_metric(Datadog::AppSec::Ext::TAG_APPSEC_ENABLED, 1)
154
- # We add this tag when ASM standalone is enabled to make sure we don't bill APM
155
- span.set_metric(Datadog::AppSec::Ext::TAG_APM_ENABLED, 0) if Datadog.configuration.appsec.standalone.enabled
156
150
  span.set_tag('_dd.runtime_family', 'ruby')
157
151
  span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)
158
152
 
@@ -180,9 +174,11 @@ module Datadog
180
174
  end
181
175
  end
182
176
  end
177
+ # standard:enable Metrics/MethodLength
183
178
 
184
- def add_request_tags(scope, env)
185
- span = scope.service_entry_span
179
+ # standard:disable Metrics/MethodLength
180
+ def add_request_tags(context, env)
181
+ span = context.span
186
182
 
187
183
  return unless span
188
184
 
@@ -203,19 +199,7 @@ module Datadog
203
199
  )
204
200
  end
205
201
  end
206
-
207
- def add_waf_runtime_tags(scope)
208
- span = scope.service_entry_span
209
- context = scope.processor_context
210
-
211
- return unless span && context
212
-
213
- span.set_tag('_dd.appsec.waf.timeouts', context.timeouts)
214
-
215
- # these tags expect time in us
216
- span.set_tag('_dd.appsec.waf.duration', context.time_ns / 1000.0)
217
- span.set_tag('_dd.appsec.waf.duration_ext', context.time_ext_ns / 1000.0)
218
- end
202
+ # standard:enable Metrics/MethodLength
219
203
 
220
204
  def to_rack_header(header)
221
205
  @rack_headers[header] ||= Datadog::Tracing::Contrib::Rack::Header.to_rack_header(header)
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
4
- require_relative '../../../reactive/operation'
5
- require_relative '../reactive/action'
6
3
  require_relative '../../../event'
4
+ require_relative '../../../security_event'
5
+ require_relative '../../../instrumentation/gateway'
7
6
 
8
7
  module Datadog
9
8
  module AppSec
@@ -21,43 +20,27 @@ module Datadog
21
20
 
22
21
  def watch_request_action(gateway = Instrumentation.gateway)
23
22
  gateway.watch('rails.request.action', :appsec) do |stack, gateway_request|
24
- block = false
25
-
26
- event = nil
27
- scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
23
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
28
24
 
29
- AppSec::Reactive::Operation.new('rails.request.action') do |op|
30
- Rails::Reactive::Action.subscribe(op, scope.processor_context) do |result|
31
- if result.status == :match
32
- # TODO: should this hash be an Event instance instead?
33
- event = {
34
- waf_result: result,
35
- trace: scope.trace,
36
- span: scope.service_entry_span,
37
- request: gateway_request,
38
- actions: result.actions
39
- }
25
+ persistent_data = {
26
+ 'server.request.body' => gateway_request.parsed_body,
27
+ 'server.request.path_params' => gateway_request.route_params
28
+ }
40
29
 
41
- # We want to keep the trace in case of security event
42
- scope.trace.keep! if scope.trace
43
- Datadog::AppSec::Event.tag_and_keep!(scope, result)
44
- scope.processor_context.events << event
45
- end
46
- end
30
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
47
31
 
48
- block = Rails::Reactive::Action.publish(op, gateway_request)
32
+ if result.match? || !result.derivatives.empty?
33
+ context.events.push(
34
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
35
+ )
49
36
  end
50
37
 
51
- next [nil, [[:block, event]]] if block
52
-
53
- ret, res = stack.call(gateway_request.request)
54
-
55
- if event
56
- res ||= []
57
- res << [:monitor, event]
38
+ if result.match?
39
+ AppSec::Event.tag_and_keep!(context, result)
40
+ AppSec::ActionsHandler.handle(result.actions)
58
41
  end
59
42
 
60
- [ret, res]
43
+ stack.call(gateway_request.request)
61
44
  end
62
45
  end
63
46
  end
@@ -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?
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative '../../../core/utils/only_once'
4
4
 
5
- require_relative '../patcher'
6
5
  require_relative 'framework'
7
6
  require_relative '../../response'
8
7
  require_relative '../rack/request_middleware'
@@ -18,8 +17,6 @@ module Datadog
18
17
  module Rails
19
18
  # Patcher for AppSec on Rails
20
19
  module Patcher
21
- include Datadog::AppSec::Contrib::Patcher
22
-
23
20
  BEFORE_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
24
21
  AFTER_INITIALIZE_ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Datadog::Core::Utils::OnlyOnce.new }
25
22
 
@@ -73,29 +70,19 @@ module Datadog
73
70
  def process_action(*args)
74
71
  env = request.env
75
72
 
76
- context = env[Datadog::AppSec::Ext::SCOPE_KEY]
73
+ context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
77
74
 
78
75
  return super unless context
79
76
 
80
77
  # TODO: handle exceptions, except for super
81
78
 
82
79
  gateway_request = Gateway::Request.new(request)
83
- request_return, request_response = Instrumentation.gateway.push('rails.request.action', gateway_request) do
84
- super
85
- end
86
80
 
87
- if request_response
88
- blocked_event = request_response.find { |action, _options| action == :block }
89
- if blocked_event
90
- @_response = AppSec::Response.negotiate(
91
- env,
92
- blocked_event.last[:actions]
93
- ).to_action_dispatch_response
94
- request_return = @_response.body
95
- end
81
+ http_response, _gateway_request = Instrumentation.gateway.push('rails.request.action', gateway_request) do
82
+ super
96
83
  end
97
84
 
98
- request_return
85
+ http_response
99
86
  end
100
87
  end
101
88
 
@@ -109,27 +96,27 @@ module Datadog
109
96
  # find tracer middleware reference in Rails::Configuration::MiddlewareStackProxy
110
97
  app.middleware.instance_variable_get(:@operations).each do |operation|
111
98
  args = case operation
112
- when Array
113
- # rails 5.2
114
- _op, args = operation
115
- args
116
- when Proc
117
- if operation.binding.local_variables.include?(:args)
118
- # rails 6.0, 6.1
119
- operation.binding.local_variable_get(:args)
120
- else
121
- # rails 7.0 uses ... to pass args
122
- args_getter = Class.new do
123
- def method_missing(_op, *args) # rubocop:disable Style/MissingRespondToMissing
124
- args
125
- end
126
- end.new
127
- operation.call(args_getter)
128
- end
129
- else
130
- # unknown, pass through
131
- []
132
- 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
133
120
 
134
121
  found = true if args.include?(middleware)
135
122
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../integration'
4
+ require_relative 'patcher'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module RestClient
10
+ # This class defines properties of rest-client AppSec integration
11
+ class Integration
12
+ include Datadog::AppSec::Contrib::Integration
13
+
14
+ MINIMUM_VERSION = Gem::Version.new('1.8')
15
+
16
+ register_as :rest_client
17
+
18
+ def self.gem_name
19
+ 'rest-client'
20
+ end
21
+
22
+ def self.version
23
+ Gem.loaded_specs['rest-client']&.version
24
+ end
25
+
26
+ def self.loaded?
27
+ !defined?(::RestClient::Request).nil?
28
+ end
29
+
30
+ def self.compatible?
31
+ super && version >= MINIMUM_VERSION
32
+ end
33
+
34
+ def self.auto_instrument?
35
+ false
36
+ end
37
+
38
+ def patcher
39
+ Patcher
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module Contrib
6
+ module RestClient
7
+ # Patcher for RestClient gem
8
+ module Patcher
9
+ module_function
10
+
11
+ def patched?
12
+ Patcher.instance_variable_get(:@patched)
13
+ end
14
+
15
+ def target_version
16
+ Integration.version
17
+ end
18
+
19
+ def patch
20
+ require_relative 'request_ssrf_detection_patch'
21
+
22
+ ::RestClient::Request.prepend(RequestSSRFDetectionPatch)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ # rubocop:disable Naming/FileName
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../event'
5
+ require_relative '../../security_event'
6
+
7
+ module Datadog
8
+ module AppSec
9
+ module Contrib
10
+ module RestClient
11
+ # Module that adds SSRF detection to RestClient::Request#execute
12
+ module RequestSSRFDetectionPatch
13
+ def execute(&block)
14
+ return super unless AppSec.rasp_enabled? && AppSec.active_context
15
+
16
+ context = AppSec.active_context
17
+
18
+ ephemeral_data = {'server.io.net.url' => url}
19
+ result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
20
+
21
+ if result.match?
22
+ AppSec::Event.tag_and_keep!(context, result)
23
+
24
+ context.events.push(
25
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
26
+ )
27
+
28
+ AppSec::ActionsHandler.handle(result.actions)
29
+ end
30
+
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ # rubocop:enable Naming/FileName
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../instrumentation/gateway'
4
- require_relative '../../../reactive/operation'
5
- require_relative '../../rack/reactive/request_body'
6
- require_relative '../reactive/routed'
7
3
  require_relative '../../../event'
4
+ require_relative '../../../security_event'
5
+ require_relative '../../../instrumentation/gateway'
8
6
 
9
7
  module Datadog
10
8
  module AppSec
@@ -23,85 +21,50 @@ module Datadog
23
21
 
24
22
  def watch_request_dispatch(gateway = Instrumentation.gateway)
25
23
  gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request|
26
- block = false
27
-
28
- event = nil
29
- scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
30
-
31
- AppSec::Reactive::Operation.new('sinatra.request.dispatch') do |op|
32
- Rack::Reactive::RequestBody.subscribe(op, scope.processor_context) do |result|
33
- if result.status == :match
34
- # TODO: should this hash be an Event instance instead?
35
- event = {
36
- waf_result: result,
37
- trace: scope.trace,
38
- span: scope.service_entry_span,
39
- request: gateway_request,
40
- actions: result.actions
41
- }
42
-
43
- # We want to keep the trace in case of security event
44
- scope.trace.keep! if scope.trace
45
- Datadog::AppSec::Event.tag_and_keep!(scope, result)
46
- scope.processor_context.events << event
47
- end
48
- end
49
-
50
- block = Rack::Reactive::RequestBody.publish(op, gateway_request)
51
- end
24
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
25
+
26
+ persistent_data = {
27
+ 'server.request.body' => gateway_request.form_hash
28
+ }
52
29
 
53
- next [nil, [[:block, event]]] if block
30
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
54
31
 
55
- ret, res = stack.call(gateway_request.request)
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
56
37
 
57
- if event
58
- res ||= []
59
- res << [:monitor, event]
38
+ if result.match?
39
+ AppSec::Event.tag_and_keep!(context, result)
40
+ AppSec::ActionsHandler.handle(result.actions)
60
41
  end
61
42
 
62
- [ret, res]
43
+ stack.call(gateway_request.request)
63
44
  end
64
45
  end
65
46
 
66
47
  def watch_request_routed(gateway = Instrumentation.gateway)
67
48
  gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)|
68
- block = false
69
-
70
- event = nil
71
- scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
72
-
73
- AppSec::Reactive::Operation.new('sinatra.request.routed') do |op|
74
- Sinatra::Reactive::Routed.subscribe(op, scope.processor_context) do |result|
75
- if result.status == :match
76
- # TODO: should this hash be an Event instance instead?
77
- event = {
78
- waf_result: result,
79
- trace: scope.trace,
80
- span: scope.service_entry_span,
81
- request: gateway_request,
82
- actions: result.actions
83
- }
84
-
85
- # We want to keep the trace in case of security event
86
- scope.trace.keep! if scope.trace
87
- Datadog::AppSec::Event.tag_and_keep!(scope, result)
88
- scope.processor_context.events << event
89
- end
90
- end
91
-
92
- block = Sinatra::Reactive::Routed.publish(op, [gateway_request, gateway_route_params])
93
- end
49
+ context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
50
+
51
+ persistent_data = {
52
+ 'server.request.path_params' => gateway_route_params.params
53
+ }
54
+
55
+ result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
94
56
 
95
- next [nil, [[:block, event]]] if block
57
+ if result.match?
58
+ AppSec::Event.tag_and_keep!(context, result)
96
59
 
97
- ret, res = stack.call(gateway_request.request)
60
+ context.events.push(
61
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
62
+ )
98
63
 
99
- if event
100
- res ||= []
101
- res << [:monitor, event]
64
+ AppSec::ActionsHandler.handle(result.actions)
102
65
  end
103
66
 
104
- [ret, res]
67
+ stack.call(gateway_request.request)
105
68
  end
106
69
  end
107
70
  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?