cw-datadog 2.23.0.2 → 2.23.0.3

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/ext/datadog_profiling_native_extension/extconf.rb +4 -2
  3. data/ext/libdatadog_api/library_config.c +12 -11
  4. data/ext/libdatadog_extconf_helpers.rb +1 -1
  5. data/lib/datadog/appsec/api_security/route_extractor.rb +20 -5
  6. data/lib/datadog/appsec/api_security/sampler.rb +3 -1
  7. data/lib/datadog/appsec/assets/blocked.html +8 -0
  8. data/lib/datadog/appsec/assets/blocked.json +1 -1
  9. data/lib/datadog/appsec/assets/blocked.text +3 -1
  10. data/lib/datadog/appsec/assets.rb +1 -1
  11. data/lib/datadog/appsec/remote.rb +4 -0
  12. data/lib/datadog/appsec/response.rb +18 -4
  13. data/lib/datadog/core/cloudwise/client.rb +364 -25
  14. data/lib/datadog/core/cloudwise/component.rb +197 -52
  15. data/lib/datadog/core/cloudwise/docc_heartbeat_worker.rb +105 -0
  16. data/lib/datadog/core/cloudwise/docc_operation_worker.rb +191 -0
  17. data/lib/datadog/core/cloudwise/docc_registration_worker.rb +89 -0
  18. data/lib/datadog/core/cloudwise/license_worker.rb +3 -1
  19. data/lib/datadog/core/cloudwise/probe_state.rb +134 -12
  20. data/lib/datadog/core/configuration/components.rb +10 -9
  21. data/lib/datadog/core/configuration/settings.rb +28 -0
  22. data/lib/datadog/core/configuration/supported_configurations.rb +5 -2
  23. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  24. data/lib/datadog/core/remote/component.rb +2 -2
  25. data/lib/datadog/core/remote/transport/config.rb +2 -10
  26. data/lib/datadog/core/remote/transport/http/config.rb +9 -9
  27. data/lib/datadog/core/remote/transport/http/negotiation.rb +17 -8
  28. data/lib/datadog/core/remote/transport/http.rb +2 -0
  29. data/lib/datadog/core/remote/transport/negotiation.rb +2 -18
  30. data/lib/datadog/core/remote/worker.rb +23 -35
  31. data/lib/datadog/core/telemetry/component.rb +26 -13
  32. data/lib/datadog/core/telemetry/event/app_started.rb +67 -49
  33. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  34. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -6
  35. data/lib/datadog/core/telemetry/transport/telemetry.rb +1 -2
  36. data/lib/datadog/core/telemetry/worker.rb +51 -6
  37. data/lib/datadog/core/transport/http/adapters/net.rb +2 -0
  38. data/lib/datadog/core/transport/http/client.rb +69 -0
  39. data/lib/datadog/core/utils/only_once_successful.rb +6 -2
  40. data/lib/datadog/data_streams/transport/http/client.rb +4 -32
  41. data/lib/datadog/data_streams/transport/stats.rb +1 -1
  42. data/lib/datadog/di/probe_notification_builder.rb +35 -13
  43. data/lib/datadog/di/transport/diagnostics.rb +2 -2
  44. data/lib/datadog/di/transport/http/diagnostics.rb +2 -4
  45. data/lib/datadog/di/transport/http/input.rb +2 -4
  46. data/lib/datadog/di/transport/input.rb +2 -2
  47. data/lib/datadog/open_feature/component.rb +60 -0
  48. data/lib/datadog/open_feature/configuration.rb +27 -0
  49. data/lib/datadog/open_feature/evaluation_engine.rb +59 -0
  50. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  51. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  52. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  53. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  54. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  55. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  56. data/lib/datadog/open_feature/ext.rb +13 -0
  57. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  58. data/lib/datadog/open_feature/provider.rb +134 -0
  59. data/lib/datadog/open_feature/remote.rb +74 -0
  60. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  61. data/lib/datadog/open_feature/transport.rb +72 -0
  62. data/lib/datadog/open_feature.rb +19 -0
  63. data/lib/datadog/profiling/component.rb +6 -0
  64. data/lib/datadog/profiling/profiler.rb +4 -0
  65. data/lib/datadog/profiling.rb +1 -2
  66. data/lib/datadog/single_step_instrument.rb +1 -1
  67. data/lib/datadog/tracing/contrib/cloudwise/propagation.rb +164 -7
  68. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
  69. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  70. data/lib/datadog/tracing/contrib/karafka/patcher.rb +14 -0
  71. data/lib/datadog/tracing/contrib/rack/middlewares.rb +6 -2
  72. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  73. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  74. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  75. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  76. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  77. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +46 -0
  78. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  79. data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
  80. data/lib/datadog/tracing/contrib.rb +1 -0
  81. data/lib/datadog/tracing/transport/http/api.rb +40 -1
  82. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  83. data/lib/datadog/tracing/transport/http/traces.rb +4 -2
  84. data/lib/datadog/tracing/transport/trace_formatter.rb +16 -0
  85. data/lib/datadog/version.rb +2 -2
  86. data/lib/datadog.rb +1 -0
  87. metadata +38 -15
  88. data/lib/datadog/core/cloudwise/IMPLEMENTATION_V2.md +0 -517
  89. data/lib/datadog/core/cloudwise/QUICKSTART.md +0 -398
  90. data/lib/datadog/core/cloudwise/README.md +0 -722
  91. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  92. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  93. data/lib/datadog/di/transport/http/client.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1df9f1c701dfee9c819f80db1e8e764e10d0a283556d63aa89ec0cd7b1ebbdb4
4
- data.tar.gz: 20190b5ab1f748d04967ced16fb2dd2f1a816f78c7cbd147313004876c8d8006
3
+ metadata.gz: e48258b923a9015853cdfcb2b879dfcf9cc347ca9c8ade2ec013d66c0752ed93
4
+ data.tar.gz: '0998633db06aa8661eeb1f75bb6b4a18460109ae6815671cdcc6e10f8def8a30'
5
5
  SHA512:
6
- metadata.gz: b59b083e935746d529131ecf3e068d25330b825eaeca87e68cba933309baa620a08aefc2d8995e06199b37384bda49c4ea1dd14498e365031b3ade42834fd04f
7
- data.tar.gz: 1ae963ed6f4812e7cdd7d0d1439a7cb4ed7d5a74ae957f2b41fffb5a7aeba54cbbd48c1e71f67a4d3e021a3f8b48bc5fa0f50568f6162012f859d02b15290770
6
+ metadata.gz: 216d0de9105aecd55f60d887be3c1779d3fdb51aa120f454a4b8ab7093f6e0e64fe06df5d9ea69677c94a190ed1cd767f67be0fd98c255b137c64495f9208447
7
+ data.tar.gz: 126ae7bae30741f6b010cf6e13dd5ff013f0a2e69a82bf2a156043260142781e520f4d87341bebbd4d928e599790094e67af55f505e1f08c138eca515e2ef77e
@@ -141,8 +141,10 @@ end
141
141
  # On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
142
142
  $defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "3.5"
143
143
 
144
- # On Ruby 2.5 and 3.3, this symbol was not visible. It is on 2.6 to 3.2, as well as 3.4+
145
- $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3")
144
+ # This symbol is exclusively visible on certain Ruby versions: 2.6 to 3.2, as well as 3.4 and 3.5-preview1 (but not 4.0)
145
+ # It's only used to get extra information about an object when a failure happens, so it's a "very nice to have" but not
146
+ # actually required for correct behavior of the profiler.
147
+ $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3", "4.0")
146
148
 
147
149
  # On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
148
150
  $defs << "-DNO_POSTPONED_TRIGGER" if RUBY_VERSION < "3.3"
@@ -99,27 +99,28 @@ static VALUE _native_configurator_get(VALUE self) {
99
99
  ddog_Configurator *configurator;
100
100
  TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);
101
101
 
102
- // Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
103
- // We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
104
- // So we cannot reference it with &config_logged_result
105
- // We are doing this in case one of the ruby API raises an exception before the end of this function,
106
- // so the allocated memory will still be freed
107
- ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
108
- *configurator_logged_result = ddog_library_configurator_get(configurator);
109
- VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);
102
+ // We don't allocate memory here so if there is an error, we don't need to manage the memory
103
+ ddog_LibraryConfigLoggedResult before_error_result = ddog_library_configurator_get(configurator);
110
104
 
111
- if (configurator_logged_result->tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
112
- ddog_Error err = configurator_logged_result->err;
105
+ if (before_error_result.tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
106
+ ddog_Error err = before_error_result.err;
113
107
  VALUE message = get_error_details_and_drop(&err);
114
108
  if (is_config_loaded()) {
115
109
  log_warning(message);
116
110
  } else {
117
111
  log_warning_without_config(message);
118
112
  }
119
- RB_GC_GUARD(config_logged_result_rb);
120
113
  return rb_hash_new();
121
114
  }
122
115
 
116
+ // Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
117
+ // We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
118
+ // We are doing this in case one of the ruby API raises an exception before the end of this function,
119
+ // so the allocated memory will still be freed
120
+ ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
121
+ *configurator_logged_result = before_error_result;
122
+ VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);
123
+
123
124
  VALUE logs = Qnil;
124
125
  if (configurator_logged_result->ok.logs.length > 0) {
125
126
  logs = rb_utf8_str_new_cstr(configurator_logged_result->ok.logs.ptr);
@@ -10,7 +10,7 @@ module Datadog
10
10
  module LibdatadogExtconfHelpers
11
11
  # Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
12
12
  # may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
13
- LIBDATADOG_VERSION = '~> 23.0.0.1.0'
13
+ LIBDATADOG_VERSION = '~> 24.0.1.1.0'
14
14
 
15
15
  # Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
16
16
  # libdatadog are moved after the extension gets compiled.
@@ -10,7 +10,8 @@ module Datadog
10
10
  SINATRA_ROUTE_KEY = 'sinatra.route'
11
11
  SINATRA_ROUTE_SEPARATOR = ' '
12
12
  GRAPE_ROUTE_KEY = 'grape.routing_args'
13
- RAILS_ROUTE_KEY = 'action_dispatch.route_uri_pattern'
13
+ RAILS_ROUTE_URI_PATTERN_KEY = 'action_dispatch.route_uri_pattern'
14
+ RAILS_ROUTE_KEY = 'action_dispatch.route' # Rails 8.1.1+
14
15
  RAILS_ROUTES_KEY = 'action_dispatch.routes'
15
16
  RAILS_PATH_PARAMS_KEY = 'action_dispatch.request.path_parameters'
16
17
  RAILS_FORMAT_SUFFIX = '(.:format)'
@@ -37,6 +38,9 @@ module Datadog
37
38
  # Rails > 7.1 (fast path)
38
39
  # uses `action_dispatch.route_uri_pattern` with a string like
39
40
  # "/users/:id(.:format)"
41
+ # Rails > 8.1.1 (fast path)
42
+ # uses `action_dispatch.route` to store the ActionDispatch::Journey::Route
43
+ # that matched when the request was routed
40
44
  #
41
45
  # WARNING: This method works only *after* the request has been routed.
42
46
  #
@@ -52,11 +56,18 @@ module Datadog
52
56
  pattern = request.env[SINATRA_ROUTE_KEY].split(SINATRA_ROUTE_SEPARATOR, 2)[1]
53
57
  "#{request.script_name}#{pattern}"
54
58
  elsif request.env.key?(RAILS_ROUTE_KEY)
55
- request.env[RAILS_ROUTE_KEY].delete_suffix(RAILS_FORMAT_SUFFIX)
59
+ request.env[RAILS_ROUTE_KEY].path.spec.to_s.delete_suffix(RAILS_FORMAT_SUFFIX)
60
+ elsif request.env.key?(RAILS_ROUTE_URI_PATTERN_KEY)
61
+ request.env[RAILS_ROUTE_URI_PATTERN_KEY].delete_suffix(RAILS_FORMAT_SUFFIX)
56
62
  elsif request.env.key?(RAILS_ROUTES_KEY) && !request.env.fetch(RAILS_PATH_PARAMS_KEY, {}).empty?
57
- # NOTE: Rails mutate HEAD request in order to understand that route is supported.
58
- # It will assing GET request method and run the route recognition.
59
- request = request.env[RAILS_ROUTES_KEY].request_class.new(request.env) if request.head?
63
+ # NOTE: In Rails < 7.1 this `request` argument will be a Rack::Request,
64
+ # it does not have all the methods that ActionDispatch::Request has.
65
+ # Before trying to use the router to recognize the route, we need to
66
+ # create a new ActionDispatch::Request from the request env
67
+ #
68
+ # NOTE: Rails mutates HEAD request by changing the method to GET
69
+ # and uses it for route recognition to check if the route is defined
70
+ request = request.env[RAILS_ROUTES_KEY].request_class.new(request.env)
60
71
 
61
72
  pattern = request.env[RAILS_ROUTES_KEY].router
62
73
  .recognize(request) { |route, _| break route.path.spec.to_s }
@@ -70,6 +81,10 @@ module Datadog
70
81
  else
71
82
  Tracing::Contrib::Rack::RouteInference.read_or_infer(request.env)
72
83
  end
84
+ rescue => e
85
+ AppSec.telemetry&.report(e, description: 'AppSec: Could not extract route pattern')
86
+
87
+ nil
73
88
  end
74
89
  end
75
90
  end
@@ -45,7 +45,9 @@ module Datadog
45
45
  return true if @sample_delay_seconds.zero?
46
46
  return false if response.status == 404
47
47
 
48
- key = Zlib.crc32("#{request.request_method}#{RouteExtractor.route_pattern(request)}#{response.status}")
48
+ route_pattern = RouteExtractor.route_pattern(request).to_s
49
+
50
+ key = Zlib.crc32("#{request.request_method}#{route_pattern}#{response.status}")
49
51
  current_timestamp = Core::Utils::Time.now.to_i
50
52
  cached_timestamp = @cache[key] || 0
51
53
 
@@ -82,12 +82,20 @@
82
82
  footer p {
83
83
  font-size: 16px
84
84
  }
85
+
86
+ .security-response-id {
87
+ font-size:14px;
88
+ color:#999;
89
+ margin-top:20px;
90
+ font-family:monospace
91
+ }
85
92
  </style>
86
93
  </head>
87
94
 
88
95
  <body>
89
96
  <main>
90
97
  <p>Sorry, you cannot access this page. Please contact the customer service team.</p>
98
+ <p class="security-response-id">Security Response ID: [security_response_id]</p>
91
99
  </main>
92
100
  <footer>
93
101
  <p>Security provided by <a
@@ -1 +1 @@
1
- {"errors": [{"title": "You've been blocked", "detail": "Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]}
1
+ {"errors":[{"title":"You've been blocked","detail":"Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}],"security_response_id":"[security_response_id]"}
@@ -1,5 +1,7 @@
1
- You've been blocked
1
+ You've been blocked.
2
2
 
3
3
  Sorry, you cannot access this page. Please contact the customer service team.
4
4
 
5
+ Security Response ID: [security_response_id]
6
+
5
7
  Security provided by Datadog.
@@ -21,7 +21,7 @@ module Datadog
21
21
  end
22
22
 
23
23
  def blocked(format: :html)
24
- (@blocked ||= {})[format] ||= read("blocked.#{format}")
24
+ (@blocked ||= {})[format] ||= read("blocked.#{format}").freeze
25
25
  end
26
26
 
27
27
  def path
@@ -23,6 +23,8 @@ module Datadog
23
23
  CAP_ASM_CUSTOM_RULES = 1 << 8
24
24
  CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9
25
25
  CAP_ASM_TRUSTED_IPS = 1 << 10
26
+ CAP_ASM_PROCESSOR_OVERRIDES = 1 << 16
27
+ CAP_ASM_CUSTOM_DATA_SCANNERS = 1 << 17
26
28
  CAP_ASM_RASP_SSRF = 1 << 23
27
29
  CAP_ASM_RASP_SQLI = 1 << 21
28
30
  CAP_ASM_AUTO_USER_INSTRUM_MODE = 1 << 31
@@ -43,6 +45,8 @@ module Datadog
43
45
  CAP_ASM_CUSTOM_RULES,
44
46
  CAP_ASM_CUSTOM_BLOCKING_RESPONSE,
45
47
  CAP_ASM_TRUSTED_IPS,
48
+ CAP_ASM_PROCESSOR_OVERRIDES,
49
+ CAP_ASM_CUSTOM_DATA_SCANNERS,
46
50
  CAP_ASM_RASP_SSRF,
47
51
  CAP_ASM_RASP_SQLI,
48
52
  CAP_ASM_AUTO_USER_INSTRUM_MODE,
@@ -7,6 +7,8 @@ module Datadog
7
7
  module AppSec
8
8
  # AppSec response
9
9
  class Response
10
+ SECURITY_RESPONSE_ID_PLACEHOLDER = '[security_response_id]'
11
+
10
12
  attr_reader :status, :headers, :body
11
13
 
12
14
  def initialize(status:, headers: {}, body: [])
@@ -37,16 +39,26 @@ module Datadog
37
39
  Response.new(
38
40
  status: interrupt_params['status_code']&.to_i || 403,
39
41
  headers: {'Content-Type' => content_type},
40
- body: [content(content_type)],
42
+ body: [
43
+ content(
44
+ security_response_id: interrupt_params['security_response_id'],
45
+ content_type: content_type
46
+ )
47
+ ],
41
48
  )
42
49
  end
43
50
 
44
51
  def redirect_response(interrupt_params)
45
52
  status_code = interrupt_params['status_code'].to_i
53
+ location = interrupt_params.fetch('location')
54
+
55
+ if (security_response_id = interrupt_params.fetch('security_response_id'))
56
+ location.gsub!(SECURITY_RESPONSE_ID_PLACEHOLDER, security_response_id)
57
+ end
46
58
 
47
59
  Response.new(
48
60
  status: ((status_code >= 300 && status_code < 400) ? status_code : 303),
49
- headers: {'Location' => interrupt_params.fetch('location')},
61
+ headers: {'Location' => location},
50
62
  body: [],
51
63
  )
52
64
  end
@@ -82,16 +94,18 @@ module Datadog
82
94
  DEFAULT_CONTENT_TYPE
83
95
  end
84
96
 
85
- def content(content_type)
97
+ def content(security_response_id:, content_type:)
86
98
  content_format = CONTENT_TYPE_TO_FORMAT[content_type]
87
99
 
88
100
  using_default = Datadog.configuration.appsec.block.templates.using_default?(content_format)
89
101
 
90
- if using_default
102
+ template = if using_default
91
103
  Datadog::AppSec::Assets.blocked(format: content_format)
92
104
  else
93
105
  Datadog.configuration.appsec.block.templates.send(content_format)
94
106
  end
107
+
108
+ template.gsub(SECURITY_RESPONSE_ID_PLACEHOLDER, security_response_id.to_s)
95
109
  end
96
110
  end
97
111
  end