dd-trace 5.53.0 → 5.55.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 (368) hide show
  1. package/LICENSE-3rdparty.csv +2 -1
  2. package/ci/cypress/plugin.js +8 -0
  3. package/ci/cypress/polyfills.js +23 -0
  4. package/ci/init.js +8 -7
  5. package/index.d.ts +33 -16
  6. package/initialize.mjs +5 -6
  7. package/package.json +40 -38
  8. package/packages/datadog-code-origin/index.js +22 -4
  9. package/packages/datadog-core/src/utils/src/get.js +1 -1
  10. package/packages/datadog-core/src/utils/src/has.js +1 -1
  11. package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
  12. package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
  13. package/packages/datadog-core/src/utils/src/pick.js +2 -2
  14. package/packages/datadog-core/src/utils/src/set.js +1 -1
  15. package/packages/datadog-core/src/utils/src/uniq.js +1 -1
  16. package/packages/datadog-instrumentations/src/amqp10.js +19 -17
  17. package/packages/datadog-instrumentations/src/amqplib.js +52 -35
  18. package/packages/datadog-instrumentations/src/apollo.js +2 -2
  19. package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
  20. package/packages/datadog-instrumentations/src/cassandra-driver.js +10 -10
  21. package/packages/datadog-instrumentations/src/child_process.js +1 -2
  22. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +89 -75
  23. package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
  24. package/packages/datadog-instrumentations/src/couchbase.js +6 -9
  25. package/packages/datadog-instrumentations/src/cucumber.js +108 -68
  26. package/packages/datadog-instrumentations/src/cypress.js +2 -1
  27. package/packages/datadog-instrumentations/src/dns.js +5 -5
  28. package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
  29. package/packages/datadog-instrumentations/src/fastify.js +7 -9
  30. package/packages/datadog-instrumentations/src/fs.js +1 -1
  31. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +35 -43
  32. package/packages/datadog-instrumentations/src/graphql.js +7 -10
  33. package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
  34. package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
  35. package/packages/datadog-instrumentations/src/hapi.js +10 -11
  36. package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
  37. package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
  38. package/packages/datadog-instrumentations/src/helpers/hook.js +2 -3
  39. package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
  40. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
  41. package/packages/datadog-instrumentations/src/helpers/register.js +11 -12
  42. package/packages/datadog-instrumentations/src/http/client.js +14 -20
  43. package/packages/datadog-instrumentations/src/jest.js +201 -143
  44. package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
  45. package/packages/datadog-instrumentations/src/knex.js +4 -4
  46. package/packages/datadog-instrumentations/src/koa.js +2 -3
  47. package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
  48. package/packages/datadog-instrumentations/src/mariadb.js +49 -65
  49. package/packages/datadog-instrumentations/src/mocha/main.js +116 -73
  50. package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
  51. package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
  52. package/packages/datadog-instrumentations/src/mocha.js +3 -1
  53. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  54. package/packages/datadog-instrumentations/src/mysql.js +30 -37
  55. package/packages/datadog-instrumentations/src/mysql2.js +53 -47
  56. package/packages/datadog-instrumentations/src/net.js +1 -1
  57. package/packages/datadog-instrumentations/src/next.js +1 -0
  58. package/packages/datadog-instrumentations/src/nyc.js +3 -2
  59. package/packages/datadog-instrumentations/src/openai.js +22 -24
  60. package/packages/datadog-instrumentations/src/oracledb.js +1 -1
  61. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
  62. package/packages/datadog-instrumentations/src/pg.js +3 -5
  63. package/packages/datadog-instrumentations/src/playwright.js +123 -83
  64. package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
  65. package/packages/datadog-instrumentations/src/redis.js +4 -4
  66. package/packages/datadog-instrumentations/src/restify.js +9 -13
  67. package/packages/datadog-instrumentations/src/rhea.js +42 -54
  68. package/packages/datadog-instrumentations/src/router.js +30 -32
  69. package/packages/datadog-instrumentations/src/tedious.js +2 -3
  70. package/packages/datadog-instrumentations/src/vitest.js +87 -52
  71. package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
  72. package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
  73. package/packages/datadog-plugin-amqplib/src/client.js +6 -2
  74. package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
  75. package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
  76. package/packages/datadog-plugin-amqplib/src/util.js +1 -1
  77. package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
  78. package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
  79. package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
  80. package/packages/datadog-plugin-aws-sdk/src/base.js +15 -10
  81. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  82. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
  83. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
  84. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +28 -43
  85. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  86. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +10 -11
  87. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +4 -6
  88. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
  89. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
  90. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -3
  91. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +11 -15
  92. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  93. package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
  94. package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
  95. package/packages/datadog-plugin-child_process/src/index.js +4 -4
  96. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
  97. package/packages/datadog-plugin-cucumber/src/index.js +60 -4
  98. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +99 -28
  99. package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
  100. package/packages/datadog-plugin-cypress/src/support.js +24 -5
  101. package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
  102. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  103. package/packages/datadog-plugin-express/src/code_origin.js +30 -0
  104. package/packages/datadog-plugin-express/src/index.js +10 -12
  105. package/packages/datadog-plugin-express/src/tracing.js +19 -0
  106. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
  107. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
  108. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
  109. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +27 -10
  110. package/packages/datadog-plugin-graphql/src/execute.js +2 -2
  111. package/packages/datadog-plugin-graphql/src/index.js +10 -8
  112. package/packages/datadog-plugin-graphql/src/resolve.js +19 -12
  113. package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
  114. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
  115. package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
  116. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  117. package/packages/datadog-plugin-grpc/src/util.js +2 -2
  118. package/packages/datadog-plugin-http/src/client.js +23 -13
  119. package/packages/datadog-plugin-http2/src/client.js +24 -25
  120. package/packages/datadog-plugin-jest/src/index.js +26 -23
  121. package/packages/datadog-plugin-jest/src/util.js +8 -8
  122. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
  123. package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
  124. package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
  125. package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
  126. package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
  127. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
  128. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
  129. package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
  130. package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
  131. package/packages/datadog-plugin-mariadb/src/index.js +3 -9
  132. package/packages/datadog-plugin-mocha/src/index.js +39 -14
  133. package/packages/datadog-plugin-mongodb-core/src/index.js +3 -2
  134. package/packages/datadog-plugin-mysql/src/index.js +22 -9
  135. package/packages/datadog-plugin-mysql2/src/index.js +16 -0
  136. package/packages/datadog-plugin-net/src/tcp.js +1 -1
  137. package/packages/datadog-plugin-next/src/index.js +7 -6
  138. package/packages/datadog-plugin-openai/src/services.js +6 -10
  139. package/packages/datadog-plugin-openai/src/tracing.js +12 -18
  140. package/packages/datadog-plugin-oracledb/src/index.js +1 -1
  141. package/packages/datadog-plugin-playwright/src/index.js +25 -4
  142. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
  143. package/packages/datadog-plugin-redis/src/index.js +2 -4
  144. package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
  145. package/packages/datadog-plugin-rhea/src/producer.js +5 -2
  146. package/packages/datadog-plugin-router/src/index.js +1 -1
  147. package/packages/datadog-plugin-selenium/src/index.js +1 -6
  148. package/packages/datadog-plugin-vitest/src/index.js +52 -35
  149. package/packages/datadog-shimmer/src/shimmer.js +4 -8
  150. package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
  151. package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
  152. package/packages/dd-trace/src/appsec/blocking.js +6 -20
  153. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
  154. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
  155. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
  156. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
  157. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
  158. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +5 -8
  159. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
  160. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
  161. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
  162. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
  163. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
  164. package/packages/dd-trace/src/appsec/iast/index.js +1 -0
  165. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
  166. package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
  167. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +16 -24
  168. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
  169. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
  170. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
  171. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
  172. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -8
  173. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
  174. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  175. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +7 -8
  176. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  177. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -7
  178. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +2 -3
  179. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
  180. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
  181. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
  182. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
  183. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -28
  184. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
  185. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
  186. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
  187. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
  188. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
  189. package/packages/dd-trace/src/appsec/index.js +5 -5
  190. package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
  191. package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
  192. package/packages/dd-trace/src/appsec/reporter.js +232 -41
  193. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  194. package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
  195. package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
  196. package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
  197. package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
  198. package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
  199. package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
  200. package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
  201. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +8 -4
  202. package/packages/dd-trace/src/azure_metadata.js +9 -9
  203. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +9 -8
  204. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
  205. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +3 -2
  206. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
  207. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +3 -2
  208. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +3 -2
  209. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +3 -2
  210. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
  211. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
  212. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
  213. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
  214. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +3 -2
  215. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +5 -4
  216. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +12 -8
  217. package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
  218. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +3 -2
  219. package/packages/dd-trace/src/config-helper.js +89 -0
  220. package/packages/dd-trace/src/config.js +159 -129
  221. package/packages/dd-trace/src/config_stable.js +10 -7
  222. package/packages/dd-trace/src/datastreams/encoding.js +9 -9
  223. package/packages/dd-trace/src/datastreams/fnv.js +2 -2
  224. package/packages/dd-trace/src/datastreams/pathway.js +4 -4
  225. package/packages/dd-trace/src/datastreams/processor.js +5 -7
  226. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +7 -7
  227. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
  228. package/packages/dd-trace/src/datastreams/size.js +1 -1
  229. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +75 -69
  230. package/packages/dd-trace/src/debugger/devtools_client/condition.js +7 -10
  231. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
  232. package/packages/dd-trace/src/debugger/devtools_client/index.js +9 -2
  233. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
  234. package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -2
  235. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
  236. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
  237. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +11 -14
  238. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +4 -4
  239. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
  240. package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
  241. package/packages/dd-trace/src/debugger/index.js +1 -0
  242. package/packages/dd-trace/src/dogstatsd.js +7 -6
  243. package/packages/dd-trace/src/encode/0.4.js +14 -11
  244. package/packages/dd-trace/src/encode/0.5.js +4 -6
  245. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +8 -8
  246. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
  247. package/packages/dd-trace/src/encode/tags-processors.js +1 -1
  248. package/packages/dd-trace/src/exporter.js +7 -6
  249. package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
  250. package/packages/dd-trace/src/exporters/common/docker.js +4 -3
  251. package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
  252. package/packages/dd-trace/src/exporters/common/request.js +5 -2
  253. package/packages/dd-trace/src/exporters/common/util.js +4 -2
  254. package/packages/dd-trace/src/external-logger/src/index.js +5 -5
  255. package/packages/dd-trace/src/flare/file.js +1 -5
  256. package/packages/dd-trace/src/format.js +1 -1
  257. package/packages/dd-trace/src/git_properties.js +1 -1
  258. package/packages/dd-trace/src/id.js +15 -9
  259. package/packages/dd-trace/src/iitm.js +10 -22
  260. package/packages/dd-trace/src/index.js +4 -3
  261. package/packages/dd-trace/src/lambda/handler.js +7 -6
  262. package/packages/dd-trace/src/lambda/index.js +2 -1
  263. package/packages/dd-trace/src/lambda/runtime/patch.js +7 -6
  264. package/packages/dd-trace/src/lambda/runtime/ritm.js +4 -3
  265. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  266. package/packages/dd-trace/src/llmobs/index.js +21 -5
  267. package/packages/dd-trace/src/llmobs/noop.js +18 -20
  268. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
  269. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
  270. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
  271. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
  272. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
  273. package/packages/dd-trace/src/llmobs/plugins/openai.js +2 -3
  274. package/packages/dd-trace/src/llmobs/sdk.js +4 -3
  275. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  276. package/packages/dd-trace/src/llmobs/tagger.js +129 -102
  277. package/packages/dd-trace/src/llmobs/util.js +9 -9
  278. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  279. package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
  280. package/packages/dd-trace/src/log/index.js +9 -8
  281. package/packages/dd-trace/src/log/log.js +1 -1
  282. package/packages/dd-trace/src/log/writer.js +3 -4
  283. package/packages/dd-trace/src/msgpack/chunk.js +3 -3
  284. package/packages/dd-trace/src/msgpack/encoder.js +31 -31
  285. package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
  286. package/packages/dd-trace/src/noop/span.js +4 -6
  287. package/packages/dd-trace/src/noop/tracer.js +1 -2
  288. package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
  289. package/packages/dd-trace/src/opentelemetry/tracer.js +7 -6
  290. package/packages/dd-trace/src/opentracing/propagation/log.js +10 -13
  291. package/packages/dd-trace/src/opentracing/propagation/text_map.js +40 -37
  292. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
  293. package/packages/dd-trace/src/opentracing/span.js +16 -20
  294. package/packages/dd-trace/src/opentracing/tracer.js +9 -6
  295. package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
  296. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  297. package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
  298. package/packages/dd-trace/src/pkg.js +1 -1
  299. package/packages/dd-trace/src/plugin_manager.js +4 -3
  300. package/packages/dd-trace/src/plugins/ci_plugin.js +87 -11
  301. package/packages/dd-trace/src/plugins/consumer.js +2 -2
  302. package/packages/dd-trace/src/plugins/inbound.js +5 -1
  303. package/packages/dd-trace/src/plugins/index.js +0 -1
  304. package/packages/dd-trace/src/plugins/outbound.js +4 -5
  305. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  306. package/packages/dd-trace/src/plugins/producer.js +2 -2
  307. package/packages/dd-trace/src/plugins/storage.js +2 -2
  308. package/packages/dd-trace/src/plugins/util/ci.js +28 -20
  309. package/packages/dd-trace/src/plugins/util/git.js +166 -12
  310. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
  311. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  312. package/packages/dd-trace/src/plugins/util/llm.js +27 -10
  313. package/packages/dd-trace/src/plugins/util/stacktrace.js +9 -2
  314. package/packages/dd-trace/src/plugins/util/test.js +315 -51
  315. package/packages/dd-trace/src/plugins/util/url.js +1 -1
  316. package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
  317. package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -4
  318. package/packages/dd-trace/src/plugins/util/web.js +8 -8
  319. package/packages/dd-trace/src/priority_sampler.js +64 -53
  320. package/packages/dd-trace/src/profiling/config.js +51 -35
  321. package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
  322. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  323. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +7 -6
  324. package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
  325. package/packages/dd-trace/src/profiling/index.js +2 -1
  326. package/packages/dd-trace/src/profiling/profiler.js +44 -6
  327. package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
  328. package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
  329. package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
  330. package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
  331. package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
  332. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
  333. package/packages/dd-trace/src/profiling/tagger.js +21 -13
  334. package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
  335. package/packages/dd-trace/src/proxy.js +9 -10
  336. package/packages/dd-trace/src/random_sampler.js +40 -0
  337. package/packages/dd-trace/src/rate_limiter.js +4 -4
  338. package/packages/dd-trace/src/remote_config/index.js +3 -7
  339. package/packages/dd-trace/src/remote_config/manager.js +25 -13
  340. package/packages/dd-trace/src/require-package-json.js +1 -1
  341. package/packages/dd-trace/src/ritm.js +8 -8
  342. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -4
  343. package/packages/dd-trace/src/sampler.js +41 -4
  344. package/packages/dd-trace/src/sampling_rule.js +12 -3
  345. package/packages/dd-trace/src/scope.js +1 -1
  346. package/packages/dd-trace/src/serverless.js +11 -4
  347. package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
  348. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
  349. package/packages/dd-trace/src/span_processor.js +5 -4
  350. package/packages/dd-trace/src/span_sampler.js +4 -1
  351. package/packages/dd-trace/src/standalone/tracesource.js +2 -3
  352. package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
  353. package/packages/dd-trace/src/startup-log.js +6 -18
  354. package/packages/dd-trace/src/supported-configurations.json +439 -0
  355. package/packages/dd-trace/src/telemetry/dependencies.js +64 -59
  356. package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
  357. package/packages/dd-trace/src/telemetry/metrics.js +10 -5
  358. package/packages/dd-trace/src/telemetry/send-data.js +8 -7
  359. package/packages/dd-trace/src/telemetry/telemetry.js +31 -45
  360. package/packages/dd-trace/src/tracer.js +3 -7
  361. package/packages/dd-trace/src/util.js +1 -6
  362. package/version.js +1 -0
  363. package/packages/datadog-instrumentations/src/paperplane.js +0 -77
  364. package/packages/datadog-plugin-paperplane/src/index.js +0 -25
  365. package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
  366. package/packages/datadog-plugin-paperplane/src/server.js +0 -24
  367. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -122
  368. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
@@ -18,9 +18,23 @@ const zlib = require('zlib')
18
18
  const { keepTrace } = require('../priority_sampler')
19
19
  const { ASM } = require('../standalone/product')
20
20
 
21
+ const REQUEST_HEADER_TAG_PREFIX = 'http.request.headers.'
22
+ const RESPONSE_HEADER_TAG_PREFIX = 'http.response.headers.'
23
+
24
+ const COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH = 4096
25
+ const COLLECTED_REQUEST_BODY_MAX_DEPTH = 20
26
+ const COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE = 256
27
+
21
28
  // default limiter, configurable with setRateLimit()
22
29
  let limiter = new Limiter(100)
23
30
 
31
+ const config = {
32
+ headersExtendedCollectionEnabled: false,
33
+ maxHeadersCollected: 0,
34
+ headersRedaction: false,
35
+ raspBodyCollection: false
36
+ }
37
+
24
38
  const metricsQueue = new Map()
25
39
 
26
40
  // following header lists are ordered in the same way the spec orders them, it doesn't matter but it's easier to compare
@@ -31,17 +45,6 @@ const contentHeaderList = [
31
45
  'content-language'
32
46
  ]
33
47
 
34
- const EVENT_HEADERS_MAP = mapHeaderAndTags([
35
- ...ipHeaderList,
36
- 'x-forwarded',
37
- 'forwarded',
38
- 'via',
39
- ...contentHeaderList,
40
- 'host',
41
- 'accept-encoding',
42
- 'accept-language'
43
- ], 'http.request.headers.')
44
-
45
48
  const identificationHeaders = [
46
49
  'x-amzn-trace-id',
47
50
  'cloudfront-viewer-ja3-fingerprint',
@@ -53,18 +56,56 @@ const identificationHeaders = [
53
56
  'akamai-user-risk'
54
57
  ]
55
58
 
56
- // these request headers are always collected - it breaks the expected spec orders
57
- const REQUEST_HEADERS_MAP = mapHeaderAndTags([
59
+ const eventHeadersList = [
60
+ ...ipHeaderList,
61
+ 'x-forwarded',
62
+ 'forwarded',
63
+ 'via',
64
+ ...contentHeaderList,
65
+ 'host',
66
+ 'accept-encoding',
67
+ 'accept-language'
68
+ ]
69
+
70
+ const requestHeadersList = [
58
71
  'content-type',
59
72
  'user-agent',
60
73
  'accept',
61
74
  ...identificationHeaders
62
- ], 'http.request.headers.')
75
+ ]
76
+
77
+ // these request headers are always collected - it breaks the expected spec orders
78
+ const REQUEST_HEADERS_MAP = mapHeaderAndTags(requestHeadersList, REQUEST_HEADER_TAG_PREFIX)
79
+
80
+ const EVENT_HEADERS_MAP = mapHeaderAndTags(eventHeadersList, REQUEST_HEADER_TAG_PREFIX)
63
81
 
64
- const RESPONSE_HEADERS_MAP = mapHeaderAndTags(contentHeaderList, 'http.response.headers.')
82
+ const RESPONSE_HEADERS_MAP = mapHeaderAndTags(contentHeaderList, RESPONSE_HEADER_TAG_PREFIX)
83
+
84
+ const NON_EXTENDED_REQUEST_HEADERS = new Set([...requestHeadersList, ...eventHeadersList])
85
+ const NON_EXTENDED_RESPONSE_HEADERS = new Set(contentHeaderList)
86
+
87
+ function init (_config) {
88
+ limiter = new Limiter(_config.rateLimit)
89
+ config.headersExtendedCollectionEnabled = _config.extendedHeadersCollection.enabled
90
+ config.maxHeadersCollected = _config.extendedHeadersCollection.maxHeaders
91
+ config.headersRedaction = _config.extendedHeadersCollection.redaction
92
+ config.raspBodyCollection = _config.rasp.bodyCollection
93
+ }
94
+
95
+ function formatHeaderName (name) {
96
+ return name
97
+ .trim()
98
+ .slice(0, 200)
99
+ .replaceAll(/[^a-zA-Z0-9_\-:/]/g, '_')
100
+ .toLowerCase()
101
+ }
102
+
103
+ function getHeaderTag (tagPrefix, headerName) {
104
+ return `${tagPrefix}${formatHeaderName(headerName)}`
105
+ }
65
106
 
66
107
  function mapHeaderAndTags (headerList, tagPrefix) {
67
- return new Map(headerList.map(headerName => [headerName, `${tagPrefix}${formatHeaderName(headerName)}`]))
108
+ return new Map(headerList.map(headerName => [headerName, getHeaderTag(tagPrefix, headerName)]))
68
109
  }
69
110
 
70
111
  function filterHeaders (headers, map) {
@@ -75,19 +116,99 @@ function filterHeaders (headers, map) {
75
116
  for (const [headerName, tagName] of map) {
76
117
  const headerValue = headers[headerName]
77
118
  if (headerValue) {
78
- result[tagName] = '' + headerValue
119
+ result[tagName] = String(headerValue)
79
120
  }
80
121
  }
81
122
 
82
123
  return result
83
124
  }
84
125
 
85
- function formatHeaderName (name) {
86
- return name
87
- .trim()
88
- .slice(0, 200)
89
- .replace(/[^a-zA-Z0-9_\-:/]/g, '_')
90
- .toLowerCase()
126
+ function filterExtendedHeaders (headers, excludedHeaderNames, tagPrefix, limit = 0) {
127
+ const result = {}
128
+
129
+ if (!headers) return result
130
+
131
+ let counter = 0
132
+ for (const [headerName, headerValue] of Object.entries(headers)) {
133
+ if (counter >= limit) break
134
+ if (!excludedHeaderNames.has(headerName)) {
135
+ result[getHeaderTag(tagPrefix, headerName)] = String(headerValue)
136
+ counter++
137
+ }
138
+ }
139
+
140
+ return result
141
+ }
142
+
143
+ function getCollectedHeaders (req, res, shouldCollectEventHeaders) {
144
+ // Mandatory
145
+ const mandatoryCollectedHeaders = filterHeaders(req.headers, REQUEST_HEADERS_MAP)
146
+
147
+ // Basic collection
148
+ if (!shouldCollectEventHeaders) return mandatoryCollectedHeaders
149
+
150
+ const responseHeaders = res.getHeaders()
151
+
152
+ const requestEventCollectedHeaders = filterHeaders(req.headers, EVENT_HEADERS_MAP)
153
+ const responseEventCollectedHeaders = filterHeaders(responseHeaders, RESPONSE_HEADERS_MAP)
154
+
155
+ if (!config.headersExtendedCollectionEnabled || config.headersRedaction) {
156
+ // Standard collection
157
+ return Object.assign(
158
+ mandatoryCollectedHeaders,
159
+ requestEventCollectedHeaders,
160
+ responseEventCollectedHeaders
161
+ )
162
+ }
163
+
164
+ // Extended collection
165
+ const requestExtendedHeadersAvailableCount =
166
+ config.maxHeadersCollected -
167
+ Object.keys(mandatoryCollectedHeaders).length -
168
+ Object.keys(requestEventCollectedHeaders).length
169
+
170
+ const requestEventExtendedCollectedHeaders =
171
+ filterExtendedHeaders(
172
+ req.headers,
173
+ NON_EXTENDED_REQUEST_HEADERS,
174
+ REQUEST_HEADER_TAG_PREFIX,
175
+ requestExtendedHeadersAvailableCount
176
+ )
177
+
178
+ const responseExtendedHeadersAvailableCount =
179
+ config.maxHeadersCollected -
180
+ Object.keys(responseEventCollectedHeaders).length
181
+
182
+ const responseEventExtendedCollectedHeaders =
183
+ filterExtendedHeaders(
184
+ responseHeaders,
185
+ NON_EXTENDED_RESPONSE_HEADERS,
186
+ RESPONSE_HEADER_TAG_PREFIX,
187
+ responseExtendedHeadersAvailableCount
188
+ )
189
+
190
+ const headersTags = Object.assign(
191
+ mandatoryCollectedHeaders,
192
+ requestEventCollectedHeaders,
193
+ requestEventExtendedCollectedHeaders,
194
+ responseEventCollectedHeaders,
195
+ responseEventExtendedCollectedHeaders
196
+ )
197
+
198
+ // Check discarded headers
199
+ const requestHeadersCount = Object.keys(req.headers).length
200
+ if (requestHeadersCount > config.maxHeadersCollected) {
201
+ headersTags['_dd.appsec.request.header_collection.discarded'] =
202
+ requestHeadersCount - config.maxHeadersCollected
203
+ }
204
+
205
+ const responseHeadersCount = Object.keys(responseHeaders).length
206
+ if (responseHeadersCount > config.maxHeadersCollected) {
207
+ headersTags['_dd.appsec.response.header_collection.discarded'] =
208
+ responseHeadersCount - config.maxHeadersCollected
209
+ }
210
+
211
+ return headersTags
91
212
  }
92
213
 
93
214
  function reportWafInit (wafVersion, rulesVersion, diagnosticsRules = {}, success = false) {
@@ -163,17 +284,95 @@ function reportAttack (attackData) {
163
284
  const currentJson = currentTags['_dd.appsec.json']
164
285
 
165
286
  // merge JSON arrays without parsing them
166
- if (currentJson) {
167
- newTags['_dd.appsec.json'] = currentJson.slice(0, -2) + ',' + attackData.slice(1) + '}'
168
- } else {
169
- newTags['_dd.appsec.json'] = '{"triggers":' + attackData + '}'
170
- }
287
+ const attackDataStr = JSON.stringify(attackData)
288
+ newTags['_dd.appsec.json'] = currentJson
289
+ ? currentJson.slice(0, -2) + ',' + attackDataStr.slice(1) + '}'
290
+ : '{"triggers":' + attackDataStr + '}'
171
291
 
172
292
  if (req.socket) {
173
293
  newTags['network.client.ip'] = req.socket.remoteAddress
174
294
  }
175
295
 
176
296
  rootSpan.addTags(newTags)
297
+
298
+ if (config.raspBodyCollection && isRaspAttack(attackData)) {
299
+ reportRequestBody(rootSpan, req.body)
300
+ }
301
+ }
302
+
303
+ function truncateRequestBody (target, depth = 0) {
304
+ switch (typeof target) {
305
+ case 'string':
306
+ if (target.length > COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH) {
307
+ return { value: target.slice(0, COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH), truncated: true }
308
+ }
309
+ return { value: target, truncated: false }
310
+ case 'object': {
311
+ if (target === null) {
312
+ return { value: target, truncated: false }
313
+ }
314
+
315
+ if (depth >= COLLECTED_REQUEST_BODY_MAX_DEPTH) {
316
+ return { truncated: true }
317
+ }
318
+
319
+ if (typeof target.toJSON === 'function') {
320
+ try {
321
+ return truncateRequestBody(target.toJSON(), depth + 1)
322
+ } catch {
323
+ return { truncated: false }
324
+ }
325
+ }
326
+
327
+ if (Array.isArray(target)) {
328
+ const maxArrayLength = Math.min(target.length, COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE)
329
+ let wasTruncated = target.length > COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE
330
+ const truncatedArray = new Array(maxArrayLength)
331
+ for (let i = 0; i < maxArrayLength; i++) {
332
+ const { value, truncated } = truncateRequestBody(target[i], depth + 1)
333
+ if (truncated) wasTruncated = true
334
+ truncatedArray[i] = value
335
+ }
336
+
337
+ return { value: truncatedArray, truncated: wasTruncated }
338
+ }
339
+
340
+ const keys = Object.keys(target)
341
+ const maxKeysLength = Math.min(keys.length, COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE)
342
+ let wasTruncated = keys.length > COLLECTED_REQUEST_BODY_MAX_ELEMENTS_PER_NODE
343
+
344
+ const truncatedObject = {}
345
+ for (let i = 0; i < maxKeysLength; i++) {
346
+ const key = keys[i]
347
+ const { value, truncated } = truncateRequestBody(target[key], depth + 1)
348
+ if (truncated) wasTruncated = true
349
+ truncatedObject[key] = value
350
+ }
351
+ return { value: truncatedObject, truncated: wasTruncated }
352
+ }
353
+ default:
354
+ return { value: target, truncated: false }
355
+ }
356
+ }
357
+
358
+ function reportRequestBody (rootSpan, requestBody) {
359
+ if (!requestBody) return
360
+
361
+ if (!rootSpan.meta_struct) {
362
+ rootSpan.meta_struct = {}
363
+ }
364
+
365
+ if (!rootSpan.meta_struct['http.request.body']) {
366
+ const { truncated, value } = truncateRequestBody(requestBody)
367
+ rootSpan.meta_struct['http.request.body'] = value
368
+ if (truncated) {
369
+ rootSpan.setTag('_dd.appsec.rasp.request_body_size.exceeded', 'true')
370
+ }
371
+ }
372
+ }
373
+
374
+ function isRaspAttack (events) {
375
+ return events.some(e => e.rule?.tags?.module === 'rasp')
177
376
  }
178
377
 
179
378
  function isFingerprintDerivative (derivative) {
@@ -252,15 +451,9 @@ function finishRequest (req, res) {
252
451
 
253
452
  incrementWafRequestsMetric(req)
254
453
 
255
- // collect some headers even when no attack is detected
256
- const mandatoryTags = filterHeaders(req.headers, REQUEST_HEADERS_MAP)
257
- rootSpan.addTags(mandatoryTags)
258
-
259
454
  const tags = rootSpan.context()._tags
260
- if (!shouldCollectEventHeaders(tags)) return
261
455
 
262
- const newTags = filterHeaders(res.getHeaders(), RESPONSE_HEADERS_MAP)
263
- Object.assign(newTags, filterHeaders(req.headers, EVENT_HEADERS_MAP))
456
+ const newTags = getCollectedHeaders(req, res, shouldCollectEventHeaders(tags))
264
457
 
265
458
  if (tags['appsec.event'] === 'true' && typeof req.route?.path === 'string') {
266
459
  newTags['http.endpoint'] = req.route.path
@@ -283,13 +476,11 @@ function shouldCollectEventHeaders (tags = {}) {
283
476
  return false
284
477
  }
285
478
 
286
- function setRateLimit (rateLimit) {
287
- limiter = new Limiter(rateLimit)
288
- }
289
-
290
479
  module.exports = {
291
480
  metricsQueue,
481
+ init,
292
482
  filterHeaders,
483
+ filterExtendedHeaders,
293
484
  formatHeaderName,
294
485
  reportWafInit,
295
486
  reportMetrics,
@@ -298,6 +489,6 @@ module.exports = {
298
489
  reportRaspRuleSkipped: updateRaspRuleSkippedMetricTags,
299
490
  reportDerivatives,
300
491
  finishRequest,
301
- setRateLimit,
302
- mapHeaderAndTags
492
+ mapHeaderAndTags,
493
+ truncateRequestBody
303
494
  }
@@ -185,7 +185,7 @@ class SpyMap extends Map {
185
185
  }
186
186
 
187
187
  function concatArrays (files) {
188
- return Array.from(files.values()).flat()
188
+ return [...files.values()].flat()
189
189
  }
190
190
 
191
191
  /*
@@ -209,7 +209,7 @@ function mergeRulesData (files) {
209
209
  }
210
210
  }
211
211
  }
212
- return Array.from(mergedRulesData.values())
212
+ return [...mergedRulesData.values()]
213
213
  }
214
214
 
215
215
  function rulesReducer (existingEntries, rulesDataEntry) {
@@ -7,7 +7,7 @@ const addresses = require('../addresses')
7
7
 
8
8
  function setUserTags (user, rootSpan) {
9
9
  for (const k of Object.keys(user)) {
10
- rootSpan.setTag(`usr.${k}`, '' + user[k])
10
+ rootSpan.setTag(`usr.${k}`, String(user[k]))
11
11
  }
12
12
 
13
13
  rootSpan.setTag('_dd.appsec.user.collection_mode', 'sdk')
@@ -28,7 +28,7 @@ function setUser (tracer, user) {
28
28
  setUserTags(user, rootSpan)
29
29
 
30
30
  const persistent = {
31
- [addresses.USER_ID]: '' + user.id
31
+ [addresses.USER_ID]: String(user.id)
32
32
  }
33
33
 
34
34
  if (user.session_id && typeof user.session_id === 'string') {
@@ -196,7 +196,7 @@ function trackEvent (eventName, fields, sdkMethodName, rootSpan) {
196
196
  }
197
197
 
198
198
  for (const metadataKey of Object.keys(flatFields)) {
199
- tags[`appsec.events.${eventName}.${metadataKey}`] = '' + flatFields[metadataKey]
199
+ tags[`appsec.events.${eventName}.${metadataKey}`] = String(flatFields[metadataKey])
200
200
  }
201
201
  }
202
202
 
@@ -211,11 +211,11 @@ function runWaf (eventName, user) {
211
211
  }
212
212
 
213
213
  if (user?.id) {
214
- persistent[addresses.USER_ID] = '' + user.id
214
+ persistent[addresses.USER_ID] = String(user.id)
215
215
  }
216
216
 
217
217
  if (user?.login) {
218
- persistent[addresses.USER_LOGIN] = '' + user.login
218
+ persistent[addresses.USER_LOGIN] = String(user.login)
219
219
  }
220
220
 
221
221
  waf.run({ persistent })
@@ -1,8 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { calculateDDBasePath } = require('../util')
4
-
5
- const ddBasePath = calculateDDBasePath(__dirname)
3
+ const { ddBasePath } = require('../util')
6
4
 
7
5
  const LIBRARY_FRAMES_BUFFER = 20
8
6
 
@@ -23,7 +21,7 @@ function getCallSiteList (maxDepth = 100) {
23
21
  Error.prepareStackTrace = function (_, callsites) {
24
22
  callsiteList = callsites
25
23
  }
26
- const e = new Error()
24
+ const e = new Error('message')
27
25
  e.stack
28
26
  } finally {
29
27
  Error.prepareStackTrace = previousPrepareStackTrace
@@ -15,17 +15,47 @@ const {
15
15
  incrementWafUpdates,
16
16
  incrementWafRequests
17
17
  } = require('./waf')
18
+ const telemetryMetrics = require('../../telemetry/metrics')
18
19
 
19
20
  const metricsStoreMap = new WeakMap()
20
21
 
22
+ const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
23
+
21
24
  let enabled = false
25
+ let interval
26
+ const SUPPORTED_ORIGINS = new Set(['env_var', 'code', 'remote_config', 'unknown'])
22
27
 
23
- function enable (telemetryConfig) {
28
+ function enable (config) {
29
+ const telemetryConfig = config.telemetry
24
30
  enabled = telemetryConfig?.enabled && telemetryConfig.metrics
31
+
32
+ if (enabled) {
33
+ let origin = 'remote_config'
34
+
35
+ if (config.appsec.enabled) {
36
+ origin = config.getOrigin('appsec.enabled')
37
+
38
+ if (!SUPPORTED_ORIGINS.has(origin)) {
39
+ origin = 'unknown'
40
+ }
41
+ }
42
+
43
+ const gauge = appsecMetrics.gauge('enabled', { origin })
44
+ gauge.track()
45
+
46
+ interval = setInterval(() => {
47
+ gauge.track()
48
+ }, telemetryConfig.heartbeatInterval)
49
+ interval.unref?.()
50
+ }
25
51
  }
26
52
 
27
53
  function disable () {
28
54
  enabled = false
55
+ if (interval) {
56
+ clearInterval(interval)
57
+ interval = undefined
58
+ }
29
59
  }
30
60
 
31
61
  function newStore () {
@@ -21,14 +21,12 @@ function addRaspRequestMetrics (store, { duration, durationExt, wafTimeout, erro
21
21
  }
22
22
 
23
23
  if (errorCode) {
24
- if (store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode) {
25
- store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode = Math.max(
24
+ store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode = store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode
25
+ ? Math.max(
26
26
  errorCode,
27
27
  store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode
28
28
  )
29
- } else {
30
- store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode = errorCode
31
- }
29
+ : errorCode
32
30
  }
33
31
  }
34
32
 
@@ -22,14 +22,12 @@ function addWafRequestMetrics (store, { duration, durationExt, wafTimeout, error
22
22
  }
23
23
 
24
24
  if (errorCode) {
25
- if (store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode) {
26
- store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode = Math.max(
25
+ store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode = store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode
26
+ ? Math.max(
27
27
  errorCode,
28
28
  store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode
29
29
  )
30
- } else {
31
- store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode = errorCode
32
- }
30
+ : errorCode
33
31
  }
34
32
  }
35
33
 
@@ -40,12 +40,10 @@ function setCollectionMode (mode, overwrite = true) {
40
40
  }
41
41
 
42
42
  function obfuscateIfNeeded (str) {
43
- if (collectionMode === 'anonymization') {
43
+ return collectionMode === 'anonymization'
44
44
  // get first 16 bytes of sha256 hash in lowercase hex
45
- return 'anon_' + crypto.createHash('sha256').update(str).digest().toString('hex', 0, 16).toLowerCase()
46
- } else {
47
- return str
48
- }
45
+ ? 'anon_' + crypto.createHash('sha256').update(str).digest().toString('hex', 0, 16).toLowerCase()
46
+ : str
49
47
  }
50
48
 
51
49
  // TODO: should we find other ways to get the user ID ?
@@ -49,8 +49,10 @@ class WAFContextWrapper {
49
49
  if (persistent !== null && typeof persistent === 'object') {
50
50
  const persistentInputs = {}
51
51
 
52
+ let hasPersistentInputs = false
52
53
  for (const key of Object.keys(persistent)) {
53
54
  if (!this.addressesToSkip.has(key) && this.knownAddresses.has(key)) {
55
+ hasPersistentInputs = true
54
56
  persistentInputs[key] = persistent[key]
55
57
  if (preventDuplicateAddresses.has(key)) {
56
58
  newAddressesToSkip.add(key)
@@ -58,7 +60,7 @@ class WAFContextWrapper {
58
60
  }
59
61
  }
60
62
 
61
- if (Object.keys(persistentInputs).length) {
63
+ if (hasPersistentInputs) {
62
64
  payload.persistent = persistentInputs
63
65
  payloadHasData = true
64
66
  }
@@ -67,13 +69,15 @@ class WAFContextWrapper {
67
69
  if (ephemeral !== null && typeof ephemeral === 'object') {
68
70
  const ephemeralInputs = {}
69
71
 
72
+ let hasEphemeral = false
70
73
  for (const key of Object.keys(ephemeral)) {
71
74
  if (this.knownAddresses.has(key)) {
75
+ hasEphemeral = true
72
76
  ephemeralInputs[key] = ephemeral[key]
73
77
  }
74
78
  }
75
79
 
76
- if (Object.keys(ephemeralInputs).length) {
80
+ if (hasEphemeral) {
77
81
  payload.ephemeral = ephemeralInputs
78
82
  payloadHasData = true
79
83
  }
@@ -102,7 +106,7 @@ class WAFContextWrapper {
102
106
 
103
107
  const end = process.hrtime.bigint()
104
108
 
105
- metrics.durationExt = parseInt(end - start) / 1e3
109
+ metrics.durationExt = Number.parseInt(end - start) / 1e3
106
110
 
107
111
  if (typeof result.errorCode === 'number' && result.errorCode < 0) {
108
112
  const error = new Error('WAF code error')
@@ -137,7 +141,7 @@ class WAFContextWrapper {
137
141
  metrics.wafTimeout = result.timeout
138
142
 
139
143
  if (ruleTriggered) {
140
- Reporter.reportAttack(JSON.stringify(result.events))
144
+ Reporter.reportAttack(result.events)
141
145
  }
142
146
 
143
147
  Reporter.reportDerivatives(result.derivatives)
@@ -1,10 +1,10 @@
1
1
  'use strict'
2
2
 
3
- // eslint-disable-next-line @stylistic/js/max-len
4
3
  // Modeled after https://github.com/DataDog/libdatadog/blob/f3994857a59bb5679a65967138c5a3aec418a65f/ddcommon/src/azure_app_services.rs
5
4
 
6
5
  const os = require('os')
7
6
  const { getIsAzureFunction } = require('./serverless')
7
+ const { getEnvironmentVariable, getEnvironmentVariables } = require('../../dd-trace/src/config-helper')
8
8
 
9
9
  function extractSubscriptionID (ownerName) {
10
10
  if (ownerName !== undefined) {
@@ -13,7 +13,6 @@ function extractSubscriptionID (ownerName) {
13
13
  return subId
14
14
  }
15
15
  }
16
- return undefined
17
16
  }
18
17
 
19
18
  function extractResourceGroup (ownerName) {
@@ -22,7 +21,7 @@ function extractResourceGroup (ownerName) {
22
21
 
23
22
  function buildResourceID (subscriptionID, siteName, resourceGroup) {
24
23
  if (subscriptionID === undefined || siteName === undefined || resourceGroup === undefined) {
25
- return undefined
24
+ return
26
25
  }
27
26
  return `/subscriptions/${subscriptionID}/resourcegroups/${resourceGroup}/providers/microsoft.web/sites/${siteName}`
28
27
  .toLowerCase()
@@ -47,7 +46,7 @@ function buildMetadata () {
47
46
  WEBSITE_OS,
48
47
  WEBSITE_RESOURCE_GROUP,
49
48
  WEBSITE_SITE_NAME
50
- } = process.env
49
+ } = getEnvironmentVariables()
51
50
 
52
51
  const subscriptionID = extractSubscriptionID(WEBSITE_OWNER_NAME)
53
52
 
@@ -79,18 +78,19 @@ function buildMetadata () {
79
78
  function getAzureAppMetadata () {
80
79
  // DD_AZURE_APP_SERVICES is an environment variable introduced by the .NET APM team and is set automatically for
81
80
  // anyone using the Datadog APM Extensions (.NET, Java, or Node) for Windows Azure App Services
82
- // eslint-disable-next-line @stylistic/js/max-len
83
81
  // See: https://github.com/DataDog/datadog-aas-extension/blob/01f94b5c28b7fa7a9ab264ca28bd4e03be603900/node/src/applicationHost.xdt#L20-L21
84
- return process.env.DD_AZURE_APP_SERVICES !== undefined ? buildMetadata() : undefined
82
+ if (getEnvironmentVariable('DD_AZURE_APP_SERVICES') !== undefined) {
83
+ return buildMetadata()
84
+ }
85
85
  }
86
86
 
87
87
  function getAzureFunctionMetadata () {
88
- return getIsAzureFunction() ? buildMetadata() : undefined
88
+ if (getIsAzureFunction()) {
89
+ return buildMetadata()
90
+ }
89
91
  }
90
92
 
91
- // eslint-disable-next-line @stylistic/js/max-len
92
93
  // Modeled after https://github.com/DataDog/libdatadog/blob/92272e90a7919f07178f3246ef8f82295513cfed/profiling/src/exporter/mod.rs#L187
93
- // eslint-disable-next-line @stylistic/js/max-len
94
94
  // and https://github.com/DataDog/libdatadog/blob/f3994857a59bb5679a65967138c5a3aec418a65f/trace-utils/src/trace_utils.rs#L533
95
95
  function getAzureTagsFromMetadata (metadata) {
96
96
  if (metadata === undefined) {
@@ -4,6 +4,7 @@ const { join } = require('path')
4
4
  const { Worker, threadId: parentThreadId } = require('worker_threads')
5
5
  const { randomUUID } = require('crypto')
6
6
  const log = require('../../log')
7
+ const { getEnvironmentVariables } = require('../../config-helper')
7
8
 
8
9
  const probeIdToResolveBreakpointSet = new Map()
9
10
  const probeIdToResolveBreakpointRemove = new Map()
@@ -72,13 +73,13 @@ class TestVisDynamicInstrumentation {
72
73
  // for PnP support, hence why we deviate from the DI pattern here.
73
74
  // To avoid infinite initialization loops, we're disabling DI and tracing in the worker.
74
75
  env: {
75
- ...process.env,
76
- DD_CIVISIBILITY_ENABLED: 0,
77
- DD_TRACE_ENABLED: 0,
78
- DD_TEST_FAILED_TEST_REPLAY_ENABLED: 0,
79
- DD_CIVISIBILITY_MANUAL_API_ENABLED: 0,
80
- DD_TRACING_ENABLED: 0,
81
- DD_TRACE_TELEMETRY_ENABLED: 0
76
+ ...getEnvironmentVariables(),
77
+ DD_CIVISIBILITY_ENABLED: 'false',
78
+ DD_TRACE_ENABLED: 'false',
79
+ DD_TEST_FAILED_TEST_REPLAY_ENABLED: 'false',
80
+ DD_CIVISIBILITY_MANUAL_API_ENABLED: 'false',
81
+ DD_TRACING_ENABLED: 'false',
82
+ DD_INSTRUMENTATION_TELEMETRY_ENABLED: 'false'
82
83
  },
83
84
  workerData: {
84
85
  config: this._config.serialize(),
@@ -144,7 +145,7 @@ class TestVisDynamicInstrumentation {
144
145
 
145
146
  let dynamicInstrumentation
146
147
 
147
- module.exports = (config) => {
148
+ module.exports = function createAndGetTestVisDynamicInstrumentation (config) {
148
149
  if (dynamicInstrumentation) {
149
150
  return dynamicInstrumentation
150
151
  }