dd-trace 5.53.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.
- package/LICENSE-3rdparty.csv +2 -1
- package/index.d.ts +33 -16
- package/initialize.mjs +3 -4
- package/package.json +36 -34
- package/packages/datadog-core/src/utils/src/get.js +1 -1
- package/packages/datadog-core/src/utils/src/has.js +1 -1
- package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
- package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
- package/packages/datadog-core/src/utils/src/pick.js +2 -2
- package/packages/datadog-core/src/utils/src/set.js +1 -1
- package/packages/datadog-core/src/utils/src/uniq.js +1 -1
- package/packages/datadog-instrumentations/src/amqp10.js +19 -17
- package/packages/datadog-instrumentations/src/amqplib.js +52 -35
- package/packages/datadog-instrumentations/src/apollo.js +2 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -4
- package/packages/datadog-instrumentations/src/child_process.js +1 -2
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +88 -73
- package/packages/datadog-instrumentations/src/couchbase.js +3 -3
- package/packages/datadog-instrumentations/src/cucumber.js +87 -40
- package/packages/datadog-instrumentations/src/cypress.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +1 -1
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +28 -34
- package/packages/datadog-instrumentations/src/graphql.js +7 -10
- package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
- package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
- package/packages/datadog-instrumentations/src/helpers/register.js +5 -7
- package/packages/datadog-instrumentations/src/http/client.js +14 -20
- package/packages/datadog-instrumentations/src/jest.js +137 -48
- package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
- package/packages/datadog-instrumentations/src/knex.js +4 -4
- package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
- package/packages/datadog-instrumentations/src/mariadb.js +38 -61
- package/packages/datadog-instrumentations/src/mocha/main.js +63 -24
- package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
- package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +20 -36
- package/packages/datadog-instrumentations/src/mysql2.js +53 -47
- package/packages/datadog-instrumentations/src/net.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +1 -0
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +21 -23
- package/packages/datadog-instrumentations/src/oracledb.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +1 -2
- package/packages/datadog-instrumentations/src/playwright.js +112 -69
- package/packages/datadog-instrumentations/src/redis.js +3 -3
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/rhea.js +42 -54
- package/packages/datadog-instrumentations/src/router.js +22 -25
- package/packages/datadog-instrumentations/src/tedious.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +77 -28
- package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/client.js +6 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/util.js +1 -1
- package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +24 -31
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +6 -6
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +4 -5
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
- package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
- package/packages/datadog-plugin-child_process/src/index.js +4 -4
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
- package/packages/datadog-plugin-cucumber/src/index.js +57 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +97 -27
- package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
- package/packages/datadog-plugin-cypress/src/support.js +24 -5
- package/packages/datadog-plugin-express/src/code_origin.js +30 -0
- package/packages/datadog-plugin-express/src/index.js +10 -12
- package/packages/datadog-plugin-express/src/tracing.js +19 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +26 -9
- package/packages/datadog-plugin-graphql/src/execute.js +2 -2
- package/packages/datadog-plugin-graphql/src/index.js +7 -6
- package/packages/datadog-plugin-graphql/src/resolve.js +2 -2
- package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/util.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +18 -7
- package/packages/datadog-plugin-http2/src/client.js +20 -20
- package/packages/datadog-plugin-jest/src/index.js +23 -21
- package/packages/datadog-plugin-jest/src/util.js +8 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
- package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
- package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
- package/packages/datadog-plugin-mariadb/src/index.js +3 -9
- package/packages/datadog-plugin-mocha/src/index.js +33 -13
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +11 -9
- package/packages/datadog-plugin-mysql2/src/index.js +16 -0
- package/packages/datadog-plugin-net/src/tcp.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +6 -5
- package/packages/datadog-plugin-openai/src/services.js +6 -10
- package/packages/datadog-plugin-openai/src/tracing.js +10 -14
- package/packages/datadog-plugin-oracledb/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +22 -2
- package/packages/datadog-plugin-redis/src/index.js +1 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
- package/packages/datadog-plugin-rhea/src/producer.js +5 -2
- package/packages/datadog-plugin-router/src/index.js +1 -1
- package/packages/datadog-plugin-selenium/src/index.js +1 -6
- package/packages/datadog-plugin-vitest/src/index.js +47 -31
- package/packages/datadog-shimmer/src/shimmer.js +4 -8
- package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
- package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +6 -20
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +4 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +4 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/index.js +1 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
- package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +6 -13
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +6 -6
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -24
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
- package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
- package/packages/dd-trace/src/appsec/reporter.js +233 -40
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
- package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
- package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
- package/packages/dd-trace/src/azure_metadata.js +2 -7
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +8 -5
- package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/config.js +82 -51
- package/packages/dd-trace/src/config_stable.js +3 -3
- package/packages/dd-trace/src/datastreams/encoding.js +9 -9
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +4 -4
- package/packages/dd-trace/src/datastreams/processor.js +5 -7
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
- package/packages/dd-trace/src/datastreams/size.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +74 -67
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +6 -8
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +7 -1
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +8 -10
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
- package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
- package/packages/dd-trace/src/dogstatsd.js +5 -4
- package/packages/dd-trace/src/encode/0.4.js +9 -9
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +3 -3
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +1 -1
- package/packages/dd-trace/src/exporter.js +6 -6
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
- package/packages/dd-trace/src/exporters/common/docker.js +1 -1
- package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +1 -1
- package/packages/dd-trace/src/external-logger/src/index.js +5 -5
- package/packages/dd-trace/src/flare/file.js +1 -5
- package/packages/dd-trace/src/format.js +1 -1
- package/packages/dd-trace/src/git_properties.js +1 -1
- package/packages/dd-trace/src/id.js +12 -6
- package/packages/dd-trace/src/iitm.js +10 -22
- package/packages/dd-trace/src/lambda/handler.js +6 -6
- package/packages/dd-trace/src/lambda/runtime/patch.js +4 -4
- package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +2 -2
- package/packages/dd-trace/src/llmobs/tagger.js +110 -96
- package/packages/dd-trace/src/llmobs/util.js +9 -9
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
- package/packages/dd-trace/src/log/index.js +4 -4
- package/packages/dd-trace/src/log/log.js +1 -1
- package/packages/dd-trace/src/log/writer.js +2 -2
- package/packages/dd-trace/src/msgpack/chunk.js +3 -3
- package/packages/dd-trace/src/msgpack/encoder.js +28 -28
- package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
- package/packages/dd-trace/src/noop/span.js +3 -5
- package/packages/dd-trace/src/noop/tracer.js +1 -2
- package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +6 -5
- package/packages/dd-trace/src/opentracing/propagation/log.js +6 -8
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +27 -23
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
- package/packages/dd-trace/src/opentracing/span.js +9 -14
- package/packages/dd-trace/src/opentracing/tracer.js +9 -6
- package/packages/dd-trace/src/payload-tagging/index.js +1 -1
- package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
- package/packages/dd-trace/src/pkg.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +62 -10
- package/packages/dd-trace/src/plugins/consumer.js +2 -2
- package/packages/dd-trace/src/plugins/inbound.js +5 -1
- package/packages/dd-trace/src/plugins/index.js +0 -1
- package/packages/dd-trace/src/plugins/outbound.js +4 -5
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/producer.js +2 -2
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/util/ci.js +23 -15
- package/packages/dd-trace/src/plugins/util/git.js +165 -11
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +27 -10
- package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +311 -48
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +12 -3
- package/packages/dd-trace/src/plugins/util/web.js +5 -4
- package/packages/dd-trace/src/priority_sampler.js +22 -22
- package/packages/dd-trace/src/profiling/config.js +44 -8
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +37 -2
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
- package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
- package/packages/dd-trace/src/profiling/tagger.js +3 -5
- package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
- package/packages/dd-trace/src/proxy.js +7 -9
- package/packages/dd-trace/src/random_sampler.js +40 -0
- package/packages/dd-trace/src/rate_limiter.js +4 -4
- package/packages/dd-trace/src/remote_config/index.js +3 -7
- package/packages/dd-trace/src/remote_config/manager.js +25 -13
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/ritm.js +4 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/sampler.js +33 -4
- package/packages/dd-trace/src/sampling_rule.js +12 -3
- package/packages/dd-trace/src/scope.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
- package/packages/dd-trace/src/span_processor.js +3 -3
- package/packages/dd-trace/src/span_sampler.js +4 -1
- package/packages/dd-trace/src/standalone/tracesource.js +1 -1
- package/packages/dd-trace/src/startup-log.js +2 -2
- package/packages/dd-trace/src/telemetry/dependencies.js +4 -4
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
- package/packages/dd-trace/src/telemetry/metrics.js +10 -5
- package/packages/dd-trace/src/telemetry/send-data.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +23 -24
- package/packages/dd-trace/src/util.js +1 -1
- package/version.js +1 -0
- package/packages/datadog-instrumentations/src/paperplane.js +0 -77
- package/packages/datadog-plugin-paperplane/src/index.js +0 -25
- package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
- package/packages/datadog-plugin-paperplane/src/server.js +0 -24
|
@@ -93,11 +93,9 @@ function getBlockWithContentData (req, specificType, actionParameters) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
function getBlockingData (req, specificType, actionParameters) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
144
|
-
templateHtml = config.appsec.blockedTemplateHtml
|
|
145
|
-
} else {
|
|
146
|
-
templateHtml = blockedTemplates.html
|
|
147
|
-
}
|
|
141
|
+
templateHtml = config.appsec.blockedTemplateHtml || blockedTemplates.html
|
|
148
142
|
|
|
149
|
-
|
|
150
|
-
templateJson = config.appsec.blockedTemplateJson
|
|
151
|
-
} else {
|
|
152
|
-
templateJson = blockedTemplates.json
|
|
153
|
-
}
|
|
143
|
+
templateJson = config.appsec.blockedTemplateJson || blockedTemplates.json
|
|
154
144
|
|
|
155
|
-
|
|
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) {
|
|
@@ -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 (
|
|
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.
|
|
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
|
|
24
|
+
if (!headerValue?.startsWith(HEADER_VALID_PREFIX)) {
|
|
28
25
|
return false
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
const semicolonIndex = headerValue.indexOf(';')
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
23
|
+
String.raw`node:internal\fs`,
|
|
24
24
|
'fs.js',
|
|
25
25
|
'internal/fs',
|
|
26
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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.
|
|
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
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const LRUCache = require('lru-cache')
|
|
4
|
+
const web = require('../../plugins/util/web')
|
|
5
|
+
const vulnerabilities = require('./vulnerabilities')
|
|
6
|
+
|
|
3
7
|
const OVERHEAD_CONTROLLER_CONTEXT_KEY = 'oce'
|
|
4
8
|
const REPORT_VULNERABILITY = 'REPORT_VULNERABILITY'
|
|
5
9
|
const INTERVAL_RESET_GLOBAL_CONTEXT = 60 * 1000
|
|
@@ -9,13 +13,62 @@ const GLOBAL_OCE_CONTEXT = {}
|
|
|
9
13
|
let resetGlobalContextInterval
|
|
10
14
|
let config = {}
|
|
11
15
|
let availableRequest = 0
|
|
16
|
+
|
|
17
|
+
const globalRouteMap = new LRUCache({ max: 4096 })
|
|
18
|
+
let vulnerabilitiesSize = 0
|
|
19
|
+
const vulnerabilityIndexes = Object.values(vulnerabilities).reduce((obj, item, index) => {
|
|
20
|
+
obj[item] = index
|
|
21
|
+
vulnerabilitiesSize++
|
|
22
|
+
return obj
|
|
23
|
+
}, {})
|
|
24
|
+
|
|
25
|
+
function newCountersArray () {
|
|
26
|
+
return (new Array(vulnerabilitiesSize)).fill(0)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function copyFromGlobalMap (route) {
|
|
30
|
+
const vulnerabilityCounters = globalRouteMap.get(route)
|
|
31
|
+
return vulnerabilityCounters ? [...vulnerabilityCounters] : newCountersArray()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// for testing purposes
|
|
35
|
+
function clearGlobalRouteMap () {
|
|
36
|
+
globalRouteMap.clear()
|
|
37
|
+
}
|
|
38
|
+
|
|
12
39
|
const OPERATIONS = {
|
|
13
40
|
REPORT_VULNERABILITY: {
|
|
14
|
-
hasQuota: (context) => {
|
|
15
|
-
const reserved = context
|
|
41
|
+
hasQuota: (context, vulnerabilityType) => {
|
|
42
|
+
const reserved = context?.tokens?.[REPORT_VULNERABILITY] > 0
|
|
43
|
+
if (reserved && context.route != null) {
|
|
44
|
+
let copyMap = context.copyMap
|
|
45
|
+
let localMap = context.localMap
|
|
46
|
+
|
|
47
|
+
if (context.loadedRoute !== context.route) {
|
|
48
|
+
context.copyMaps ??= {}
|
|
49
|
+
context.copyMaps[context.route] ??= copyFromGlobalMap(context.route)
|
|
50
|
+
context.localMaps ??= {}
|
|
51
|
+
context.localMaps[context.route] ??= newCountersArray()
|
|
52
|
+
context.loadedRoute = context.route
|
|
53
|
+
copyMap = context.copyMaps[context.route]
|
|
54
|
+
localMap = context.localMaps[context.route]
|
|
55
|
+
context.copyMap = copyMap
|
|
56
|
+
context.localMap = localMap
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const vulnerabilityIndex = vulnerabilityIndexes[vulnerabilityType]
|
|
60
|
+
const counter = localMap[vulnerabilityIndex]++
|
|
61
|
+
const storedCounter = copyMap[vulnerabilityIndex]
|
|
62
|
+
|
|
63
|
+
if (counter < storedCounter) {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
16
68
|
if (reserved) {
|
|
17
69
|
context.tokens[REPORT_VULNERABILITY]--
|
|
18
70
|
}
|
|
71
|
+
|
|
19
72
|
return reserved
|
|
20
73
|
},
|
|
21
74
|
name: REPORT_VULNERABILITY,
|
|
@@ -41,12 +94,52 @@ function _getNewContext () {
|
|
|
41
94
|
}
|
|
42
95
|
|
|
43
96
|
function _getContext (iastContext) {
|
|
44
|
-
if (iastContext
|
|
97
|
+
if (iastContext?.[OVERHEAD_CONTROLLER_CONTEXT_KEY]) {
|
|
98
|
+
const oceContext = iastContext[OVERHEAD_CONTROLLER_CONTEXT_KEY]
|
|
99
|
+
if (!oceContext.webContext) {
|
|
100
|
+
oceContext.webContext = web.getContext(iastContext.req)
|
|
101
|
+
oceContext.method = iastContext.req?.method
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const currentPaths = oceContext.webContext?.paths
|
|
105
|
+
if (currentPaths !== oceContext.paths || !oceContext.route) {
|
|
106
|
+
oceContext.paths = currentPaths
|
|
107
|
+
oceContext.route = '#' + oceContext.method + '#' + (currentPaths?.join('') || '')
|
|
108
|
+
}
|
|
109
|
+
|
|
45
110
|
return iastContext[OVERHEAD_CONTROLLER_CONTEXT_KEY]
|
|
46
111
|
}
|
|
47
112
|
return GLOBAL_OCE_CONTEXT
|
|
48
113
|
}
|
|
49
114
|
|
|
115
|
+
function consolidateVulnerabilities (iastContext) {
|
|
116
|
+
const context = _getContext(iastContext)
|
|
117
|
+
if (!context.localMaps) return
|
|
118
|
+
|
|
119
|
+
const reserved = context.tokens?.[REPORT_VULNERABILITY] > 0
|
|
120
|
+
|
|
121
|
+
if (reserved) { // still a bit of budget available
|
|
122
|
+
Object.keys(context.localMaps).forEach(route => {
|
|
123
|
+
globalRouteMap.set(route, newCountersArray())
|
|
124
|
+
})
|
|
125
|
+
} else {
|
|
126
|
+
Object.keys(context.localMaps).forEach(route => {
|
|
127
|
+
const localMap = context.localMaps[route]
|
|
128
|
+
const globalMap = globalRouteMap.get(route)
|
|
129
|
+
if (!globalMap) {
|
|
130
|
+
globalRouteMap.set(route, localMap)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for (let i = 0; i < vulnerabilitiesSize; i++) {
|
|
135
|
+
if (localMap[i] > globalMap[i]) {
|
|
136
|
+
globalMap[i] = localMap[i]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
50
143
|
function _resetGlobalContext () {
|
|
51
144
|
Object.assign(GLOBAL_OCE_CONTEXT, _getNewContext())
|
|
52
145
|
}
|
|
@@ -70,9 +163,9 @@ function releaseRequest () {
|
|
|
70
163
|
}
|
|
71
164
|
}
|
|
72
165
|
|
|
73
|
-
function hasQuota (operation, iastContext) {
|
|
166
|
+
function hasQuota (operation, iastContext, vulnerabilityType) {
|
|
74
167
|
const oceContext = _getContext(iastContext)
|
|
75
|
-
return operation.hasQuota(oceContext)
|
|
168
|
+
return operation.hasQuota(oceContext, vulnerabilityType)
|
|
76
169
|
}
|
|
77
170
|
|
|
78
171
|
function initializeRequestContext (iastContext) {
|
|
@@ -90,7 +183,7 @@ function startGlobalContext () {
|
|
|
90
183
|
resetGlobalContextInterval = setInterval(() => {
|
|
91
184
|
_resetGlobalContext()
|
|
92
185
|
}, INTERVAL_RESET_GLOBAL_CONTEXT)
|
|
93
|
-
resetGlobalContextInterval.unref
|
|
186
|
+
resetGlobalContextInterval.unref?.()
|
|
94
187
|
}
|
|
95
188
|
|
|
96
189
|
function finishGlobalContext () {
|
|
@@ -110,5 +203,7 @@ module.exports = {
|
|
|
110
203
|
hasQuota,
|
|
111
204
|
acquireRequest,
|
|
112
205
|
releaseRequest,
|
|
113
|
-
configure
|
|
206
|
+
configure,
|
|
207
|
+
consolidateVulnerabilities,
|
|
208
|
+
clearGlobalRouteMap
|
|
114
209
|
}
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const process = require('process')
|
|
5
|
-
const {
|
|
5
|
+
const { ddBasePath } = require('../../util')
|
|
6
6
|
const pathLine = {
|
|
7
7
|
getNodeModulesPaths,
|
|
8
8
|
getRelativePath,
|
|
9
9
|
getNonDDCallSiteFrames,
|
|
10
|
-
|
|
11
|
-
ddBasePath: calculateDDBasePath(__dirname) // Only for test purposes
|
|
10
|
+
ddBasePath // Exported only for test purposes
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
const EXCLUDED_PATHS = [
|
|
@@ -32,7 +31,7 @@ function getNonDDCallSiteFrames (callSiteFrames, externallyExcludedPaths) {
|
|
|
32
31
|
|
|
33
32
|
for (const callsite of callSiteFrames) {
|
|
34
33
|
const filepath = callsite.file
|
|
35
|
-
if (!isExcluded(callsite, externallyExcludedPaths) && filepath.
|
|
34
|
+
if (!isExcluded(callsite, externallyExcludedPaths) && !filepath.includes(pathLine.ddBasePath)) {
|
|
36
35
|
callsite.path = getRelativePath(filepath)
|
|
37
36
|
callsite.isInternal = !path.isAbsolute(filepath)
|
|
38
37
|
|
|
@@ -58,14 +57,14 @@ function isExcluded (callsite, externallyExcludedPaths) {
|
|
|
58
57
|
excludedPaths = [...excludedPaths, ...externallyExcludedPaths]
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
for (
|
|
62
|
-
if (filename.
|
|
60
|
+
for (const excludedPath of excludedPaths) {
|
|
61
|
+
if (filename.includes(excludedPath)) {
|
|
63
62
|
return true
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
for (
|
|
68
|
-
if (filename.indexOf(
|
|
66
|
+
for (const EXCLUDED_PATH_PREFIX of EXCLUDED_PATH_PREFIXES) {
|
|
67
|
+
if (filename.indexOf(EXCLUDED_PATH_PREFIX) === 0) {
|
|
69
68
|
return true
|
|
70
69
|
}
|
|
71
70
|
}
|
|
@@ -52,7 +52,7 @@ function onModuleLoaded (payload) {
|
|
|
52
52
|
|
|
53
53
|
function getControls (filename) {
|
|
54
54
|
if (filename.startsWith('file://')) {
|
|
55
|
-
filename = filename.
|
|
55
|
+
filename = filename.slice(7)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
let key = path.isAbsolute(filename) ? path.relative(process.cwd(), filename) : filename
|
|
@@ -74,12 +74,9 @@ function hookModule (filename, module, controlsByFile) {
|
|
|
74
74
|
return
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} else {
|
|
81
|
-
wrapper = wrapInputValidator(target, parameters, secureMarks)
|
|
82
|
-
}
|
|
77
|
+
const wrapper = type === SANITIZER_TYPE
|
|
78
|
+
? wrapSanitizer(target, secureMarks)
|
|
79
|
+
: wrapInputValidator(target, parameters, secureMarks)
|
|
83
80
|
|
|
84
81
|
if (methodName) {
|
|
85
82
|
parent[methodName] = wrapper
|
|
@@ -97,11 +94,7 @@ function hookModule (filename, module, controlsByFile) {
|
|
|
97
94
|
function resolve (path, obj, separator = '.') {
|
|
98
95
|
if (!path) {
|
|
99
96
|
// esm module with default export
|
|
100
|
-
|
|
101
|
-
return { target: obj.default, parent: obj, methodName: 'default' }
|
|
102
|
-
} else {
|
|
103
|
-
return { target: obj, parent: obj }
|
|
104
|
-
}
|
|
97
|
+
return obj?.default ? { target: obj.default, parent: obj, methodName: 'default' } : { target: obj, parent: obj }
|
|
105
98
|
}
|
|
106
99
|
|
|
107
100
|
const properties = path.split(separator)
|
|
@@ -164,7 +157,7 @@ function addSecureMarks (value, secureMarks, createNewTainted = true) {
|
|
|
164
157
|
if (createNewTainted) {
|
|
165
158
|
parent[lastKey] = securedTainted
|
|
166
159
|
}
|
|
167
|
-
} catch
|
|
160
|
+
} catch {
|
|
168
161
|
// if it is a readonly property, do nothing
|
|
169
162
|
}
|
|
170
163
|
})
|
|
@@ -10,7 +10,7 @@ const SECURITY_CONTROL_ELEMENT_DELIMITER = ','
|
|
|
10
10
|
const INPUT_VALIDATOR_TYPE = 'INPUT_VALIDATOR'
|
|
11
11
|
const SANITIZER_TYPE = 'SANITIZER'
|
|
12
12
|
|
|
13
|
-
const validTypes = [INPUT_VALIDATOR_TYPE, SANITIZER_TYPE]
|
|
13
|
+
const validTypes = new Set([INPUT_VALIDATOR_TYPE, SANITIZER_TYPE])
|
|
14
14
|
|
|
15
15
|
function parse (securityControlsConfiguration) {
|
|
16
16
|
const controls = new Map()
|
|
@@ -42,7 +42,7 @@ function parseControl (control) {
|
|
|
42
42
|
let [type, marks, file, method, parameters] = fields
|
|
43
43
|
|
|
44
44
|
type = type.trim().toUpperCase()
|
|
45
|
-
if (!validTypes.
|
|
45
|
+
if (!validTypes.has(type)) {
|
|
46
46
|
log.warn('[ASM] Invalid security control type: %s', type)
|
|
47
47
|
return
|
|
48
48
|
}
|
|
@@ -60,7 +60,7 @@ function parseControl (control) {
|
|
|
60
60
|
|
|
61
61
|
try {
|
|
62
62
|
parameters = getParameters(parameters)
|
|
63
|
-
} catch
|
|
63
|
+
} catch {
|
|
64
64
|
log.warn('[ASM] Invalid non-numeric security control parameter %s', parameters)
|
|
65
65
|
return
|
|
66
66
|
}
|
|
@@ -77,11 +77,11 @@ function getSecureMarks (marks) {
|
|
|
77
77
|
function getParameters (parameters) {
|
|
78
78
|
return parameters?.split(SECURITY_CONTROL_ELEMENT_DELIMITER)
|
|
79
79
|
.map(param => {
|
|
80
|
-
const parsedParam = parseInt(param, 10)
|
|
80
|
+
const parsedParam = Number.parseInt(param, 10)
|
|
81
81
|
|
|
82
82
|
// discard the securityControl if there is an incorrect parameter
|
|
83
|
-
if (isNaN(parsedParam)) {
|
|
84
|
-
throw new
|
|
83
|
+
if (Number.isNaN(parsedParam)) {
|
|
84
|
+
throw new TypeError('Invalid non-numeric security control parameter')
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
return parsedParam
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
const NODE_MODULES = 'node_modules'
|
|
4
4
|
|
|
5
5
|
const isPrivateModule = function (file) {
|
|
6
|
-
return file && file.
|
|
6
|
+
return file && !file.includes(NODE_MODULES)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const isDdTrace = function (file) {
|
|
10
|
-
return
|
|
10
|
+
return Boolean(file?.includes('dd-trace'))
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
module.exports = {
|
|
@@ -20,10 +20,10 @@ function taintObject (iastContext, object, type) {
|
|
|
20
20
|
try {
|
|
21
21
|
if (typeof value === 'string') {
|
|
22
22
|
const tainted = TaintedUtils.newTaintedString(transactionId, value, property, type)
|
|
23
|
-
if (
|
|
24
|
-
result = tainted
|
|
25
|
-
} else {
|
|
23
|
+
if (parent) {
|
|
26
24
|
parent[key] = tainted
|
|
25
|
+
} else {
|
|
26
|
+
result = tainted
|
|
27
27
|
}
|
|
28
28
|
} else if (typeof value === 'object' && !visited.has(value)) {
|
|
29
29
|
visited.add(value)
|