dd-trace 6.15.0 → 6.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/ci/diagnose.js +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +4 -8
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/package-check.js +4 -1
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +1 -2
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +169 -0
- package/next.d.ts +27 -0
- package/next.js +3 -0
- package/package.json +28 -23
- package/packages/datadog-esbuild/index.js +14 -1
- package/packages/datadog-esbuild/src/resolver.js +284 -0
- package/packages/datadog-esbuild/src/utils.js +162 -120
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/ai.js +39 -97
- package/packages/datadog-instrumentations/src/anthropic.js +76 -134
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +1 -3
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/azure-cosmos.js +1 -1
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +23 -9
- package/packages/datadog-instrumentations/src/azure-functions.js +48 -0
- package/packages/datadog-instrumentations/src/bullmq.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -3
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +72 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
- package/packages/datadog-instrumentations/src/dd-trace-api.js +2 -2
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +39 -14
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +25 -8
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +69 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +13 -64
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +109 -29
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-durable-functions.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -16
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +6 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +99 -75
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +141 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/langchain.js +1 -1
- package/packages/datadog-instrumentations/src/langgraph.js +1 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mercurius.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +22 -25
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-agents.js +1 -1
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +97 -80
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -16
- package/packages/datadog-instrumentations/src/playwright.js +238 -55
- package/packages/datadog-instrumentations/src/postgres.js +7 -0
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +56 -23
- package/packages/datadog-instrumentations/src/webdriverio.js +23 -42
- package/packages/datadog-instrumentations/src/ws.js +0 -1
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +7 -2
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-cosmos/src/index.js +1 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +95 -1
- package/packages/datadog-plugin-cucumber/src/index.js +10 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -24
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -36
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-request-context.js +31 -0
- package/packages/datadog-plugin-graphql/src/resolve-error.js +32 -11
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +13 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +39 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +76 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +10 -0
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-turbopack/index.js +206 -0
- package/packages/datadog-turbopack/src/constants.js +5 -0
- package/packages/datadog-turbopack/src/loader.js +484 -0
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +3 -2
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +53 -25
- package/packages/dd-trace/src/aiguard/integrations/evaluate.js +49 -25
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -3
- package/packages/dd-trace/src/aiguard/integrations/openai.js +132 -29
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +116 -42
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +29 -2
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +25 -0
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/telemetry/api_security.js +1 -3
- package/packages/dd-trace/src/appsec/telemetry/common.js +4 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +23 -5
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +1 -20
- package/packages/dd-trace/src/appsec/telemetry/user.js +1 -3
- package/packages/dd-trace/src/appsec/telemetry/waf.js +1 -20
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +74 -66
- package/packages/dd-trace/src/config/helper.js +9 -2
- package/packages/dd-trace/src/config/index.js +44 -29
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +146 -9
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +76 -17
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +34 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +40 -14
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +50 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/discovery.js +3 -5
- package/packages/dd-trace/src/evp_proxy/path.js +11 -4
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/docker.js +4 -1
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/proxy.js +3 -0
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +0 -2
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +639 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +30 -7
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/index.js +0 -4
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +0 -6
- package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +4 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +103 -35
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +36 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugin_manager.js +9 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +8 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +25 -21
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +21 -45
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/utils.js +0 -10
|
@@ -114,11 +114,10 @@ function digitRunEnd (value, from, length) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
117
|
+
* Returns the end of a plain integer or decimal literal, or `-1` to delegate exponents and radix literals to `NUMERIC`.
|
|
118
118
|
* @param {string} value
|
|
119
119
|
* @param {number} intEnd Index after the integer digit run measured by the caller.
|
|
120
120
|
* @param {number} length
|
|
121
|
-
* @returns {number} Index after the literal, or `-1` to defer to the `NUMERIC` regex.
|
|
122
121
|
*/
|
|
123
122
|
function scanPlainNumber (value, intEnd, length) {
|
|
124
123
|
// A digit run touching `x`/`b` is a radix prefix (`0x`, `0b`) — let the regex own it.
|
|
@@ -177,7 +176,6 @@ const FALL_THROUGH = -2 // not a literal start -> advance one character and reco
|
|
|
177
176
|
* @param {string} value
|
|
178
177
|
* @param {number} from
|
|
179
178
|
* @param {number} length
|
|
180
|
-
* @returns {number} Index of the first line terminator at or after `from`, else `length`.
|
|
181
179
|
*/
|
|
182
180
|
function lineEnd (value, from, length) {
|
|
183
181
|
for (let i = from; i < length; i++) {
|
|
@@ -196,7 +194,6 @@ function lineEnd (value, from, length) {
|
|
|
196
194
|
* @param {number} quote Char code of the opening delimiter, `'` or `"`.
|
|
197
195
|
* @param {boolean} conservativeBackslash Whether an odd backslash before a closing quote makes the
|
|
198
196
|
* remainder ambiguous and therefore unterminated.
|
|
199
|
-
* @returns {number} Index after the closing quote, or `UNTERMINATED`.
|
|
200
197
|
*/
|
|
201
198
|
function scanQuotedDoubled (value, start, length, quote, conservativeBackslash) {
|
|
202
199
|
let backslashCount = 0
|
|
@@ -229,7 +226,6 @@ function scanQuotedDoubled (value, start, length, quote, conservativeBackslash)
|
|
|
229
226
|
* @param {number} length
|
|
230
227
|
* @param {number} quote Char code of the opening delimiter, `'` or `"`.
|
|
231
228
|
* @param {boolean} doubled Whether two adjacent quotes escape each other.
|
|
232
|
-
* @returns {number} Index after the closing quote, or `UNTERMINATED`.
|
|
233
229
|
*/
|
|
234
230
|
function scanQuotedBackslash (value, start, length, quote, doubled) {
|
|
235
231
|
for (let i = start + 1; i < length; i++) {
|
|
@@ -269,12 +265,13 @@ function isPostgresEscapeString (value, quoteIndex) {
|
|
|
269
265
|
/**
|
|
270
266
|
* Oracle `q'X…X'`: `X` is one of `< ( { [` (closed by its mirror) or any other char (closed by
|
|
271
267
|
* itself). The body may span line terminators.
|
|
268
|
+
* The result is the index after the closing `X'`.
|
|
269
|
+
* It is `FALL_THROUGH` when `q'` ends the value or is followed by a line terminator.
|
|
270
|
+
* Oracle forbids whitespace as the delimiter, so this case is a plain string instead of a quote opener.
|
|
271
|
+
* It is `UNTERMINATED` when no closing delimiter exists.
|
|
272
272
|
* @param {string} value
|
|
273
273
|
* @param {number} start
|
|
274
274
|
* @param {number} length
|
|
275
|
-
* @returns {number} Index after the closing `X'`; `FALL_THROUGH` when `q'` is at the end of the value
|
|
276
|
-
* or followed by a line terminator — Oracle forbids whitespace as the delimiter, so that `'` is a
|
|
277
|
-
* plain string, not a quote opener; or `UNTERMINATED`.
|
|
278
275
|
*/
|
|
279
276
|
function scanOracleQuote (value, start, length) {
|
|
280
277
|
const delimiter = value.charCodeAt(start + 2)
|
|
@@ -294,11 +291,12 @@ function scanOracleQuote (value, start, length) {
|
|
|
294
291
|
* Postgres `$tag$ … $tag$`, where `tag` is empty or an identifier. The body may span line
|
|
295
292
|
* terminators — PL/pgSQL function bodies routinely do, and treating a newline as the end of the
|
|
296
293
|
* literal would leave the rest of a multi-line body unredacted.
|
|
294
|
+
* The result is the index after the closing tag.
|
|
295
|
+
* It is `FALL_THROUGH` when no second `$` exists.
|
|
296
|
+
* It is `UNTERMINATED` when the opening tag is malformed or has no close.
|
|
297
297
|
* @param {string} value
|
|
298
298
|
* @param {number} start
|
|
299
299
|
* @param {number} length
|
|
300
|
-
* @returns {number} Index after the closing tag; `FALL_THROUGH` when no second `$` exists; or
|
|
301
|
-
* `UNTERMINATED` when the opening tag is malformed or has no close.
|
|
302
300
|
*/
|
|
303
301
|
function scanDollarQuote (value, start, length) {
|
|
304
302
|
const tagEnd = value.indexOf('$', start + 1)
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../../../../../log')
|
|
4
4
|
|
|
5
|
-
const AUTHORITY =
|
|
5
|
+
const AUTHORITY = String.raw`^(?:[^:]+:)?[\t\r\n]*/[\t\r\n]*/([^@]+)@`
|
|
6
6
|
// The key class excludes `?` and `#` so the greedy quantifier is bounded per fragment.
|
|
7
7
|
// Query keys cannot legitimately contain those characters (they delimit query/fragment
|
|
8
8
|
// boundaries), so excluding them preserves match semantics for valid URLs while keeping
|
|
9
9
|
// the regex linear on arbitrary input.
|
|
10
10
|
const QUERY_FRAGMENT = '[?#&]([^=&;?#]+)=([^?#&]+)'
|
|
11
|
-
const pattern = new RegExp(`${AUTHORITY}|${QUERY_FRAGMENT}`, '
|
|
11
|
+
const pattern = new RegExp(`${AUTHORITY}|${QUERY_FRAGMENT}`, 'g')
|
|
12
12
|
|
|
13
13
|
module.exports = function extractSensitiveRanges (evidence) {
|
|
14
14
|
try {
|
|
@@ -24,8 +24,8 @@ const MAX_EVIDENCE_LENGTH = 32_768
|
|
|
24
24
|
|
|
25
25
|
class SensitiveHandler {
|
|
26
26
|
constructor () {
|
|
27
|
-
this._namePattern = new RegExp(/** @type {string} */ (defaults['iast.
|
|
28
|
-
this._valuePattern = new RegExp(/** @type {string} */ (defaults['iast.
|
|
27
|
+
this._namePattern = new RegExp(/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_NAME_PATTERN']), 'gmi')
|
|
28
|
+
this._valuePattern = new RegExp(/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_VALUE_PATTERN']), 'gmi')
|
|
29
29
|
|
|
30
30
|
this._sensitiveAnalyzers = new Map()
|
|
31
31
|
this._sensitiveAnalyzers.set(vulnerabilities.CODE_INJECTION, taintedRangeBasedSensitiveAnalyzer)
|
|
@@ -13,7 +13,10 @@ const REGEX_FOR_STRINGIFY_SENSITIVE_NOT_STRING = new RegExp(String.raw`"${STRING
|
|
|
13
13
|
const REGEX_FOR_STRINGIFY_SENSITIVE = new RegExp(String.raw`${STRINGIFY_SENSITIVE_KEY}_\d+_(\d+)_`)
|
|
14
14
|
const REGEX_FOR_STRINGIFY_RANGE = new RegExp(String.raw`(${STRINGIFY_RANGE_KEY}_\d+_)`)
|
|
15
15
|
|
|
16
|
-
const sensitiveValueRegex = new RegExp(
|
|
16
|
+
const sensitiveValueRegex = new RegExp(
|
|
17
|
+
/** @type {string} */ (defaults['iast.DD_IAST_REDACTION_VALUE_PATTERN']),
|
|
18
|
+
'gmi'
|
|
19
|
+
)
|
|
17
20
|
|
|
18
21
|
function iterateObject (target, fn, levelKeys = [], depth = 10, visited = new Set()) {
|
|
19
22
|
for (const key of Object.keys(target)) {
|
|
@@ -138,15 +138,15 @@ function replaceCallSiteFromSourceMap (callsite) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
function start (config, _tracer) {
|
|
141
|
-
deduplicationEnabled = config.iast.
|
|
142
|
-
stackTraceEnabled = config.iast.
|
|
143
|
-
stackTraceMaxDepth = config.appsec.
|
|
144
|
-
maxStackTraces = config.appsec.
|
|
141
|
+
deduplicationEnabled = config.iast.DD_IAST_DEDUPLICATION_ENABLED
|
|
142
|
+
stackTraceEnabled = config.iast.DD_IAST_STACK_TRACE_ENABLED
|
|
143
|
+
stackTraceMaxDepth = config.appsec.DD_APPSEC_MAX_STACK_TRACE_DEPTH
|
|
144
|
+
maxStackTraces = config.appsec.DD_APPSEC_MAX_STACK_TRACES
|
|
145
145
|
|
|
146
146
|
vulnerabilitiesFormatter.setRedactVulnerabilities(
|
|
147
|
-
config.iast.
|
|
148
|
-
config.iast.
|
|
149
|
-
config.iast.
|
|
147
|
+
config.iast.DD_IAST_REDACTION_ENABLED,
|
|
148
|
+
config.iast.DD_IAST_REDACTION_NAME_PATTERN,
|
|
149
|
+
config.iast.DD_IAST_REDACTION_VALUE_PATTERN
|
|
150
150
|
)
|
|
151
151
|
if (deduplicationEnabled) {
|
|
152
152
|
startClearCacheTimer()
|
|
@@ -87,7 +87,7 @@ function enable (_config) {
|
|
|
87
87
|
appsecTelemetry.enable(_config)
|
|
88
88
|
graphql.enable()
|
|
89
89
|
|
|
90
|
-
if (_config.appsec.
|
|
90
|
+
if (_config.appsec.DD_APPSEC_RASP_ENABLED) {
|
|
91
91
|
rasp.enable(_config)
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -101,7 +101,7 @@ function enable (_config) {
|
|
|
101
101
|
|
|
102
102
|
apiSecurity.configure(_config)
|
|
103
103
|
|
|
104
|
-
UserTracking.setCollectionMode(_config.appsec.
|
|
104
|
+
UserTracking.setCollectionMode(_config.appsec.DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE, false)
|
|
105
105
|
|
|
106
106
|
httpRequest.setConfig(_config)
|
|
107
107
|
|
|
@@ -11,6 +11,8 @@ const waf = require('./waf')
|
|
|
11
11
|
|
|
12
12
|
const activeInvocations = new WeakMap()
|
|
13
13
|
|
|
14
|
+
const MAX_RESPONSE_BODY_SIZE = 16 * 1024 * 1024
|
|
15
|
+
|
|
14
16
|
/**
|
|
15
17
|
* Maps pre-extracted HTTP data from the Lambda event to WAF addresses,
|
|
16
18
|
* runs the WAF, and reports results on the span.
|
|
@@ -86,11 +88,12 @@ function onLambdaStartInvocation (data) {
|
|
|
86
88
|
* WAF pass, disposes the WAF context, and finishes the request report.
|
|
87
89
|
*
|
|
88
90
|
* @param {{ span: object, statusCode: string | undefined,
|
|
89
|
-
* responseHeaders: Record<string, string> | undefined
|
|
91
|
+
* responseHeaders: Record<string, string> | undefined,
|
|
92
|
+
* responseBody: unknown, isBase64Encoded: boolean | undefined }} data
|
|
90
93
|
*/
|
|
91
94
|
function onLambdaEndInvocation (data) {
|
|
92
95
|
try {
|
|
93
|
-
const { span, statusCode, responseHeaders } = data
|
|
96
|
+
const { span, statusCode, responseHeaders, responseBody, isBase64Encoded } = data
|
|
94
97
|
|
|
95
98
|
if (!span) {
|
|
96
99
|
log.warn('[ASM] No span provided in Lambda end invocation')
|
|
@@ -127,6 +130,11 @@ function onLambdaEndInvocation (data) {
|
|
|
127
130
|
|
|
128
131
|
if (samplingDecision === apiSecurity.SamplingDecision.SAMPLE) {
|
|
129
132
|
persistent[addresses.WAF_CONTEXT_PROCESSOR] = { 'extract-schema': true }
|
|
133
|
+
|
|
134
|
+
const parsedBody = parseResponseBody(responseBody, responseHeaders, isBase64Encoded)
|
|
135
|
+
if (parsedBody !== undefined) {
|
|
136
|
+
persistent[addresses.HTTP_INCOMING_RESPONSE_BODY] = parsedBody
|
|
137
|
+
}
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
let wafResult
|
|
@@ -147,6 +155,67 @@ function onLambdaEndInvocation (data) {
|
|
|
147
155
|
}
|
|
148
156
|
}
|
|
149
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Turns the raw response body published by the Lambda layer into the object the WAF expects
|
|
160
|
+
*
|
|
161
|
+
* @param {unknown} rawBody
|
|
162
|
+
* @param {Record<string, string> | undefined} headers Already lowercased by the Lambda layer
|
|
163
|
+
* @param {boolean | undefined} isBase64Encoded
|
|
164
|
+
* @returns {object | undefined} The parsed body, or `undefined` when it cannot be used
|
|
165
|
+
*/
|
|
166
|
+
function parseResponseBody (rawBody, headers, isBase64Encoded) {
|
|
167
|
+
if (!rawBody) return
|
|
168
|
+
|
|
169
|
+
// A handler that answered with the payload itself needs no parsing, and no content type either.
|
|
170
|
+
if (typeof rawBody === 'object') return rawBody
|
|
171
|
+
|
|
172
|
+
if (typeof rawBody !== 'string') return
|
|
173
|
+
|
|
174
|
+
if (!isJsonContentType(headers?.['content-type'])) return
|
|
175
|
+
|
|
176
|
+
if (isOverSizeCap(rawBody, isBase64Encoded)) {
|
|
177
|
+
log.debug('[ASM] Lambda response body larger than %d bytes, skipping schema extraction',
|
|
178
|
+
MAX_RESPONSE_BODY_SIZE)
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const contentEncoding = headers?.['content-encoding']?.toLowerCase()
|
|
183
|
+
if (contentEncoding && contentEncoding !== 'identity') return
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const parsed = JSON.parse(isBase64Encoded ? Buffer.from(rawBody, 'base64').toString('utf8') : rawBody)
|
|
187
|
+
|
|
188
|
+
// A JSON scalar carries no schema worth extracting.
|
|
189
|
+
if (parsed === null || typeof parsed !== 'object') return
|
|
190
|
+
|
|
191
|
+
return parsed
|
|
192
|
+
} catch {
|
|
193
|
+
// The SyntaxError message embeds a fragment of the body, which is customer data.
|
|
194
|
+
log.debug('[ASM] Failed to parse Lambda response body')
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @param {string | undefined} contentType
|
|
200
|
+
*/
|
|
201
|
+
function isJsonContentType (contentType) {
|
|
202
|
+
return typeof contentType === 'string' && contentType.toLowerCase().includes('json')
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Tells whether a raw body exceeds the size cap, without decoding or measuring it when avoidable
|
|
207
|
+
*
|
|
208
|
+
* @param {string} rawBody
|
|
209
|
+
* @param {boolean | undefined} isBase64Encoded
|
|
210
|
+
*/
|
|
211
|
+
function isOverSizeCap (rawBody, isBase64Encoded) {
|
|
212
|
+
if (isBase64Encoded) return Math.floor(rawBody.length * 3 / 4) >= MAX_RESPONSE_BODY_SIZE
|
|
213
|
+
if (rawBody.length >= MAX_RESPONSE_BODY_SIZE) return true
|
|
214
|
+
if (rawBody.length * 3 < MAX_RESPONSE_BODY_SIZE) return false
|
|
215
|
+
|
|
216
|
+
return Buffer.byteLength(rawBody, 'utf8') >= MAX_RESPONSE_BODY_SIZE
|
|
217
|
+
}
|
|
218
|
+
|
|
150
219
|
module.exports = {
|
|
151
220
|
onLambdaStartInvocation,
|
|
152
221
|
onLambdaEndInvocation,
|
|
@@ -45,7 +45,11 @@ class DatadogRaspAbortError extends Error {
|
|
|
45
45
|
function handleResult (result, req, res, abortController, config, raspRule) {
|
|
46
46
|
const generateStackTraceAction = result?.actions?.generate_stack
|
|
47
47
|
|
|
48
|
-
const {
|
|
48
|
+
const {
|
|
49
|
+
DD_APPSEC_STACK_TRACE_ENABLED: enabled,
|
|
50
|
+
DD_APPSEC_MAX_STACK_TRACE_DEPTH: maxDepth,
|
|
51
|
+
DD_APPSEC_MAX_STACK_TRACES: maxStackTraces,
|
|
52
|
+
} = config.appsec
|
|
49
53
|
|
|
50
54
|
const rootSpan = web.root(req)
|
|
51
55
|
|
|
@@ -43,7 +43,7 @@ function enable (rcInstance, config, appsec) {
|
|
|
43
43
|
setCollectionMode(rcConfig.auto_user_instrum.mode)
|
|
44
44
|
autoUserInstrumModeId = configId
|
|
45
45
|
} else if (configId === autoUserInstrumModeId) {
|
|
46
|
-
setCollectionMode(config.appsec.
|
|
46
|
+
setCollectionMode(config.appsec.DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE)
|
|
47
47
|
autoUserInstrumModeId = null
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -68,7 +68,7 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
|
|
|
68
68
|
const isRemoteConfigControlling = action === 'apply' || action === 'modify'
|
|
69
69
|
const shouldEnable = isRemoteConfigControlling
|
|
70
70
|
? rcConfig.asm.enabled // take control
|
|
71
|
-
: config.appsec.
|
|
71
|
+
: config.appsec.DD_APPSEC_ENABLED // give back control to local config
|
|
72
72
|
|
|
73
73
|
if (shouldEnable) {
|
|
74
74
|
appsec.enable(config)
|
|
@@ -79,8 +79,10 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
|
|
|
79
79
|
// TODO: Use configWithOrigin /generateTelemetry instead of manually constructing the change.
|
|
80
80
|
updateConfig([
|
|
81
81
|
{
|
|
82
|
-
name: '
|
|
83
|
-
origin: isRemoteConfigControlling
|
|
82
|
+
name: 'DD_APPSEC_ENABLED',
|
|
83
|
+
origin: isRemoteConfigControlling
|
|
84
|
+
? 'remote_config'
|
|
85
|
+
: config.getOrigin('appsec.DD_APPSEC_ENABLED'),
|
|
84
86
|
value: shouldEnable,
|
|
85
87
|
},
|
|
86
88
|
], config)
|
|
@@ -93,7 +95,7 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
|
|
|
93
95
|
* @param {object} appsecConfig - Appsec config
|
|
94
96
|
*/
|
|
95
97
|
function enableWafUpdate (appsecConfig) {
|
|
96
|
-
if (rc && appsecConfig && !appsecConfig.
|
|
98
|
+
if (rc && appsecConfig && !appsecConfig.DD_APPSEC_RULES) {
|
|
97
99
|
// dirty require to make startup faster for serverless
|
|
98
100
|
const { ASM_WAF_PRODUCTS } = require('./rc-products')
|
|
99
101
|
const RuleManager = require('./rule_manager')
|
|
@@ -119,7 +121,7 @@ function enableWafUpdate (appsecConfig) {
|
|
|
119
121
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_TRACE_TAGGING_RULES, true)
|
|
120
122
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_EXTENDED_DATA_COLLECTION, true)
|
|
121
123
|
|
|
122
|
-
if (appsecConfig.
|
|
124
|
+
if (appsecConfig.DD_APPSEC_RASP_ENABLED) {
|
|
123
125
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_SQLI, true)
|
|
124
126
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_SSRF, true)
|
|
125
127
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_LFI, true)
|
|
@@ -8,7 +8,7 @@ const web = require('../plugins/util/web')
|
|
|
8
8
|
const { ipHeaderList } = require('../plugins/util/ip_extractor')
|
|
9
9
|
const { keepTrace } = require('../priority_sampler')
|
|
10
10
|
const { ASM } = require('../standalone/product')
|
|
11
|
-
const { isEmpty } = require('../util')
|
|
11
|
+
const { isEmpty, truncateString } = require('../util')
|
|
12
12
|
const { getActiveRequest } = require('./store')
|
|
13
13
|
const {
|
|
14
14
|
incrementWafInitMetric,
|
|
@@ -114,11 +114,15 @@ const NON_EXTENDED_REQUEST_HEADERS = new Set([...requestHeadersList, ...eventHea
|
|
|
114
114
|
const NON_EXTENDED_RESPONSE_HEADERS = new Set(responseHeaderList)
|
|
115
115
|
const REDACTED_HEADERS = new Set(redactedHeadersList)
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @param {import('../config/config-types').ConfigProperties['appsec']} _config
|
|
119
|
+
* @param {boolean} [inferredProxyServicesEnabled]
|
|
120
|
+
*/
|
|
117
121
|
function init (_config, inferredProxyServicesEnabled) {
|
|
118
|
-
config.headersExtendedCollectionEnabled = _config.
|
|
119
|
-
config.maxHeadersCollected = _config.
|
|
120
|
-
config.headersRedaction = _config.
|
|
121
|
-
config.raspBodyCollection = _config.
|
|
122
|
+
config.headersExtendedCollectionEnabled = _config.DD_APPSEC_COLLECT_ALL_HEADERS
|
|
123
|
+
config.maxHeadersCollected = _config.DD_APPSEC_MAX_COLLECTED_HEADERS
|
|
124
|
+
config.headersRedaction = _config.DD_APPSEC_HEADER_COLLECTION_REDACTION_ENABLED
|
|
125
|
+
config.raspBodyCollection = _config.DD_APPSEC_RASP_COLLECT_REQUEST_BODY
|
|
122
126
|
config.inferredProxyServicesEnabled = inferredProxyServicesEnabled
|
|
123
127
|
}
|
|
124
128
|
|
|
@@ -431,7 +435,7 @@ function truncateRequestBody (target, depth = 0) {
|
|
|
431
435
|
switch (typeof target) {
|
|
432
436
|
case 'string':
|
|
433
437
|
if (target.length > COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH) {
|
|
434
|
-
return { value: target
|
|
438
|
+
return { value: truncateString(target, COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH), truncated: true }
|
|
435
439
|
}
|
|
436
440
|
return { value: target, truncated: false }
|
|
437
441
|
case 'object': {
|
|
@@ -20,15 +20,15 @@ let appliedActions = new Map()
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* @typedef {import('./waf').WAFConfig & {
|
|
23
|
+
* @typedef {import('./waf').WAFConfig & { DD_APPSEC_RULES?: string }} AppSecConfig
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @param {AppSecConfig} config
|
|
28
28
|
*/
|
|
29
29
|
function loadRules (config) {
|
|
30
|
-
const defaultRules = config.
|
|
31
|
-
? JSON.parse(readFileSync(config.
|
|
30
|
+
const defaultRules = config.DD_APPSEC_RULES
|
|
31
|
+
? JSON.parse(readFileSync(config.DD_APPSEC_RULES, 'utf8'))
|
|
32
32
|
: require('./recommended.json')
|
|
33
33
|
|
|
34
34
|
waf.init(defaultRules, config)
|
|
@@ -14,7 +14,6 @@ const { getRootSpan } = require('./utils')
|
|
|
14
14
|
* @param {import('../../tracer')} tracer
|
|
15
15
|
* @param {import('../../../../../index').User} user
|
|
16
16
|
* @param {Record<string, string>} [metadata]
|
|
17
|
-
* @returns {void}
|
|
18
17
|
*/
|
|
19
18
|
function trackUserLoginSuccessEvent (tracer, user, metadata) {
|
|
20
19
|
// TODO: better user check here and in _setUser() ?
|
|
@@ -48,7 +47,6 @@ function trackUserLoginSuccessEvent (tracer, user, metadata) {
|
|
|
48
47
|
* @param {string} userId
|
|
49
48
|
* @param {boolean} exists
|
|
50
49
|
* @param {Record<string, string>} [metadata]
|
|
51
|
-
* @returns {void}
|
|
52
50
|
*/
|
|
53
51
|
function trackUserLoginFailureEvent (tracer, userId, exists, metadata) {
|
|
54
52
|
if (!userId || typeof userId !== 'string') {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const telemetryMetrics = require('../../telemetry/metrics')
|
|
4
|
+
|
|
3
5
|
const DD_TELEMETRY_REQUEST_METRICS = Symbol('_dd.appsec.telemetry.request.metrics')
|
|
6
|
+
const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
4
7
|
|
|
5
8
|
const tags = {
|
|
6
9
|
BLOCK_FAILURE: 'block_failure',
|
|
@@ -22,6 +25,7 @@ function getVersionsTags (wafVersion, rulesVersion) {
|
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
module.exports = {
|
|
28
|
+
appsecMetrics,
|
|
25
29
|
tags,
|
|
26
30
|
getVersionsTags,
|
|
27
31
|
DD_TELEMETRY_REQUEST_METRICS,
|
|
@@ -5,14 +5,13 @@ const {
|
|
|
5
5
|
incrementApiSecRequestNoSchema,
|
|
6
6
|
incrementApiSecRequestSchema,
|
|
7
7
|
} = require('./api_security')
|
|
8
|
-
const { DD_TELEMETRY_REQUEST_METRICS } = require('./common')
|
|
8
|
+
const { appsecMetrics, DD_TELEMETRY_REQUEST_METRICS, getVersionsTags } = require('./common')
|
|
9
9
|
const { incrementMissingUserId, incrementMissingUserLogin, incrementSdkEvent } = require('./user')
|
|
10
10
|
const {
|
|
11
11
|
addRaspRequestMetrics,
|
|
12
12
|
trackRaspMetrics,
|
|
13
13
|
trackRaspRuleMatch,
|
|
14
14
|
trackRaspRuleSkipped,
|
|
15
|
-
incrementRaspDurationMetrics,
|
|
16
15
|
} = require('./rasp')
|
|
17
16
|
const {
|
|
18
17
|
addWafRequestMetrics,
|
|
@@ -21,7 +20,6 @@ const {
|
|
|
21
20
|
incrementWafUpdates,
|
|
22
21
|
incrementWafConfigErrors,
|
|
23
22
|
incrementWafRequests,
|
|
24
|
-
incrementWafDurationMetrics,
|
|
25
23
|
} = require('./waf')
|
|
26
24
|
|
|
27
25
|
const metricsStoreMap = new WeakMap()
|
|
@@ -150,8 +148,28 @@ function incrementRequestDurationMetrics (req) {
|
|
|
150
148
|
const store = getStore(req)
|
|
151
149
|
const requestMetrics = store[DD_TELEMETRY_REQUEST_METRICS]
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
if (!requestMetrics.duration && !requestMetrics.durationExt &&
|
|
152
|
+
!requestMetrics.raspDuration && !requestMetrics.raspDurationExt) return
|
|
153
|
+
|
|
154
|
+
const { duration, durationExt, raspDuration, raspDurationExt, wafVersion, rulesVersion } = requestMetrics
|
|
155
|
+
|
|
156
|
+
const versionsTags = getVersionsTags(wafVersion, rulesVersion)
|
|
157
|
+
|
|
158
|
+
if (duration) {
|
|
159
|
+
appsecMetrics.distribution('waf.duration', versionsTags).track(duration)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (durationExt) {
|
|
163
|
+
appsecMetrics.distribution('waf.duration_ext', versionsTags).track(durationExt)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (raspDuration) {
|
|
167
|
+
appsecMetrics.distribution('rasp.duration', versionsTags).track(raspDuration)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (raspDurationExt) {
|
|
171
|
+
appsecMetrics.distribution('rasp.duration_ext', versionsTags).track(raspDurationExt)
|
|
172
|
+
}
|
|
155
173
|
}
|
|
156
174
|
|
|
157
175
|
function incrementMissingUserLoginMetric (framework, eventType) {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { DD_TELEMETRY_REQUEST_METRICS, getVersionsTags } = require('./common')
|
|
5
|
-
|
|
6
|
-
const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
3
|
+
const { appsecMetrics, DD_TELEMETRY_REQUEST_METRICS, getVersionsTags } = require('./common')
|
|
7
4
|
|
|
8
5
|
const BLOCKING_STATUS = {
|
|
9
6
|
FAILURE: 'failure',
|
|
@@ -77,21 +74,6 @@ function trackRaspRuleMatch (store, raspRule, blockTriggered, blocked) {
|
|
|
77
74
|
appsecMetrics.count('rasp.rule.match', tags).inc(1)
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
function incrementRaspDurationMetrics (requestMetrics) {
|
|
81
|
-
const { raspDuration, raspDurationExt, wafVersion, rulesVersion } = requestMetrics
|
|
82
|
-
if (!raspDuration && !raspDurationExt) return
|
|
83
|
-
|
|
84
|
-
const versionsTags = getVersionsTags(wafVersion, rulesVersion)
|
|
85
|
-
|
|
86
|
-
if (raspDuration) {
|
|
87
|
-
appsecMetrics.distribution('rasp.duration', versionsTags).track(raspDuration)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (raspDurationExt) {
|
|
91
|
-
appsecMetrics.distribution('rasp.duration_ext', versionsTags).track(raspDurationExt)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
77
|
function trackRaspRuleSkipped (raspRule, reason) {
|
|
96
78
|
const tags = { reason, rule_type: raspRule.type }
|
|
97
79
|
|
|
@@ -115,5 +97,4 @@ module.exports = {
|
|
|
115
97
|
trackRaspMetrics,
|
|
116
98
|
trackRaspRuleMatch,
|
|
117
99
|
trackRaspRuleSkipped,
|
|
118
|
-
incrementRaspDurationMetrics,
|
|
119
100
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
3
|
+
const { appsecMetrics } = require('./common')
|
|
6
4
|
|
|
7
5
|
function incrementMissingUserLogin (framework, eventType) {
|
|
8
6
|
appsecMetrics.count('instrum.user_auth.missing_user_login', {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { tags, getVersionsTags, DD_TELEMETRY_REQUEST_METRICS } = require('./common')
|
|
5
|
-
|
|
6
|
-
const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
3
|
+
const { appsecMetrics, tags, getVersionsTags, DD_TELEMETRY_REQUEST_METRICS } = require('./common')
|
|
7
4
|
|
|
8
5
|
const DD_TELEMETRY_WAF_RESULT_TAGS = Symbol('_dd.appsec.telemetry.waf.result.tags')
|
|
9
6
|
|
|
@@ -126,21 +123,6 @@ function incrementWafRequests (store) {
|
|
|
126
123
|
}
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
function incrementWafDurationMetrics (requestMetrics) {
|
|
130
|
-
const { duration, durationExt, wafVersion, rulesVersion } = requestMetrics
|
|
131
|
-
if (!duration && !durationExt) return
|
|
132
|
-
|
|
133
|
-
const versionsTags = getVersionsTags(wafVersion, rulesVersion)
|
|
134
|
-
|
|
135
|
-
if (duration) {
|
|
136
|
-
appsecMetrics.distribution('waf.duration', versionsTags).track(duration)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (durationExt) {
|
|
140
|
-
appsecMetrics.distribution('waf.duration_ext', versionsTags).track(durationExt)
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
126
|
function incrementTruncatedMetrics (metrics, truncationReason) {
|
|
145
127
|
const truncationTags = { truncation_reason: truncationReason }
|
|
146
128
|
appsecMetrics.count('waf.input_truncated', truncationTags).inc(1)
|
|
@@ -163,5 +145,4 @@ module.exports = {
|
|
|
163
145
|
incrementWafUpdates,
|
|
164
146
|
incrementWafConfigErrors,
|
|
165
147
|
incrementWafRequests,
|
|
166
|
-
incrementWafDurationMetrics,
|
|
167
148
|
}
|
|
@@ -25,7 +25,7 @@ let limiter = new Limiter(100)
|
|
|
25
25
|
let WAFManager = null
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* @typedef {import('./waf_manager').WAFManagerConfig & {
|
|
28
|
+
* @typedef {import('./waf_manager').WAFManagerConfig & { DD_APPSEC_TRACE_RATE_LIMIT: number }} WAFConfig
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
const waf = {
|
|
@@ -48,7 +48,7 @@ const waf = {
|
|
|
48
48
|
function init (rules, config) {
|
|
49
49
|
destroy()
|
|
50
50
|
|
|
51
|
-
limiter = new Limiter(config.
|
|
51
|
+
limiter = new Limiter(config.DD_APPSEC_TRACE_RATE_LIMIT)
|
|
52
52
|
|
|
53
53
|
// Lazy loading improves the startup time
|
|
54
54
|
WAFManager = require('./waf_manager')
|
|
@@ -8,9 +8,9 @@ const contexts = new WeakMap()
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @typedef {object} WAFManagerConfig
|
|
11
|
-
* @property {number}
|
|
12
|
-
* @property {string}
|
|
13
|
-
* @property {string}
|
|
11
|
+
* @property {number} DD_APPSEC_WAF_TIMEOUT - Maximum time in microseconds for WAF execution
|
|
12
|
+
* @property {string} DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP - Regex to redact sensitive data by key
|
|
13
|
+
* @property {string} DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP - Regex to redact sensitive data by value
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
class WAFManager {
|
|
@@ -22,7 +22,7 @@ class WAFManager {
|
|
|
22
22
|
*/
|
|
23
23
|
constructor (rules, config) {
|
|
24
24
|
this.config = config
|
|
25
|
-
this.wafTimeout = config.
|
|
25
|
+
this.wafTimeout = config.DD_APPSEC_WAF_TIMEOUT
|
|
26
26
|
this.ddwaf = this._loadDDWAF(rules)
|
|
27
27
|
this.rulesVersion = this.ddwaf.diagnostics.ruleset_version
|
|
28
28
|
this.defaultRules = rules
|
|
@@ -36,7 +36,10 @@ class WAFManager {
|
|
|
36
36
|
const { DDWAF } = require('@datadog/native-appsec')
|
|
37
37
|
this.ddwafVersion = DDWAF.version()
|
|
38
38
|
|
|
39
|
-
const {
|
|
39
|
+
const {
|
|
40
|
+
DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP: obfuscatorKeyRegex,
|
|
41
|
+
DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP: obfuscatorValueRegex,
|
|
42
|
+
} = this.config
|
|
40
43
|
return new DDWAF(rules, WAFManager.defaultWafConfigPath, { obfuscatorKeyRegex, obfuscatorValueRegex })
|
|
41
44
|
} catch (err) {
|
|
42
45
|
this.ddwafVersion ||= 'unknown'
|
|
@@ -81,7 +81,6 @@ function defineField (fieldName, headerName, read, operations) {
|
|
|
81
81
|
/**
|
|
82
82
|
* @param {Carrier} carrier
|
|
83
83
|
* @param {Value} value
|
|
84
|
-
* @returns {void}
|
|
85
84
|
*/
|
|
86
85
|
write (carrier, value) {
|
|
87
86
|
carrier[headerName] = value
|
|
@@ -89,7 +88,6 @@ function defineField (fieldName, headerName, read, operations) {
|
|
|
89
88
|
|
|
90
89
|
/**
|
|
91
90
|
* @param {Carrier} carrier
|
|
92
|
-
* @returns {boolean}
|
|
93
91
|
*/
|
|
94
92
|
has (carrier) {
|
|
95
93
|
return headerName in carrier
|
|
@@ -97,7 +95,6 @@ function defineField (fieldName, headerName, read, operations) {
|
|
|
97
95
|
|
|
98
96
|
/**
|
|
99
97
|
* @param {Carrier} carrier
|
|
100
|
-
* @returns {void}
|
|
101
98
|
*/
|
|
102
99
|
delete (carrier) {
|
|
103
100
|
delete carrier[headerName]
|
|
@@ -106,7 +103,6 @@ function defineField (fieldName, headerName, read, operations) {
|
|
|
106
103
|
/**
|
|
107
104
|
* @param {Carrier} carrier
|
|
108
105
|
* @param {Carrier} target
|
|
109
|
-
* @returns {void}
|
|
110
106
|
*/
|
|
111
107
|
copy (carrier, target) {
|
|
112
108
|
if (Object.hasOwn(carrier, headerName)) target[headerName] = carrier[headerName]
|
|
@@ -308,7 +304,6 @@ defineCapability('legacyBaggage', FIELD_READ | FIELD_WRITE, {
|
|
|
308
304
|
/**
|
|
309
305
|
* @param {Carrier} carrier
|
|
310
306
|
* @param {Record<string, string>} target
|
|
311
|
-
* @returns {void}
|
|
312
307
|
*/
|
|
313
308
|
read (carrier, target) {
|
|
314
309
|
for (const name of Object.keys(carrier)) {
|