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
@@ -12,14 +12,29 @@ module Datadog
12
12
  DEFAULT_OBFUSCATOR_KEY_REGEX = '(?i)pass|pw(?:or)?d|secret|(?:api|private|public|access)[_-]?key|token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization|jsessionid|phpsessid|asp\.net[_-]sessionid|sid|jwt'
13
13
  DEFAULT_OBFUSCATOR_VALUE_REGEX = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:[_-]?phrase)?|secret(?:[_-]?key)?|(?:(?:api|private|public|access)[_-]?)key(?:[_-]?id)?|(?:(?:auth|access|id|refresh)[_-]?)?token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|jsessionid|phpsessid|asp\.net(?:[_-]|-)sessionid|sid|jwt)(?:\s*=[^;]|"\s*:\s*"[^"]+")|bearer\s+[a-z0-9\._\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\w=-]+\.ey[I-L][\w=-]+(?:\.[\w.+\/=-]+)?|[\-]{5}BEGIN[a-z\s]+PRIVATE\sKEY[\-]{5}[^\-]+[\-]{5}END[a-z\s]+PRIVATE\sKEY|ssh-rsa\s*[a-z0-9\/\.+]{100,}'
14
14
  # rubocop:enable Layout/LineLength
15
+
16
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE = 'disabled'
17
+ ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE = 'anonymization'
18
+ IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE = 'identification'
19
+ AUTO_USER_INSTRUMENTATION_MODES = [
20
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE,
21
+ ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
22
+ IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
23
+ ].freeze
24
+ AUTO_USER_INSTRUMENTATION_MODES_ALIASES = {
25
+ 'ident' => IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE,
26
+ 'anon' => ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
27
+ }.freeze
28
+
29
+ # NOTE: These two constants are deprecated
30
+ SAFE_TRACK_USER_EVENTS_MODE = 'safe'
31
+ EXTENDED_TRACK_USER_EVENTS_MODE = 'extended'
15
32
  APPSEC_VALID_TRACK_USER_EVENTS_MODE = [
16
- 'safe',
17
- 'extended'
33
+ SAFE_TRACK_USER_EVENTS_MODE, EXTENDED_TRACK_USER_EVENTS_MODE
18
34
  ].freeze
19
- APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES = [
20
- '1',
21
- 'true'
22
- ].concat(APPSEC_VALID_TRACK_USER_EVENTS_MODE).freeze
35
+ APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES = ['1', 'true'].concat(
36
+ APPSEC_VALID_TRACK_USER_EVENTS_MODE
37
+ ).freeze
23
38
 
24
39
  def self.extended(base)
25
40
  base = base.singleton_class unless base.is_a?(Class)
@@ -49,6 +64,15 @@ module Datadog
49
64
  end
50
65
  end
51
66
 
67
+ # RASP or Runtime Application Self-Protection
68
+ # is a collection of techniques and heuristics aimed at detecting malicious inputs and preventing
69
+ # any potential side-effects on the application resulting from the use of said malicious inputs.
70
+ option :rasp_enabled do |o|
71
+ o.type :bool, nilable: true
72
+ o.env 'DD_APPSEC_RASP_ENABLED'
73
+ o.default true
74
+ end
75
+
52
76
  option :ruleset do |o|
53
77
  o.env 'DD_APPSEC_RULES'
54
78
  o.default :recommended
@@ -107,9 +131,12 @@ module Datadog
107
131
  o.type :string, nilable: true
108
132
  o.setter do |value|
109
133
  if value
110
- raise(ArgumentError, "appsec.templates.html: file not found: #{value}") unless File.exist?(value)
134
+ unless File.exist?(value)
135
+ raise(ArgumentError,
136
+ "appsec.templates.html: file not found: #{value}")
137
+ end
111
138
 
112
- File.open(value, 'rb', &:read) || ''
139
+ File.binread(value) || ''
113
140
  end
114
141
  end
115
142
  end
@@ -119,9 +146,12 @@ module Datadog
119
146
  o.type :string, nilable: true
120
147
  o.setter do |value|
121
148
  if value
122
- raise(ArgumentError, "appsec.templates.json: file not found: #{value}") unless File.exist?(value)
149
+ unless File.exist?(value)
150
+ raise(ArgumentError,
151
+ "appsec.templates.json: file not found: #{value}")
152
+ end
123
153
 
124
- File.open(value, 'rb', &:read) || ''
154
+ File.binread(value) || ''
125
155
  end
126
156
  end
127
157
  end
@@ -131,15 +161,101 @@ module Datadog
131
161
  o.type :string, nilable: true
132
162
  o.setter do |value|
133
163
  if value
134
- raise(ArgumentError, "appsec.templates.text: file not found: #{value}") unless File.exist?(value)
164
+ unless File.exist?(value)
165
+ raise(ArgumentError,
166
+ "appsec.templates.text: file not found: #{value}")
167
+ end
135
168
 
136
- File.open(value, 'rb', &:read) || ''
169
+ File.binread(value) || ''
137
170
  end
138
171
  end
139
172
  end
140
173
  end
141
174
  end
142
175
 
176
+ settings :stack_trace do
177
+ option :enabled do |o|
178
+ o.type :bool
179
+ o.env 'DD_APPSEC_STACK_TRACE_ENABLED'
180
+ o.default true
181
+ end
182
+
183
+ # The maximum number of stack trace frames to collect for each stack trace.
184
+ #
185
+ # If the stack trace exceeds this limit, the frames are dropped from the middle of the stack trace:
186
+ # 75% of the frames are kept from the top of the stack trace and 25% from the bottom
187
+ # (this percentage is also configurable).
188
+ #
189
+ # Minimum value is 10.
190
+ # Set to zero if you don't want any frames to be dropped.
191
+ #
192
+ # Default value is 32
193
+ option :max_depth do |o|
194
+ o.type :int
195
+ o.env 'DD_APPSEC_MAX_STACK_TRACE_DEPTH'
196
+ o.default 32
197
+
198
+ o.setter do |value|
199
+ value = 0 if value < 0
200
+ value
201
+ end
202
+ end
203
+
204
+ # The percentage of frames to keep from the top of the stack trace.
205
+ #
206
+ # Default value is 75
207
+ option :top_percentage do |o|
208
+ o.type :int
209
+ o.env 'DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT'
210
+ o.default 75
211
+
212
+ o.setter do |value|
213
+ value = 100 if value > 100
214
+ value = 0 if value.negative?
215
+ value
216
+ end
217
+ end
218
+
219
+ # Maximum number of stack traces to collect per span.
220
+ #
221
+ # Set to zero if you want to collect all stack traces.
222
+ #
223
+ # Default value is 2
224
+ option :max_stack_traces do |o|
225
+ o.type :int
226
+ o.env 'DD_APPSEC_MAX_STACK_TRACES'
227
+ o.default 2
228
+
229
+ o.setter do |value|
230
+ value = 0 if value < 0
231
+ value
232
+ end
233
+ end
234
+ end
235
+
236
+ settings :auto_user_instrumentation do
237
+ define_method(:enabled?) { get_option(:mode) != DISABLED_AUTO_USER_INSTRUMENTATION_MODE }
238
+
239
+ option :mode do |o|
240
+ o.type :string
241
+ o.env 'DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE'
242
+ o.default IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
243
+ o.setter do |value|
244
+ mode = AUTO_USER_INSTRUMENTATION_MODES_ALIASES.fetch(value, value)
245
+ next mode if AUTO_USER_INSTRUMENTATION_MODES.include?(mode)
246
+
247
+ Datadog.logger.warn(
248
+ 'The appsec.auto_user_instrumentation.mode value provided is not supported. ' \
249
+ "Supported values are: #{AUTO_USER_INSTRUMENTATION_MODES.join(" | ")}. " \
250
+ "Using value: #{DISABLED_AUTO_USER_INSTRUMENTATION_MODE}."
251
+ )
252
+
253
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE
254
+ end
255
+ end
256
+ end
257
+
258
+ # DEV-3.0: Remove `track_user_events.enabled` and `track_user_events.mode` options
143
259
  settings :track_user_events do
144
260
  option :enabled do |o|
145
261
  o.default true
@@ -152,24 +268,43 @@ module Datadog
152
268
  APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES.include?(env_value.strip.downcase)
153
269
  end
154
270
  end
271
+ o.after_set do |_, _, precedence|
272
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
273
+ Core.log_deprecation(key: :appsec_track_user_events_enabled) do
274
+ 'The appsec.track_user_events.enabled setting is deprecated. ' \
275
+ 'Please remove it from your Datadog.configure block and use ' \
276
+ 'appsec.auto_user_instrumentation.mode instead.'
277
+ end
278
+ end
279
+ end
155
280
  end
156
281
 
157
282
  option :mode do |o|
158
283
  o.type :string
159
284
  o.env 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING'
160
- o.default 'safe'
285
+ o.default SAFE_TRACK_USER_EVENTS_MODE
161
286
  o.setter do |v|
162
287
  if APPSEC_VALID_TRACK_USER_EVENTS_MODE.include?(v)
163
288
  v
164
289
  elsif v == 'disabled'
165
- 'safe'
290
+ SAFE_TRACK_USER_EVENTS_MODE
166
291
  else
167
292
  Datadog.logger.warn(
168
293
  'The appsec.track_user_events.mode value provided is not supported.' \
169
- 'Supported values are: safe | extended.' \
170
- 'Using default value `safe`'
294
+ "Supported values are: #{APPSEC_VALID_TRACK_USER_EVENTS_MODE.join(" | ")}." \
295
+ "Using default value: #{SAFE_TRACK_USER_EVENTS_MODE}."
171
296
  )
172
- 'safe'
297
+
298
+ SAFE_TRACK_USER_EVENTS_MODE
299
+ end
300
+ end
301
+ o.after_set do |_, _, precedence|
302
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
303
+ Core.log_deprecation(key: :appsec_track_user_events_mode) do
304
+ 'The appsec.track_user_events.mode setting is deprecated. ' \
305
+ 'Please remove it from your Datadog.configure block and use ' \
306
+ 'appsec.auto_user_instrumentation.mode instead.'
307
+ end
173
308
  end
174
309
  end
175
310
  end
@@ -197,14 +332,6 @@ module Datadog
197
332
  o.type :bool, nilable: true
198
333
  o.env 'DD_APPSEC_SCA_ENABLED'
199
334
  end
200
-
201
- settings :standalone do
202
- option :enabled do |o|
203
- o.type :bool
204
- o.env 'DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED'
205
- o.default false
206
- end
207
- end
208
335
  end
209
336
  end
210
337
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'metrics'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ # This class accumulates the context over the request life-cycle and exposes
8
+ # interface sufficient for instrumentation to perform threat detection.
9
+ class Context
10
+ ActiveContextError = Class.new(StandardError)
11
+
12
+ attr_reader :trace, :span, :events
13
+
14
+ class << self
15
+ def activate(context)
16
+ raise ArgumentError, 'not a Datadog::AppSec::Context' unless context.instance_of?(Context)
17
+ raise ActiveContextError, 'another context is active, nested contexts are not supported' if active
18
+
19
+ Thread.current[Ext::ACTIVE_CONTEXT_KEY] = context
20
+ end
21
+
22
+ def deactivate
23
+ active&.finalize
24
+ ensure
25
+ Thread.current[Ext::ACTIVE_CONTEXT_KEY] = nil
26
+ end
27
+
28
+ def active
29
+ Thread.current[Ext::ACTIVE_CONTEXT_KEY]
30
+ end
31
+ end
32
+
33
+ def initialize(trace, span, security_engine)
34
+ @trace = trace
35
+ @span = span
36
+ @events = []
37
+ @security_engine = security_engine
38
+ @waf_runner = security_engine.new_runner
39
+ @metrics = Metrics::Collector.new
40
+ end
41
+
42
+ def run_waf(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT)
43
+ result = @waf_runner.run(persistent_data, ephemeral_data, timeout)
44
+
45
+ @metrics.record_waf(result)
46
+ result
47
+ end
48
+
49
+ def run_rasp(type, persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT)
50
+ result = @waf_runner.run(persistent_data, ephemeral_data, timeout)
51
+
52
+ Metrics::Telemetry.report_rasp(type, result)
53
+ @metrics.record_rasp(result)
54
+
55
+ result
56
+ end
57
+
58
+ def extract_schema
59
+ @waf_runner.run({'waf.context.processor' => {'extract-schema' => true}}, {})
60
+ end
61
+
62
+ def export_metrics
63
+ return if @span.nil?
64
+
65
+ Metrics::Exporter.export_waf_metrics(@metrics.waf, @span)
66
+ Metrics::Exporter.export_rasp_metrics(@metrics.rasp, @span)
67
+ end
68
+
69
+ def finalize
70
+ @waf_runner.finalize
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../event'
4
+ require_relative '../../security_event'
5
+
6
+ module Datadog
7
+ module AppSec
8
+ module Contrib
9
+ module ActiveRecord
10
+ # AppSec module that will be prepended to ActiveRecord adapter
11
+ module Instrumentation
12
+ module_function
13
+
14
+ def detect_sql_injection(sql, adapter_name)
15
+ return unless AppSec.rasp_enabled?
16
+
17
+ context = AppSec.active_context
18
+ return unless context
19
+
20
+ # libddwaf expects db system to be lowercase,
21
+ # in case of sqlite adapter, libddwaf expects 'sqlite' as db system
22
+ db_system = adapter_name.downcase
23
+ db_system = 'sqlite' if db_system == 'sqlite3'
24
+
25
+ ephemeral_data = {
26
+ 'server.db.statement' => sql,
27
+ 'server.db.system' => db_system
28
+ }
29
+
30
+ waf_timeout = Datadog.configuration.appsec.waf_timeout
31
+ result = context.run_rasp(Ext::RASP_SQLI, {}, ephemeral_data, waf_timeout)
32
+
33
+ if result.match?
34
+ AppSec::Event.tag_and_keep!(context, result)
35
+
36
+ context.events.push(
37
+ AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
38
+ )
39
+
40
+ AppSec::ActionsHandler.handle(result.actions)
41
+ end
42
+ end
43
+
44
+ # patch for mysql2, sqlite3, and postgres+jdbc adapters in ActiveRecord >= 7.1
45
+ module InternalExecQueryAdapterPatch
46
+ def internal_exec_query(sql, *args, **rest)
47
+ Instrumentation.detect_sql_injection(sql, adapter_name)
48
+
49
+ super
50
+ end
51
+ end
52
+
53
+ # patch for mysql2, sqlite3, and postgres+jdbc adapters in ActiveRecord < 7.1
54
+ module ExecQueryAdapterPatch
55
+ def exec_query(sql, *args, **rest)
56
+ Instrumentation.detect_sql_injection(sql, adapter_name)
57
+
58
+ super
59
+ end
60
+ end
61
+
62
+ # patch for mysql2, sqlite3, and postgres+jdbc db adapters in ActiveRecord 4
63
+ module Rails4ExecQueryAdapterPatch
64
+ def exec_query(sql, *args)
65
+ Instrumentation.detect_sql_injection(sql, adapter_name)
66
+
67
+ super
68
+ end
69
+ end
70
+
71
+ # patch for non-jdbc postgres adapter in ActiveRecord > 4
72
+ module ExecuteAndClearAdapterPatch
73
+ def execute_and_clear(sql, *args, **rest)
74
+ Instrumentation.detect_sql_injection(sql, adapter_name)
75
+
76
+ super
77
+ end
78
+ end
79
+
80
+ # patch for non-jdbc postgres adapter in ActiveRecord 4
81
+ module Rails4ExecuteAndClearAdapterPatch
82
+ def execute_and_clear(sql, name, binds)
83
+ Instrumentation.detect_sql_injection(sql, adapter_name)
84
+
85
+ super
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,41 @@
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 ActiveRecord
10
+ # This class provides helper methods that are used when patching ActiveRecord
11
+ class Integration
12
+ include Datadog::AppSec::Contrib::Integration
13
+
14
+ MINIMUM_VERSION = Gem::Version.new('4')
15
+
16
+ register_as :active_record, auto_patch: true
17
+
18
+ def self.version
19
+ Gem.loaded_specs['activerecord']&.version
20
+ end
21
+
22
+ def self.loaded?
23
+ !defined?(::ActiveRecord).nil?
24
+ end
25
+
26
+ def self.compatible?
27
+ super && version >= MINIMUM_VERSION
28
+ end
29
+
30
+ def self.auto_instrument?
31
+ true
32
+ end
33
+
34
+ def patcher
35
+ Patcher
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'instrumentation'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ module Contrib
8
+ module ActiveRecord
9
+ # AppSec patcher module for ActiveRecord
10
+ module Patcher
11
+ module_function
12
+
13
+ def patched?
14
+ Patcher.instance_variable_get(:@patched)
15
+ end
16
+
17
+ def target_version
18
+ Integration.version
19
+ end
20
+
21
+ def patch
22
+ # Rails 7.0 intruduced new on-load hooks for sqlite3 and postgresql adapters
23
+ # The load hook for mysql2 adapter was introduced in Rails 7.1
24
+ #
25
+ # If the adapter is not loaded when the :active_record load hook is called,
26
+ # we need to add a load hook for the adapter
27
+ ActiveSupport.on_load :active_record do
28
+ if defined?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
29
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
30
+ else
31
+ ActiveSupport.on_load :active_record_sqlite3adapter do
32
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
33
+ end
34
+ end
35
+
36
+ if defined?(::ActiveRecord::ConnectionAdapters::Mysql2Adapter)
37
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
38
+ else
39
+ ActiveSupport.on_load :active_record_mysql2adapter do
40
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
41
+ end
42
+ end
43
+
44
+ if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
45
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
46
+ else
47
+ ActiveSupport.on_load :active_record_postgresqladapter do
48
+ ::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def patch_sqlite3_adapter
55
+ instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
56
+ Instrumentation::InternalExecQueryAdapterPatch
57
+ elsif ::ActiveRecord.gem_version.segments.first == 4
58
+ Instrumentation::Rails4ExecQueryAdapterPatch
59
+ else
60
+ Instrumentation::ExecQueryAdapterPatch
61
+ end
62
+
63
+ ::ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(instrumentation_module)
64
+ end
65
+
66
+ def patch_mysql2_adapter
67
+ instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
68
+ Instrumentation::InternalExecQueryAdapterPatch
69
+ elsif ::ActiveRecord.gem_version.segments.first == 4
70
+ Instrumentation::Rails4ExecQueryAdapterPatch
71
+ else
72
+ Instrumentation::ExecQueryAdapterPatch
73
+ end
74
+
75
+ ::ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(instrumentation_module)
76
+ end
77
+
78
+ def patch_postgresql_adapter
79
+ instrumentation_module = if ::ActiveRecord.gem_version.segments.first == 4
80
+ Instrumentation::Rails4ExecuteAndClearAdapterPatch
81
+ else
82
+ Instrumentation::ExecuteAndClearAdapterPatch
83
+ end
84
+
85
+ if defined?(::ActiveRecord::ConnectionAdapters::JdbcAdapter)
86
+ instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
87
+ Instrumentation::InternalExecQueryAdapterPatch
88
+ elsif ::ActiveRecord.gem_version.segments.first == 4
89
+ Instrumentation::Rails4ExecQueryAdapterPatch
90
+ else
91
+ Instrumentation::ExecQueryAdapterPatch
92
+ end
93
+ end
94
+
95
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(instrumentation_module)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -9,7 +9,7 @@ module Datadog
9
9
  def self.patch_all
10
10
  integrations = []
11
11
 
12
- Datadog::AppSec::Contrib::Integration.registry.each do |_name, integration|
12
+ Datadog::AppSec::Contrib::Integration.registry.each_value do |integration|
13
13
  next unless integration.klass.auto_instrument?
14
14
 
15
15
  integrations << integration.name
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ module Contrib
6
+ module Devise
7
+ # A temporary configuration module to accomodate new RFC changes.
8
+ # NOTE: DEV-3 Remove module
9
+ module Configuration
10
+ TRACK_USER_EVENTS_CONVERSION_RULES = {
11
+ AppSec::Configuration::Settings::SAFE_TRACK_USER_EVENTS_MODE =>
12
+ AppSec::Configuration::Settings::ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
13
+ AppSec::Configuration::Settings::EXTENDED_TRACK_USER_EVENTS_MODE =>
14
+ AppSec::Configuration::Settings::IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
15
+ }.freeze
16
+
17
+ module_function
18
+
19
+ # NOTE: DEV-3 Replace method use with `auto_user_instrumentation.enabled?`
20
+ def auto_user_instrumentation_enabled?
21
+ appsec = Datadog.configuration.appsec
22
+ appsec.auto_user_instrumentation.mode
23
+
24
+ unless appsec.auto_user_instrumentation.options[:mode].default_precedence?
25
+ return appsec.auto_user_instrumentation.enabled?
26
+ end
27
+
28
+ appsec.track_user_events.enabled
29
+ end
30
+
31
+ # NOTE: DEV-3 Replace method use with `auto_user_instrumentation.mode`
32
+ def auto_user_instrumentation_mode
33
+ appsec = Datadog.configuration.appsec
34
+
35
+ # NOTE: Reading both to trigger precedence set
36
+ appsec.auto_user_instrumentation.mode
37
+ appsec.track_user_events.mode
38
+
39
+ if !appsec.track_user_events.options[:mode].default_precedence? &&
40
+ appsec.auto_user_instrumentation.options[:mode].default_precedence?
41
+ return TRACK_USER_EVENTS_CONVERSION_RULES.fetch(
42
+ appsec.track_user_events.mode, appsec.auto_user_instrumentation.mode
43
+ )
44
+ end
45
+
46
+ appsec.auto_user_instrumentation.mode
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end