dd-trace 5.52.0 → 5.54.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 (332) hide show
  1. package/LICENSE-3rdparty.csv +2 -1
  2. package/README.md +5 -0
  3. package/index.d.ts +87 -22
  4. package/initialize.mjs +3 -4
  5. package/package.json +36 -34
  6. package/packages/datadog-core/src/utils/src/get.js +1 -1
  7. package/packages/datadog-core/src/utils/src/has.js +1 -1
  8. package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
  9. package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
  10. package/packages/datadog-core/src/utils/src/pick.js +2 -2
  11. package/packages/datadog-core/src/utils/src/set.js +1 -1
  12. package/packages/datadog-core/src/utils/src/uniq.js +1 -1
  13. package/packages/datadog-instrumentations/src/amqp10.js +19 -17
  14. package/packages/datadog-instrumentations/src/amqplib.js +57 -37
  15. package/packages/datadog-instrumentations/src/apollo.js +2 -2
  16. package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
  17. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -4
  18. package/packages/datadog-instrumentations/src/child_process.js +3 -3
  19. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +92 -62
  20. package/packages/datadog-instrumentations/src/couchbase.js +5 -4
  21. package/packages/datadog-instrumentations/src/cucumber.js +126 -84
  22. package/packages/datadog-instrumentations/src/cypress.js +2 -1
  23. package/packages/datadog-instrumentations/src/dns.js +1 -1
  24. package/packages/datadog-instrumentations/src/express.js +2 -6
  25. package/packages/datadog-instrumentations/src/fs.js +7 -6
  26. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +28 -34
  27. package/packages/datadog-instrumentations/src/graphql.js +7 -10
  28. package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
  29. package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
  30. package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
  31. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
  32. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -1
  33. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
  34. package/packages/datadog-instrumentations/src/helpers/register.js +21 -18
  35. package/packages/datadog-instrumentations/src/http/client.js +16 -21
  36. package/packages/datadog-instrumentations/src/iovalkey.js +51 -0
  37. package/packages/datadog-instrumentations/src/jest.js +184 -87
  38. package/packages/datadog-instrumentations/src/kafkajs.js +65 -44
  39. package/packages/datadog-instrumentations/src/knex.js +4 -4
  40. package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
  41. package/packages/datadog-instrumentations/src/mariadb.js +38 -61
  42. package/packages/datadog-instrumentations/src/mocha/main.js +85 -59
  43. package/packages/datadog-instrumentations/src/mocha/utils.js +103 -82
  44. package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
  45. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  46. package/packages/datadog-instrumentations/src/mysql.js +20 -36
  47. package/packages/datadog-instrumentations/src/mysql2.js +55 -47
  48. package/packages/datadog-instrumentations/src/net.js +4 -2
  49. package/packages/datadog-instrumentations/src/next.js +7 -14
  50. package/packages/datadog-instrumentations/src/nyc.js +1 -1
  51. package/packages/datadog-instrumentations/src/openai.js +21 -23
  52. package/packages/datadog-instrumentations/src/oracledb.js +1 -1
  53. package/packages/datadog-instrumentations/src/pg.js +6 -13
  54. package/packages/datadog-instrumentations/src/playwright.js +170 -136
  55. package/packages/datadog-instrumentations/src/redis.js +3 -3
  56. package/packages/datadog-instrumentations/src/restify.js +2 -2
  57. package/packages/datadog-instrumentations/src/rhea.js +42 -54
  58. package/packages/datadog-instrumentations/src/router.js +22 -25
  59. package/packages/datadog-instrumentations/src/tedious.js +1 -1
  60. package/packages/datadog-instrumentations/src/url.js +9 -17
  61. package/packages/datadog-instrumentations/src/vitest.js +126 -97
  62. package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
  63. package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
  64. package/packages/datadog-plugin-amqplib/src/client.js +6 -2
  65. package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
  66. package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
  67. package/packages/datadog-plugin-amqplib/src/util.js +1 -1
  68. package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
  69. package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
  70. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
  71. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  72. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
  73. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +24 -31
  74. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  75. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +6 -6
  76. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  77. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
  78. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +4 -5
  79. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  80. package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
  81. package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
  82. package/packages/datadog-plugin-child_process/src/index.js +4 -4
  83. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
  84. package/packages/datadog-plugin-cucumber/src/index.js +86 -20
  85. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +97 -27
  86. package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
  87. package/packages/datadog-plugin-cypress/src/support.js +24 -5
  88. package/packages/datadog-plugin-express/src/code_origin.js +30 -0
  89. package/packages/datadog-plugin-express/src/index.js +10 -12
  90. package/packages/datadog-plugin-express/src/tracing.js +19 -0
  91. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
  92. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
  93. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
  94. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +26 -9
  95. package/packages/datadog-plugin-graphql/src/execute.js +2 -2
  96. package/packages/datadog-plugin-graphql/src/index.js +7 -6
  97. package/packages/datadog-plugin-graphql/src/resolve.js +2 -2
  98. package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
  99. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
  100. package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
  101. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  102. package/packages/datadog-plugin-grpc/src/util.js +2 -2
  103. package/packages/datadog-plugin-http/src/client.js +18 -7
  104. package/packages/datadog-plugin-http2/src/client.js +20 -20
  105. package/packages/datadog-plugin-iovalkey/src/index.js +18 -0
  106. package/packages/datadog-plugin-jest/src/index.js +36 -28
  107. package/packages/datadog-plugin-jest/src/util.js +8 -8
  108. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
  109. package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
  110. package/packages/datadog-plugin-kafkajs/src/producer.js +15 -7
  111. package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
  112. package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
  113. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
  114. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
  115. package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
  116. package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
  117. package/packages/datadog-plugin-mariadb/src/index.js +3 -9
  118. package/packages/datadog-plugin-mocha/src/index.js +88 -48
  119. package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
  120. package/packages/datadog-plugin-mysql/src/index.js +11 -9
  121. package/packages/datadog-plugin-mysql2/src/index.js +16 -0
  122. package/packages/datadog-plugin-net/src/tcp.js +1 -1
  123. package/packages/datadog-plugin-next/src/index.js +6 -5
  124. package/packages/datadog-plugin-openai/src/services.js +6 -10
  125. package/packages/datadog-plugin-openai/src/tracing.js +10 -14
  126. package/packages/datadog-plugin-oracledb/src/index.js +1 -1
  127. package/packages/datadog-plugin-playwright/src/index.js +48 -22
  128. package/packages/datadog-plugin-redis/src/index.js +9 -4
  129. package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
  130. package/packages/datadog-plugin-rhea/src/producer.js +5 -2
  131. package/packages/datadog-plugin-router/src/index.js +1 -1
  132. package/packages/datadog-plugin-selenium/src/index.js +1 -6
  133. package/packages/datadog-plugin-vitest/src/index.js +99 -72
  134. package/packages/datadog-shimmer/src/shimmer.js +163 -36
  135. package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
  136. package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
  137. package/packages/dd-trace/src/appsec/blocking.js +6 -20
  138. package/packages/dd-trace/src/appsec/graphql.js +2 -2
  139. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  140. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
  141. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
  142. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +4 -6
  143. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
  144. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +4 -6
  145. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
  146. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
  147. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
  148. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
  149. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
  150. package/packages/dd-trace/src/appsec/iast/index.js +1 -0
  151. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
  152. package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
  153. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +6 -13
  154. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
  155. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
  156. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
  157. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
  158. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -7
  159. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
  160. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  161. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -7
  162. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  163. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +6 -6
  164. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -1
  165. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
  166. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
  167. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
  168. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -24
  169. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
  170. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
  171. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
  172. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
  173. package/packages/dd-trace/src/appsec/index.js +15 -12
  174. package/packages/dd-trace/src/appsec/rasp/index.js +19 -17
  175. package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
  176. package/packages/dd-trace/src/appsec/rasp/utils.js +11 -6
  177. package/packages/dd-trace/src/appsec/reporter.js +233 -40
  178. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  179. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
  180. package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
  181. package/packages/dd-trace/src/appsec/telemetry/index.js +1 -2
  182. package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -14
  183. package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
  184. package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
  185. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +8 -8
  186. package/packages/dd-trace/src/azure_metadata.js +2 -7
  187. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +1 -1
  188. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
  189. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
  190. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
  191. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  192. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
  193. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
  194. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
  195. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
  196. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
  197. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -1
  198. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +1 -1
  199. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +8 -5
  200. package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
  201. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
  202. package/packages/dd-trace/src/config.js +82 -51
  203. package/packages/dd-trace/src/config_stable.js +3 -3
  204. package/packages/dd-trace/src/datastreams/encoding.js +9 -9
  205. package/packages/dd-trace/src/datastreams/fnv.js +1 -1
  206. package/packages/dd-trace/src/datastreams/pathway.js +4 -4
  207. package/packages/dd-trace/src/datastreams/processor.js +5 -7
  208. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  209. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
  210. package/packages/dd-trace/src/datastreams/size.js +1 -1
  211. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +131 -72
  212. package/packages/dd-trace/src/debugger/devtools_client/condition.js +6 -8
  213. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
  214. package/packages/dd-trace/src/debugger/devtools_client/index.js +17 -27
  215. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
  216. package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -7
  217. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +16 -8
  218. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +8 -10
  219. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +3 -3
  220. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
  221. package/packages/dd-trace/src/debugger/devtools_client/state.js +31 -4
  222. package/packages/dd-trace/src/dogstatsd.js +7 -4
  223. package/packages/dd-trace/src/encode/0.4.js +9 -9
  224. package/packages/dd-trace/src/encode/0.5.js +1 -1
  225. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +3 -3
  226. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
  227. package/packages/dd-trace/src/encode/tags-processors.js +1 -1
  228. package/packages/dd-trace/src/exporter.js +6 -6
  229. package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
  230. package/packages/dd-trace/src/exporters/common/docker.js +1 -1
  231. package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
  232. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  233. package/packages/dd-trace/src/exporters/common/util.js +1 -1
  234. package/packages/dd-trace/src/external-logger/src/index.js +5 -5
  235. package/packages/dd-trace/src/flare/file.js +1 -5
  236. package/packages/dd-trace/src/format.js +1 -1
  237. package/packages/dd-trace/src/git_properties.js +1 -1
  238. package/packages/dd-trace/src/id.js +12 -6
  239. package/packages/dd-trace/src/iitm.js +10 -22
  240. package/packages/dd-trace/src/lambda/handler.js +6 -6
  241. package/packages/dd-trace/src/lambda/runtime/patch.js +4 -4
  242. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  243. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
  244. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
  245. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
  246. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
  247. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
  248. package/packages/dd-trace/src/llmobs/sdk.js +2 -2
  249. package/packages/dd-trace/src/llmobs/tagger.js +113 -99
  250. package/packages/dd-trace/src/llmobs/util.js +9 -9
  251. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  252. package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
  253. package/packages/dd-trace/src/log/index.js +4 -4
  254. package/packages/dd-trace/src/log/log.js +1 -1
  255. package/packages/dd-trace/src/log/writer.js +2 -2
  256. package/packages/dd-trace/src/msgpack/chunk.js +3 -3
  257. package/packages/dd-trace/src/msgpack/encoder.js +28 -28
  258. package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
  259. package/packages/dd-trace/src/noop/span.js +3 -5
  260. package/packages/dd-trace/src/noop/tracer.js +1 -2
  261. package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
  262. package/packages/dd-trace/src/opentelemetry/tracer.js +6 -5
  263. package/packages/dd-trace/src/opentracing/propagation/log.js +6 -8
  264. package/packages/dd-trace/src/opentracing/propagation/text_map.js +27 -23
  265. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
  266. package/packages/dd-trace/src/opentracing/span.js +9 -14
  267. package/packages/dd-trace/src/opentracing/tracer.js +9 -6
  268. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  269. package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
  270. package/packages/dd-trace/src/pkg.js +1 -1
  271. package/packages/dd-trace/src/plugins/ci_plugin.js +62 -10
  272. package/packages/dd-trace/src/plugins/consumer.js +2 -2
  273. package/packages/dd-trace/src/plugins/inbound.js +5 -1
  274. package/packages/dd-trace/src/plugins/index.js +1 -1
  275. package/packages/dd-trace/src/plugins/outbound.js +4 -5
  276. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  277. package/packages/dd-trace/src/plugins/producer.js +2 -2
  278. package/packages/dd-trace/src/plugins/storage.js +2 -2
  279. package/packages/dd-trace/src/plugins/util/ci.js +23 -15
  280. package/packages/dd-trace/src/plugins/util/git.js +165 -11
  281. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
  282. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  283. package/packages/dd-trace/src/plugins/util/llm.js +27 -10
  284. package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
  285. package/packages/dd-trace/src/plugins/util/test.js +311 -48
  286. package/packages/dd-trace/src/plugins/util/url.js +1 -1
  287. package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
  288. package/packages/dd-trace/src/plugins/util/user-provided-git.js +12 -3
  289. package/packages/dd-trace/src/plugins/util/web.js +5 -4
  290. package/packages/dd-trace/src/priority_sampler.js +22 -22
  291. package/packages/dd-trace/src/profiling/config.js +44 -8
  292. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +5 -5
  293. package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
  294. package/packages/dd-trace/src/profiling/profiler.js +37 -2
  295. package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
  296. package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
  297. package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
  298. package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
  299. package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
  300. package/packages/dd-trace/src/profiling/tagger.js +3 -5
  301. package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
  302. package/packages/dd-trace/src/proxy.js +7 -13
  303. package/packages/dd-trace/src/random_sampler.js +40 -0
  304. package/packages/dd-trace/src/rate_limiter.js +4 -4
  305. package/packages/dd-trace/src/remote_config/index.js +3 -7
  306. package/packages/dd-trace/src/remote_config/manager.js +25 -13
  307. package/packages/dd-trace/src/require-package-json.js +1 -1
  308. package/packages/dd-trace/src/ritm.js +4 -4
  309. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
  310. package/packages/dd-trace/src/sampler.js +33 -4
  311. package/packages/dd-trace/src/sampling_rule.js +12 -3
  312. package/packages/dd-trace/src/scope.js +1 -1
  313. package/packages/dd-trace/src/serverless.js +0 -48
  314. package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
  315. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +8 -0
  316. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
  317. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  318. package/packages/dd-trace/src/span_processor.js +3 -3
  319. package/packages/dd-trace/src/span_sampler.js +4 -1
  320. package/packages/dd-trace/src/standalone/tracesource.js +1 -1
  321. package/packages/dd-trace/src/startup-log.js +2 -2
  322. package/packages/dd-trace/src/telemetry/dependencies.js +4 -4
  323. package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
  324. package/packages/dd-trace/src/telemetry/metrics.js +10 -5
  325. package/packages/dd-trace/src/telemetry/send-data.js +1 -1
  326. package/packages/dd-trace/src/telemetry/telemetry.js +23 -24
  327. package/packages/dd-trace/src/util.js +1 -1
  328. package/version.js +1 -0
  329. package/packages/datadog-instrumentations/src/paperplane.js +0 -77
  330. package/packages/datadog-plugin-paperplane/src/index.js +0 -25
  331. package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
  332. package/packages/datadog-plugin-paperplane/src/server.js +0 -24
@@ -1,12 +1,24 @@
1
1
  'use strict'
2
2
 
3
+ /**
4
+ * @type {Set<string | symbol>}
5
+ */
3
6
  const skipMethods = new Set([
4
7
  'caller',
5
8
  'arguments',
6
9
  'name',
7
10
  'length'
8
11
  ])
12
+ const skipMethodSize = skipMethods.size
9
13
 
14
+ const nonConfigurableModuleExports = new WeakMap()
15
+
16
+ /**
17
+ * Copies properties from the original function to the wrapped function.
18
+ *
19
+ * @param {Function} original - The original function.
20
+ * @param {Function} wrapped - The wrapped function.
21
+ */
10
22
  function copyProperties (original, wrapped) {
11
23
  if (original.constructor !== wrapped.constructor) {
12
24
  const proto = Object.getPrototypeOf(original)
@@ -23,7 +35,7 @@ function copyProperties (original, wrapped) {
23
35
  if (ownKeys.length !== 2) {
24
36
  for (const key of ownKeys) {
25
37
  if (skipMethods.has(key)) continue
26
- const descriptor = Object.getOwnPropertyDescriptor(original, key)
38
+ const descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(original, key))
27
39
  if (descriptor.writable && descriptor.enumerable && descriptor.configurable) {
28
40
  wrapped[key] = original[key]
29
41
  } else if (descriptor.writable || descriptor.configurable || !Object.hasOwn(wrapped, key)) {
@@ -33,6 +45,33 @@ function copyProperties (original, wrapped) {
33
45
  }
34
46
  }
35
47
 
48
+ /**
49
+ * Copies properties from the original object to the wrapped object, skipping a specific key.
50
+ *
51
+ * @param {Record<string | symbol, unknown>} original - The original object.
52
+ * @param {Record<string | symbol, unknown>} wrapped - The wrapped object.
53
+ * @param {string | symbol} skipKey - The key to skip during copying.
54
+ */
55
+ function copyObjectProperties (original, wrapped, skipKey) {
56
+ const ownKeys = Reflect.ownKeys(original)
57
+ for (const key of ownKeys) {
58
+ if (key === skipKey) continue
59
+ const descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(original, key))
60
+ if (descriptor.writable && descriptor.enumerable && descriptor.configurable) {
61
+ wrapped[key] = original[key]
62
+ } else if (descriptor.writable || descriptor.configurable || !Object.hasOwn(wrapped, key)) {
63
+ Object.defineProperty(wrapped, key, descriptor)
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Wraps a function with a wrapper function.
70
+ *
71
+ * @param {Function} original - The original function to wrap.
72
+ * @param {(original: Function) => Function} wrapper - The wrapper function.
73
+ * @returns {Function} The wrapped function.
74
+ */
36
75
  function wrapFunction (original, wrapper) {
37
76
  const wrapped = wrapper(original)
38
77
 
@@ -44,28 +83,55 @@ function wrapFunction (original, wrapper) {
44
83
  return wrapped
45
84
  }
46
85
 
47
- function wrap (target, name, wrapper) {
48
- assertMethod(target, name)
86
+ /**
87
+ * Wraps a method of an object with a wrapper function.
88
+ *
89
+ * @param {Record<string | symbol, unknown> | Function} target - The target
90
+ * object.
91
+ * @param {string | symbol} name - The property key of the method to wrap.
92
+ * @param {(original: Function) => (...args) => any} wrapper - The wrapper function.
93
+ * @param {{ replaceGetter?: boolean }} [options] - If `replaceGetter` is set to
94
+ * true, the getter is accessed and the getter is replaced with one that just
95
+ * returns the earlier retrieved value. Use with care! This may only be done in
96
+ * case the getter absolutely has no side effect and no setter is defined for the
97
+ * property.
98
+ * @returns {Record<string | symbol, unknown> | Function} The target object with
99
+ * the wrapped method.
100
+ */
101
+ function wrap (target, name, wrapper, options) {
49
102
  if (typeof wrapper !== 'function') {
50
- throw new Error(wrapper ? 'Target is not a function' : 'No function provided')
103
+ throw new TypeError(wrapper ? 'Target is not a function' : 'No function provided')
51
104
  }
52
105
 
53
- const original = target[name]
54
- const wrapped = wrapper(original)
106
+ // No descriptor means original was on the prototype. This is not totally
107
+ // safe, since we define the property on the target. That could have an impact
108
+ // in case e.g., the own keys are checks.
109
+ const descriptor = Object.getOwnPropertyDescriptor(target, name) ?? {
110
+ value: target[name],
111
+ writable: true,
112
+ configurable: true,
113
+ enumerable: false
114
+ }
55
115
 
56
- if (typeof original === 'function') copyProperties(original, wrapped)
116
+ if (descriptor.set && (!descriptor.get || options?.replaceGetter)) {
117
+ // It is possible to support these cases by instrumenting both the getter
118
+ // and setter (or only the setter, in case that is a use case).
119
+ // For now, this is not supported due to the complexity and the fact that
120
+ // this is not a common use case.
121
+ throw new Error(options?.replaceGetter
122
+ ? 'Replacing a getter/setter pair is not supported. Implement if required.'
123
+ : 'Replacing setters is not supported. Implement if required.')
124
+ }
57
125
 
58
- let descriptor = Object.getOwnPropertyDescriptor(target, name)
126
+ const original = descriptor.value ?? options?.replaceGetter ? target[name] : descriptor.get
59
127
 
60
- // No descriptor means original was on the prototype
61
- if (descriptor === undefined) {
62
- descriptor = {
63
- value: wrapped,
64
- writable: true,
65
- configurable: true,
66
- enumerable: false
67
- }
68
- } else if (descriptor.writable) {
128
+ assertMethod(target, name, original)
129
+
130
+ const wrapped = wrapper(original)
131
+
132
+ copyProperties(original, wrapped)
133
+
134
+ if (descriptor.writable) {
69
135
  // Fast path for assigned properties.
70
136
  if (descriptor.configurable && descriptor.enumerable) {
71
137
  target[name] = wrapped
@@ -73,25 +139,54 @@ function wrap (target, name, wrapper) {
73
139
  }
74
140
  descriptor.value = wrapped
75
141
  } else {
76
- if (descriptor.get || descriptor.set) {
77
- // TODO(BridgeAR): What happens in case there is a setter? This seems wrong?
78
- // What happens in case the user does indeed set this to a different value?
79
- // In that case the getter would potentially return the wrong value?
80
- descriptor.get = () => wrapped
142
+ if (descriptor.get) {
143
+ // `replaceGetter` may only be used when the getter has no side effect.
144
+ descriptor.get = options?.replaceGetter ? () => wrapped : wrapped
81
145
  } else {
82
146
  descriptor.value = wrapped
83
147
  }
84
148
 
85
149
  if (descriptor.configurable === false) {
86
- // TODO(BridgeAR): Bail out instead (throw). It is unclear if the newly
87
- // created object is actually used. If it's not used, the wrapping would
88
- // have had no effect without noticing. It is also unclear what would happen
89
- // in case user code would check for properties to be own properties. That
90
- // would fail with this code. A function being replaced with an object is
91
- // also not possible.
92
- return Object.create(target, {
93
- [name]: descriptor
94
- })
150
+ // TODO(BridgeAR): This currently only works on the most outer part. The
151
+ // moduleExports object.
152
+ //
153
+ // It would be possible to also implement it for non moduleExports objects
154
+ // by passing through the moduleExports object and the property names that
155
+ // are accessed. That way it would be possible to redefine the complete
156
+ // property chain. Example:
157
+ //
158
+ // shimmer.wrap(hapi.Server.prototype, 'start', wrapStart)
159
+ // shimmer.wrap(hapi.Server.prototype, 'ext', wrapExt)
160
+ //
161
+ // shimmer.wrap(hapi, 'Server', 'prototype', 'start', wrapStart)
162
+ // shimmer.wrap(hapi, 'Server', 'prototype', 'ext', wrapExt)
163
+ //
164
+ // That would however still not resolve the issue about the user replacing
165
+ // the return value so that the hook picks up the new hapi moduleExports
166
+ // object. To safely fix that, we would have to couple the register helper
167
+ // with this code. That way it would be possible to directly pass through
168
+ // the entries.
169
+
170
+ // In case more than a single property is not configurable and writable,
171
+ // Just reuse the already created object.
172
+ let moduleExports = nonConfigurableModuleExports.get(target)
173
+ if (!moduleExports) {
174
+ if (typeof target === 'function') {
175
+ const original = target
176
+ moduleExports = function (...args) { return original.apply(original, args) }
177
+ // This is a rare case. Accept the slight performance hit.
178
+ skipMethods.add(name)
179
+ copyProperties(target, moduleExports)
180
+ if (skipMethods.size === skipMethodSize + 1) {
181
+ skipMethods.delete(name)
182
+ }
183
+ } else {
184
+ moduleExports = Object.create(target)
185
+ copyObjectProperties(target, moduleExports, name)
186
+ }
187
+ nonConfigurableModuleExports.set(target, moduleExports)
188
+ }
189
+ target = moduleExports
95
190
  }
96
191
  }
97
192
 
@@ -100,6 +195,16 @@ function wrap (target, name, wrapper) {
100
195
  return target
101
196
  }
102
197
 
198
+ /**
199
+ * Wraps multiple methods and or multiple objects with a wrapper function.
200
+ * May also receive a single method or object or a single method name.
201
+ *
202
+ * @param {Array<Record<string | symbol, unknown> | Function> |
203
+ * Record<string | symbol, unknown> |
204
+ * Function} targets - The target objects.
205
+ * @param {Array<string | symbol> | string | symbol} names - The property keys of the methods to wrap.
206
+ * @param {(original: Function) => (...args) => any} wrapper - The wrapper function.
207
+ */
103
208
  function massWrap (targets, names, wrapper) {
104
209
  targets = toArray(targets)
105
210
  names = toArray(names)
@@ -111,29 +216,51 @@ function massWrap (targets, names, wrapper) {
111
216
  }
112
217
  }
113
218
 
219
+ /**
220
+ * Converts a value to an array if it is not already an array.
221
+ *
222
+ * @template T
223
+ * @param {T | T[]} maybeArray - The value to convert.
224
+ * @returns {T[]} The value as an array.
225
+ */
114
226
  function toArray (maybeArray) {
115
227
  return Array.isArray(maybeArray) ? maybeArray : [maybeArray]
116
228
  }
117
229
 
118
- function assertMethod (target, name) {
119
- if (typeof target?.[name] !== 'function') {
230
+ /**
231
+ * Asserts that a method is a function.
232
+ *
233
+ * @param {Record<string | symbol, unknown> | Function} target - The target object.
234
+ * @param {string | symbol} name - The property key of the method.
235
+ * @param {unknown} method - The method to assert.
236
+ * @throws {Error} If the method is not a function.
237
+ */
238
+ function assertMethod (target, name, method) {
239
+ if (typeof method !== 'function') {
120
240
  let message = 'No target object provided'
121
241
 
122
242
  if (target) {
123
243
  if (typeof target !== 'object' && typeof target !== 'function') {
124
244
  message = 'Invalid target'
125
245
  } else {
126
- message = target[name] ? `Original method ${name} is not a function` : `No original method ${name}`
246
+ name = String(name)
247
+ message = method ? `Original method ${name} is not a function` : `No original method ${name}`
127
248
  }
128
249
  }
129
250
 
130
- throw new Error(message)
251
+ throw new TypeError(message)
131
252
  }
132
253
  }
133
254
 
255
+ /**
256
+ * Asserts that a target is not a class constructor.
257
+ *
258
+ * @param {Function} target - The target function.
259
+ * @throws {Error} If the target is a class constructor.
260
+ */
134
261
  function assertNotClass (target) {
135
262
  if (Function.prototype.toString.call(target).startsWith('class')) {
136
- throw new Error('Target is a native class constructor and cannot be wrapped.')
263
+ throw new TypeError('Target is a native class constructor and cannot be wrapped.')
137
264
  }
138
265
  }
139
266
 
@@ -18,8 +18,8 @@ let asmStandaloneEnabled
18
18
  let sampledRequests
19
19
 
20
20
  class NoopTTLCache {
21
- clear () { }
22
- set (_key, _value) { return undefined }
21
+ clear () {}
22
+ set (_key, _value) {}
23
23
  has (_key) { return false }
24
24
  }
25
25
 
@@ -1,4 +1,4 @@
1
- /* eslint-disable @stylistic/js/max-len */
1
+ /* eslint-disable @stylistic/max-len */
2
2
  'use strict'
3
3
 
4
4
  const html = '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>You\'ve been blocked</title><style>a,body,div,html,span{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}body{background:-webkit-radial-gradient(26% 19%,circle,#fff,#f4f7f9);background:radial-gradient(circle at 26% 19%,#fff,#f4f7f9);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:center;align-content:center;width:100%;min-height:100vh;line-height:1;flex-direction:column}p{display:block}main{text-align:center;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:center;align-content:center;flex-direction:column}p{font-size:18px;line-height:normal;color:#646464;font-family:sans-serif;font-weight:400}a{color:#4842b7}footer{width:100%;text-align:center}footer p{font-size:16px}</style></head><body><main><p>Sorry, you cannot access this page. Please contact the customer service team.</p></main><footer><p>Security provided by <a href="https://www.datadoghq.com/product/security-platform/application-security-monitoring/" target="_blank">Datadog</a></p></footer></body></html>'
@@ -93,11 +93,9 @@ function getBlockWithContentData (req, specificType, actionParameters) {
93
93
  }
94
94
 
95
95
  function getBlockingData (req, specificType, actionParameters) {
96
- if (actionParameters?.location) {
97
- return getBlockWithRedirectData(actionParameters)
98
- } else {
99
- return getBlockWithContentData(req, specificType, actionParameters)
100
- }
96
+ return actionParameters?.location
97
+ ? getBlockWithRedirectData(actionParameters)
98
+ : getBlockWithContentData(req, specificType, actionParameters)
101
99
  }
102
100
 
103
101
  function block (req, res, rootSpan, abortController, actionParameters = defaultBlockingActionParameters) {
@@ -140,23 +138,11 @@ function getBlockingAction (actions) {
140
138
  }
141
139
 
142
140
  function setTemplates (config) {
143
- if (config.appsec.blockedTemplateHtml) {
144
- templateHtml = config.appsec.blockedTemplateHtml
145
- } else {
146
- templateHtml = blockedTemplates.html
147
- }
141
+ templateHtml = config.appsec.blockedTemplateHtml || blockedTemplates.html
148
142
 
149
- if (config.appsec.blockedTemplateJson) {
150
- templateJson = config.appsec.blockedTemplateJson
151
- } else {
152
- templateJson = blockedTemplates.json
153
- }
143
+ templateJson = config.appsec.blockedTemplateJson || blockedTemplates.json
154
144
 
155
- if (config.appsec.blockedTemplateGraphql) {
156
- templateGraphqlJson = config.appsec.blockedTemplateGraphql
157
- } else {
158
- templateGraphqlJson = blockedTemplates.graphqlJson
159
- }
145
+ templateGraphqlJson = config.appsec.blockedTemplateGraphql || blockedTemplates.graphqlJson
160
146
  }
161
147
 
162
148
  function isBlocked (res) {
@@ -38,8 +38,8 @@ function onGraphqlStartResolve ({ context, resolverInfo }) {
38
38
 
39
39
  if (!resolverInfo || typeof resolverInfo !== 'object') return
40
40
 
41
- const actions = waf.run({ ephemeral: { [addresses.HTTP_INCOMING_GRAPHQL_RESOLVER]: resolverInfo } }, req)
42
- const blockingAction = getBlockingAction(actions)
41
+ const result = waf.run({ ephemeral: { [addresses.HTTP_INCOMING_GRAPHQL_RESOLVER]: resolverInfo } }, req)
42
+ const blockingAction = getBlockingAction(result?.actions)
43
43
  if (blockingAction) {
44
44
  const requestData = graphqlRequestData.get(req)
45
45
  if (requestData?.isInGraphqlRequest) {
@@ -1,4 +1,4 @@
1
- /* eslint-disable @stylistic/js/max-len */
1
+ /* eslint-disable @stylistic/max-len */
2
2
  'use strict'
3
3
 
4
4
  const { NameAndValue } = require('./hardcoded-rule-type')
@@ -1,4 +1,4 @@
1
- /* eslint-disable @stylistic/js/max-len */
1
+ /* eslint-disable @stylistic/max-len */
2
2
  'use strict'
3
3
 
4
4
  const { ValueOnly, NameAndValue } = require('./hardcoded-rule-type')
@@ -1,4 +1,4 @@
1
- /* eslint-disable @stylistic/js/max-len */
1
+ /* eslint-disable @stylistic/max-len */
2
2
  'use strict'
3
3
 
4
4
  const { ValueOnly, NameAndValue } = require('./hardcoded-rule-type')
@@ -11,13 +11,13 @@ const {
11
11
  } = require('../taint-tracking/source-types')
12
12
 
13
13
  const EXCLUDED_PATHS = getNodeModulesPaths('express')
14
- const EXCLUDED_HEADER_NAMES = [
14
+ const EXCLUDED_HEADER_NAMES = new Set([
15
15
  'location',
16
16
  'sec-websocket-location',
17
17
  'sec-websocket-accept',
18
18
  'upgrade',
19
19
  'connection'
20
- ]
20
+ ])
21
21
 
22
22
  class HeaderInjectionAnalyzer extends InjectionAnalyzer {
23
23
  constructor () {
@@ -27,9 +27,7 @@ class HeaderInjectionAnalyzer extends InjectionAnalyzer {
27
27
  onConfigure () {
28
28
  this.addSub('datadog:http:server:response:set-header:finish', ({ name, value }) => {
29
29
  if (Array.isArray(value)) {
30
- for (let i = 0; i < value.length; i++) {
31
- const headerValue = value[i]
32
-
30
+ for (const headerValue of value) {
33
31
  this.analyze({ name, value: headerValue })
34
32
  }
35
33
  } else {
@@ -65,7 +63,7 @@ class HeaderInjectionAnalyzer extends InjectionAnalyzer {
65
63
  }
66
64
 
67
65
  isExcludedHeaderName (name) {
68
- return EXCLUDED_HEADER_NAMES.includes(name)
66
+ return EXCLUDED_HEADER_NAMES.has(name)
69
67
  }
70
68
 
71
69
  isAllRangesFromHeader (ranges, headerName) {
@@ -19,26 +19,21 @@ class HstsHeaderMissingAnalyzer extends MissingHeaderAnalyzer {
19
19
  }
20
20
 
21
21
  _isHeaderValid (headerValue) {
22
- if (!headerValue) {
23
- return false
24
- }
25
22
  headerValue = headerValue.trim()
26
23
 
27
- if (!headerValue.startsWith(HEADER_VALID_PREFIX)) {
24
+ if (!headerValue?.startsWith(HEADER_VALID_PREFIX)) {
28
25
  return false
29
26
  }
30
27
 
31
28
  const semicolonIndex = headerValue.indexOf(';')
32
- let timestampString
33
- if (semicolonIndex > -1) {
34
- timestampString = headerValue.substring(HEADER_VALID_PREFIX.length + 1, semicolonIndex)
35
- } else {
36
- timestampString = headerValue.substring(HEADER_VALID_PREFIX.length + 1)
37
- }
29
+ const timestampString = headerValue.slice(
30
+ HEADER_VALID_PREFIX.length + 1,
31
+ semicolonIndex === -1 ? headerValue.length : semicolonIndex
32
+ )
38
33
 
39
- const timestamp = parseInt(timestampString)
34
+ const timestamp = Number.parseInt(timestampString)
40
35
  // eslint-disable-next-line eqeqeq
41
- return timestamp == timestampString && timestamp > 0
36
+ return timestamp > 0 && timestamp == timestampString
42
37
  }
43
38
 
44
39
  _isHttpsProtocol (req) {
@@ -10,8 +10,8 @@ const SC_NOT_FOUND = 404
10
10
  const SC_GONE = 410
11
11
  const SC_INTERNAL_SERVER_ERROR = 500
12
12
 
13
- const IGNORED_RESPONSE_STATUS_LIST = [SC_MOVED_PERMANENTLY, SC_MOVED_TEMPORARILY, SC_NOT_MODIFIED,
14
- SC_TEMPORARY_REDIRECT, SC_NOT_FOUND, SC_GONE, SC_INTERNAL_SERVER_ERROR]
13
+ const IGNORED_RESPONSE_STATUS_LIST = new Set([SC_MOVED_PERMANENTLY, SC_MOVED_TEMPORARILY, SC_NOT_MODIFIED,
14
+ SC_TEMPORARY_REDIRECT, SC_NOT_FOUND, SC_GONE, SC_INTERNAL_SERVER_ERROR])
15
15
  const HTML_CONTENT_TYPES = ['text/html', 'application/xhtml+xml']
16
16
 
17
17
  class MissingHeaderAnalyzer extends Analyzer {
@@ -37,9 +37,7 @@ class MissingHeaderAnalyzer extends Analyzer {
37
37
  }
38
38
  }
39
39
 
40
- _getLocation () {
41
- return undefined
42
- }
40
+ _getLocation () {}
43
41
 
44
42
  _checkOCE (context) {
45
43
  return true
@@ -61,7 +59,7 @@ class MissingHeaderAnalyzer extends Analyzer {
61
59
  }
62
60
 
63
61
  _isVulnerable ({ req, res }, context) {
64
- if (!IGNORED_RESPONSE_STATUS_LIST.includes(res.statusCode) && this._isResponseHtml(res)) {
62
+ if (!IGNORED_RESPONSE_STATUS_LIST.has(res.statusCode) && this._isResponseHtml(res)) {
65
63
  return this._isVulnerableFromRequestAndResponse(req, res)
66
64
  }
67
65
  return false
@@ -24,6 +24,8 @@ class NosqlInjectionMongodbAnalyzer extends InjectionAnalyzer {
24
24
  onConfigure () {
25
25
  this.configureSanitizers()
26
26
 
27
+ // Anything that accesses the storage is context dependent
28
+ // eslint-disable-next-line unicorn/consistent-function-scoping
27
29
  const onStart = ({ filters }) => {
28
30
  const store = storage('legacy').getStore()
29
31
  if (store && !store.nosqlAnalyzed && filters?.length) {
@@ -42,6 +44,8 @@ class NosqlInjectionMongodbAnalyzer extends InjectionAnalyzer {
42
44
  }
43
45
  }
44
46
 
47
+ // Anything that accesses the storage is context dependent
48
+ // eslint-disable-next-line unicorn/consistent-function-scoping
45
49
  const onFinish = () => {
46
50
  const store = storage('legacy').getStore()
47
51
  if (store?.nosqlParentStore) {
@@ -7,7 +7,7 @@ const { getIastContext } = require('../iast-context')
7
7
  const { storage } = require('../../../../../datadog-core')
8
8
  const { PATH_TRAVERSAL } = require('../vulnerabilities')
9
9
 
10
- const ignoredOperations = ['dir.close', 'close']
10
+ const ignoredOperations = new Set(['dir.close', 'close'])
11
11
 
12
12
  class PathTraversalAnalyzer extends InjectionAnalyzer {
13
13
  constructor () {
@@ -20,10 +20,10 @@ class PathTraversalAnalyzer extends InjectionAnalyzer {
20
20
  this.internalExclusionList = [
21
21
  'node:fs',
22
22
  'node:internal/fs',
23
- 'node:internal\\fs',
23
+ String.raw`node:internal\fs`,
24
24
  'fs.js',
25
25
  'internal/fs',
26
- 'internal\\fs'
26
+ String.raw`internal\fs`
27
27
  ]
28
28
  }
29
29
 
@@ -36,7 +36,7 @@ class PathTraversalAnalyzer extends InjectionAnalyzer {
36
36
  // but if we spect a store in the context to be present we are going to exclude
37
37
  // all out_of_the_request fs.operations
38
38
  // AppsecFsPlugin must be enabled
39
- if (ignoredOperations.includes(obj.operation) || outOfReqOrChild) return
39
+ if (ignoredOperations.has(obj.operation) || outOfReqOrChild) return
40
40
 
41
41
  const pathArguments = []
42
42
  if (obj.dest) {
@@ -71,16 +71,13 @@ class PathTraversalAnalyzer extends InjectionAnalyzer {
71
71
  }
72
72
 
73
73
  _isExcluded (location) {
74
- let ret = true
75
- if (location && location.path) {
74
+ if (location?.path) {
76
75
  // Exclude from reporting those vulnerabilities which location is from an internal fs call
77
- if (location.isInternal) {
78
- ret = this.internalExclusionList.some(elem => location.path.includes(elem))
79
- } else {
80
- ret = this.exclusionList.some(elem => location.path.includes(elem))
81
- }
76
+ return location.isInternal
77
+ ? this.internalExclusionList.some(elem => location.path.includes(elem))
78
+ : this.exclusionList.some(elem => location.path.includes(elem))
82
79
  }
83
- return ret
80
+ return true
84
81
  }
85
82
 
86
83
  analyze (value) {
@@ -41,7 +41,7 @@ class Analyzer extends SinkIastPlugin {
41
41
 
42
42
  if (!this._isExcluded(location)) {
43
43
  const originalLocation = this._getOriginalLocation(location)
44
- const spanId = context && context.rootSpan && context.rootSpan.context().toSpanId()
44
+ const spanId = context?.rootSpan?.context().toSpanId()
45
45
  const stackId = getIastStackTraceId(context)
46
46
  const vulnerability = this._createVulnerability(
47
47
  this._type,
@@ -112,9 +112,10 @@ class Analyzer extends SinkIastPlugin {
112
112
  const iastContext = getIastContext(store)
113
113
  if (this._isInvalidContext(store, iastContext)) return
114
114
 
115
- for (let i = 0; i < values.length; i++) {
116
- const value = values[i]
115
+ for (const value of values) {
117
116
  if (this._isVulnerable(value, iastContext)) {
117
+ // TODO(BridgeAR): Here are multiple cases that receive a different
118
+ // number of arguments than passed through. Fix those cases.
118
119
  if (this._checkOCE(iastContext, value)) {
119
120
  this._report(value, iastContext)
120
121
  }
@@ -124,7 +125,7 @@ class Analyzer extends SinkIastPlugin {
124
125
  }
125
126
 
126
127
  _checkOCE (context) {
127
- return overheadController.hasQuota(overheadController.OPERATIONS.REPORT_VULNERABILITY, context)
128
+ return overheadController.hasQuota(overheadController.OPERATIONS.REPORT_VULNERABILITY, context, this._type)
128
129
  }
129
130
 
130
131
  _createVulnerability (type, evidence, spanId, location, stackId) {
@@ -11,7 +11,7 @@ const { TagKey } = require('../telemetry/iast-metric')
11
11
 
12
12
  class IastContextPlugin extends IastPlugin {
13
13
  startCtxOn (channelName, tag) {
14
- super.addSub(channelName, (message) => this.startContext())
14
+ super.addSub(channelName, (message) => this.startContext(message?.currentStore))
15
15
 
16
16
  this._getAndRegisterSubscription({
17
17
  channelName,
@@ -44,11 +44,10 @@ class IastContextPlugin extends IastPlugin {
44
44
  }
45
45
  }
46
46
 
47
- startContext () {
47
+ startContext (store = storage('legacy').getStore()) {
48
48
  let isRequestAcquired = false
49
49
  let iastContext
50
50
 
51
- const store = storage('legacy').getStore()
52
51
  if (store) {
53
52
  const topContext = this.getTopContext()
54
53
  const rootSpan = this.getRootSpan(store)
@@ -130,9 +130,9 @@ class IastPlugin extends Plugin {
130
130
  }
131
131
 
132
132
  _getAndRegisterSubscription ({ moduleName, channelName, tag, tagKey }) {
133
- if (!channelName && !moduleName) return
134
-
135
133
  if (!moduleName) {
134
+ if (!channelName) return
135
+
136
136
  let firstSep = channelName.indexOf(':')
137
137
  if (firstSep === -1) {
138
138
  moduleName = channelName
@@ -141,7 +141,7 @@ class IastPlugin extends Plugin {
141
141
  firstSep = channelName.indexOf(':', 'tracing:'.length + 1)
142
142
  }
143
143
  const lastSep = channelName.indexOf(':', firstSep + 1)
144
- moduleName = channelName.substring(firstSep + 1, lastSep !== -1 ? lastSep : channelName.length)
144
+ moduleName = channelName.slice(firstSep + 1, lastSep === -1 ? channelName.length : lastSep)
145
145
  }
146
146
  }
147
147
 
@@ -92,6 +92,7 @@ function onIncomingHttpRequestEnd (data) {
92
92
  const vulnerabilities = iastContext.vulnerabilities
93
93
  const rootSpan = iastContext.rootSpan
94
94
  vulnerabilityReporter.sendVulnerabilities(vulnerabilities, rootSpan)
95
+ overheadController.consolidateVulnerabilities(iastContext)
95
96
  removeTransaction(iastContext)
96
97
  iastTelemetry.onRequestEnd(iastContext, iastContext.rootSpan)
97
98
  }