dd-trace 5.54.0 → 5.56.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 +1 -0
- package/ci/cypress/plugin.js +8 -0
- package/ci/cypress/polyfills.js +23 -0
- package/ci/init.js +8 -7
- package/initialize.mjs +2 -2
- package/package.json +10 -9
- package/packages/datadog-code-origin/index.js +22 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
- package/packages/datadog-core/src/utils/src/set.js +8 -10
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -6
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +2 -3
- package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
- package/packages/datadog-instrumentations/src/couchbase.js +3 -6
- package/packages/datadog-instrumentations/src/cucumber.js +21 -28
- package/packages/datadog-instrumentations/src/dns.js +4 -4
- package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
- package/packages/datadog-instrumentations/src/fastify.js +7 -9
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +14 -16
- package/packages/datadog-instrumentations/src/hapi.js +10 -11
- package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -5
- package/packages/datadog-instrumentations/src/jest.js +421 -376
- package/packages/datadog-instrumentations/src/koa.js +2 -3
- package/packages/datadog-instrumentations/src/mariadb.js +11 -4
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -75
- package/packages/datadog-instrumentations/src/mocha.js +3 -1
- package/packages/datadog-instrumentations/src/mysql.js +11 -2
- package/packages/datadog-instrumentations/src/nyc.js +2 -1
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
- package/packages/datadog-instrumentations/src/pg.js +2 -3
- package/packages/datadog-instrumentations/src/playwright.js +19 -22
- package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
- package/packages/datadog-instrumentations/src/redis.js +1 -1
- package/packages/datadog-instrumentations/src/restify.js +9 -13
- package/packages/datadog-instrumentations/src/router.js +12 -11
- package/packages/datadog-instrumentations/src/tedious.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +15 -29
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -8
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +12 -20
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -5
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -10
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -4
- package/packages/datadog-plugin-cucumber/src/index.js +3 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -1
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +1 -1
- package/packages/datadog-plugin-graphql/src/index.js +3 -2
- package/packages/datadog-plugin-graphql/src/resolve.js +17 -10
- package/packages/datadog-plugin-http/src/client.js +5 -6
- package/packages/datadog-plugin-http2/src/client.js +7 -8
- package/packages/datadog-plugin-jest/src/index.js +3 -2
- package/packages/datadog-plugin-mocha/src/index.js +6 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
- package/packages/datadog-plugin-mysql/src/index.js +11 -0
- package/packages/datadog-plugin-next/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +2 -4
- package/packages/datadog-plugin-oracledb/src/index.js +2 -1
- package/packages/datadog-plugin-playwright/src/index.js +3 -2
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
- package/packages/datadog-plugin-redis/src/index.js +1 -3
- package/packages/datadog-plugin-vitest/src/index.js +5 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +1 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +12 -13
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +44 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +8 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +0 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
- package/packages/dd-trace/src/appsec/index.js +16 -5
- package/packages/dd-trace/src/appsec/reporter.js +11 -11
- package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
- package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -2
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +2 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +8 -7
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +4 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -3
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -1
- package/packages/dd-trace/src/config-helper.js +89 -0
- package/packages/dd-trace/src/config.js +120 -115
- package/packages/dd-trace/src/config_stable.js +7 -4
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +6 -6
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +5 -1
- package/packages/dd-trace/src/debugger/index.js +1 -0
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +5 -2
- package/packages/dd-trace/src/encode/0.5.js +3 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -5
- package/packages/dd-trace/src/exporter.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -1
- package/packages/dd-trace/src/exporters/common/docker.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +4 -1
- package/packages/dd-trace/src/exporters/common/util.js +3 -1
- package/packages/dd-trace/src/id.js +3 -3
- package/packages/dd-trace/src/index.js +4 -3
- package/packages/dd-trace/src/lambda/handler.js +2 -1
- package/packages/dd-trace/src/lambda/index.js +2 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +3 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/index.js +21 -5
- package/packages/dd-trace/src/llmobs/noop.js +18 -20
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -2
- package/packages/dd-trace/src/llmobs/sdk.js +2 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +19 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/log/index.js +5 -4
- package/packages/dd-trace/src/log/writer.js +1 -2
- package/packages/dd-trace/src/msgpack/encoder.js +3 -3
- package/packages/dd-trace/src/noop/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +4 -5
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +35 -42
- package/packages/dd-trace/src/opentracing/span.js +7 -6
- package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +25 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +7 -7
- package/packages/dd-trace/src/plugins/util/git.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/stacktrace.js +8 -1
- package/packages/dd-trace/src/plugins/util/test.js +4 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +3 -4
- package/packages/dd-trace/src/priority_sampler.js +46 -35
- package/packages/dd-trace/src/profiling/config.js +12 -32
- package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -1
- package/packages/dd-trace/src/profiling/index.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +7 -4
- package/packages/dd-trace/src/profiling/profilers/events.js +10 -2
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
- package/packages/dd-trace/src/profiling/tagger.js +22 -12
- package/packages/dd-trace/src/proxy.js +2 -1
- package/packages/dd-trace/src/ritm.js +4 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -2
- package/packages/dd-trace/src/sampler.js +10 -2
- package/packages/dd-trace/src/serverless.js +11 -4
- package/packages/dd-trace/src/span_processor.js +2 -1
- package/packages/dd-trace/src/standalone/tracesource.js +1 -2
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
- package/packages/dd-trace/src/startup-log.js +5 -17
- package/packages/dd-trace/src/supported-configurations.json +440 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +62 -57
- package/packages/dd-trace/src/telemetry/send-data.js +7 -6
- package/packages/dd-trace/src/telemetry/telemetry.js +16 -26
- package/packages/dd-trace/src/tracer.js +3 -7
- package/packages/dd-trace/src/util.js +0 -5
- package/packages/datadog-core/src/utils/src/get.js +0 -11
- package/packages/datadog-core/src/utils/src/has.js +0 -14
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -120
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
|
@@ -124,9 +124,9 @@ function extractSessionDetails (authority, options) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const protocol = authority.protocol || options.protocol || 'https:'
|
|
127
|
-
let port =
|
|
128
|
-
?
|
|
129
|
-
: authority.port)
|
|
127
|
+
let port = authority.port === ''
|
|
128
|
+
? authority.protocol === 'http:' ? '80' : '443'
|
|
129
|
+
: String(authority.port)
|
|
130
130
|
let host = authority.hostname || authority.host || 'localhost'
|
|
131
131
|
|
|
132
132
|
if (protocol === 'https:' && options) {
|
|
@@ -174,17 +174,16 @@ function normalizeConfig (config) {
|
|
|
174
174
|
const filter = getFilter(config)
|
|
175
175
|
const headers = getHeaders(config)
|
|
176
176
|
|
|
177
|
-
return
|
|
177
|
+
return {
|
|
178
|
+
...config,
|
|
178
179
|
validateStatus,
|
|
179
180
|
filter,
|
|
180
181
|
headers
|
|
181
|
-
}
|
|
182
|
+
}
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
function getFilter (config) {
|
|
185
|
-
config =
|
|
186
|
-
blocklist: config.blocklist || []
|
|
187
|
-
})
|
|
186
|
+
config = { ...config, blocklist: config.blocklist || [] }
|
|
188
187
|
|
|
189
188
|
return urlFilter.getFilter(config)
|
|
190
189
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
2
2
|
const { storage } = require('../../datadog-core')
|
|
3
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
3
4
|
|
|
4
5
|
const {
|
|
5
6
|
TEST_STATUS,
|
|
@@ -48,7 +49,7 @@ const {
|
|
|
48
49
|
TELEMETRY_TEST_SESSION
|
|
49
50
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
50
51
|
|
|
51
|
-
const isJestWorker = !!
|
|
52
|
+
const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
|
|
52
53
|
|
|
53
54
|
// https://github.com/facebook/jest/blob/d6ad15b0f88a05816c2fe034dd6900d28315d570/packages/jest-worker/src/types.ts#L38
|
|
54
55
|
const CHILD_MESSAGE_END = 2
|
|
@@ -158,7 +159,7 @@ class JestPlugin extends CiPlugin {
|
|
|
158
159
|
|
|
159
160
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
160
161
|
provider: this.ciProviderName,
|
|
161
|
-
autoInjected: !!
|
|
162
|
+
autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
|
|
162
163
|
})
|
|
163
164
|
|
|
164
165
|
this.tracer._exporter.flush(() => {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
5
6
|
|
|
6
7
|
const {
|
|
7
8
|
TEST_STATUS,
|
|
@@ -429,7 +430,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
429
430
|
finishAllTraceSpans(this.testSessionSpan)
|
|
430
431
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
431
432
|
provider: this.ciProviderName,
|
|
432
|
-
autoInjected: !!
|
|
433
|
+
autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
|
|
433
434
|
})
|
|
434
435
|
}
|
|
435
436
|
this.libraryConfig = null
|
|
@@ -466,6 +467,10 @@ class MochaPlugin extends CiPlugin {
|
|
|
466
467
|
this.tracer._exporter.export(trace)
|
|
467
468
|
})
|
|
468
469
|
})
|
|
470
|
+
|
|
471
|
+
this.addBind('ci:mocha:global:run', (ctx) => {
|
|
472
|
+
return ctx.currentStore
|
|
473
|
+
})
|
|
469
474
|
}
|
|
470
475
|
|
|
471
476
|
startTestSpan (testInfo) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { isTrue } = require('../../dd-trace/src/util')
|
|
4
4
|
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
5
5
|
const coalesce = require('koalas')
|
|
6
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
6
7
|
|
|
7
8
|
class MongodbCorePlugin extends DatabasePlugin {
|
|
8
9
|
static get id () { return 'mongodb-core' }
|
|
@@ -14,7 +15,7 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
14
15
|
configure (config) {
|
|
15
16
|
super.configure(config)
|
|
16
17
|
|
|
17
|
-
const heartbeatFromEnv =
|
|
18
|
+
const heartbeatFromEnv = getEnvironmentVariable('DD_TRACE_MONGODB_HEARTBEAT_ENABLED')
|
|
18
19
|
|
|
19
20
|
this.config.heartbeatEnabled = coalesce(
|
|
20
21
|
config.heartbeatEnabled,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { storage } = require('../../datadog-core')
|
|
3
4
|
const CLIENT_PORT_KEY = require('../../dd-trace/src/constants')
|
|
4
5
|
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
5
6
|
|
|
@@ -7,6 +8,16 @@ class MySQLPlugin extends DatabasePlugin {
|
|
|
7
8
|
static get id () { return 'mysql' }
|
|
8
9
|
static get system () { return 'mysql' }
|
|
9
10
|
|
|
11
|
+
constructor () {
|
|
12
|
+
super(...arguments)
|
|
13
|
+
|
|
14
|
+
this.addSub(`apm:${this.component}:connection:start`, ctx => {
|
|
15
|
+
ctx.parentStore = storage('legacy').getStore()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
this.addBind(`apm:${this.component}:connection:finish`, ctx => ctx.parentStore)
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
bindStart (ctx) {
|
|
11
22
|
const service = this.serviceName({ pluginConfig: this.config, dbConfig: ctx.conf, system: this.system })
|
|
12
23
|
const span = this.startSpan(this.operationName(), {
|
|
@@ -766,19 +766,17 @@ function usageExtraction (tags, body, methodName, openaiStore) {
|
|
|
766
766
|
} else if (body.model && ['chat.completions.create', 'completions.create'].includes(methodName)) {
|
|
767
767
|
// estimate tokens based on method name for completions and chat completions
|
|
768
768
|
const { model } = body
|
|
769
|
-
let promptEstimated = false
|
|
770
|
-
let completionEstimated = false
|
|
771
769
|
|
|
772
770
|
// prompt tokens
|
|
773
771
|
const payload = openaiStore
|
|
774
772
|
const promptTokensCount = countPromptTokens(methodName, payload, model)
|
|
775
773
|
promptTokens = promptTokensCount.promptTokens
|
|
776
|
-
promptEstimated = promptTokensCount.promptEstimated
|
|
774
|
+
const promptEstimated = promptTokensCount.promptEstimated
|
|
777
775
|
|
|
778
776
|
// completion tokens
|
|
779
777
|
const completionTokensCount = countCompletionTokens(body, model)
|
|
780
778
|
completionTokens = completionTokensCount.completionTokens
|
|
781
|
-
completionEstimated = completionTokensCount.completionEstimated
|
|
779
|
+
const completionEstimated = completionTokensCount.completionEstimated
|
|
782
780
|
|
|
783
781
|
// total tokens
|
|
784
782
|
totalTokens = promptTokens + completionTokens
|
|
@@ -11,7 +11,8 @@ class OracledbPlugin extends DatabasePlugin {
|
|
|
11
11
|
|
|
12
12
|
start ({ query, connAttrs }) {
|
|
13
13
|
const service = this.serviceName({ pluginConfig: this.config, params: connAttrs })
|
|
14
|
-
|
|
14
|
+
// Users can pass either connectString or connectionString
|
|
15
|
+
const url = getUrl(connAttrs.connectString || connAttrs.connectionString)
|
|
15
16
|
|
|
16
17
|
this.startSpan(this.operationName(), {
|
|
17
18
|
service,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { storage } = require('../../datadog-core')
|
|
4
4
|
const id = require('../../dd-trace/src/id')
|
|
5
5
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
6
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
6
7
|
|
|
7
8
|
const {
|
|
8
9
|
TEST_STATUS,
|
|
@@ -102,7 +103,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
102
103
|
finishAllTraceSpans(this.testSessionSpan)
|
|
103
104
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
104
105
|
provider: this.ciProviderName,
|
|
105
|
-
autoInjected: !!
|
|
106
|
+
autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
|
|
106
107
|
})
|
|
107
108
|
appClosingTelemetry()
|
|
108
109
|
this.tracer._exporter.flush(onDone)
|
|
@@ -384,7 +385,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
384
385
|
span.finish()
|
|
385
386
|
|
|
386
387
|
finishAllTraceSpans(span)
|
|
387
|
-
if (
|
|
388
|
+
if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) {
|
|
388
389
|
this.tracer._exporter.flush(onDone)
|
|
389
390
|
}
|
|
390
391
|
})
|
|
@@ -102,17 +102,16 @@ class SchemaExtractor {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
return true
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
105
|
+
}
|
|
106
|
+
if (!builder.shouldExtractSchema(schemaName, depth)) {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
for (const field of schema.fieldsArray) {
|
|
110
|
+
if (!this.extractProperty(field, schemaName, field.name, builder, depth)) {
|
|
111
|
+
log.warn(`DSM: Unable to extract field with name: ${field.name} from Avro schema with name: ${schemaName}`)
|
|
113
112
|
}
|
|
114
|
-
return true
|
|
115
113
|
}
|
|
114
|
+
return true
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
static extractSchemas (descriptor, dataStreamsProcessor) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
2
2
|
const { storage } = require('../../datadog-core')
|
|
3
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
3
4
|
|
|
4
5
|
const {
|
|
5
6
|
TEST_STATUS,
|
|
@@ -275,11 +276,11 @@ class VitestPlugin extends CiPlugin {
|
|
|
275
276
|
this.addBind('ci:vitest:test-suite:start', (ctx) => {
|
|
276
277
|
const { testSuiteAbsolutePath, frameworkVersion } = ctx
|
|
277
278
|
|
|
278
|
-
this.command =
|
|
279
|
+
this.command = getEnvironmentVariable('DD_CIVISIBILITY_TEST_COMMAND')
|
|
279
280
|
this.frameworkVersion = frameworkVersion
|
|
280
281
|
const testSessionSpanContext = this.tracer.extract('text_map', {
|
|
281
|
-
'x-datadog-trace-id':
|
|
282
|
-
'x-datadog-parent-id':
|
|
282
|
+
'x-datadog-trace-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_SESSION_ID'),
|
|
283
|
+
'x-datadog-parent-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_MODULE_ID')
|
|
283
284
|
})
|
|
284
285
|
|
|
285
286
|
const trimmedCommand = DD_MAJOR < 6 ? this.command : 'vitest run'
|
|
@@ -396,7 +397,7 @@ class VitestPlugin extends CiPlugin {
|
|
|
396
397
|
finishAllTraceSpans(this.testSessionSpan)
|
|
397
398
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
398
399
|
provider: this.ciProviderName,
|
|
399
|
-
autoInjected: !!
|
|
400
|
+
autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
|
|
400
401
|
})
|
|
401
402
|
this.tracer._exporter.flush(onFinish)
|
|
402
403
|
})
|
|
@@ -5,7 +5,6 @@ module.exports = {
|
|
|
5
5
|
COMMAND_INJECTION_ANALYZER: require('./command-injection-analyzer'),
|
|
6
6
|
HARCODED_PASSWORD_ANALYZER: require('./hardcoded-password-analyzer'),
|
|
7
7
|
HARCODED_SECRET_ANALYZER: require('./hardcoded-secret-analyzer'),
|
|
8
|
-
HEADER_INJECTION_ANALYZER: require('./header-injection-analyzer'),
|
|
9
8
|
HSTS_HEADER_MISSING_ANALYZER: require('./hsts-header-missing-analyzer'),
|
|
10
9
|
INSECURE_COOKIE_ANALYZER: require('./insecure-cookie-analyzer'),
|
|
11
10
|
LDAP_ANALYZER: require('./ldap-injection-analyzer'),
|
|
@@ -32,9 +32,8 @@ class MissingHeaderAnalyzer extends Analyzer {
|
|
|
32
32
|
const headerValue = res.getHeader(headerName)
|
|
33
33
|
if (Array.isArray(headerValue)) {
|
|
34
34
|
return headerValue
|
|
35
|
-
} else {
|
|
36
|
-
return headerValue ? [headerValue.toString()] : []
|
|
37
35
|
}
|
|
36
|
+
return headerValue ? [headerValue.toString()] : []
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
_getLocation () {}
|
|
@@ -15,7 +15,7 @@ class SqlInjectionAnalyzer extends StoredInjectionAnalyzer {
|
|
|
15
15
|
|
|
16
16
|
onConfigure () {
|
|
17
17
|
this.addSub('apm:mysql:query:start', ({ sql }) => this.analyze(sql, undefined, 'MYSQL'))
|
|
18
|
-
this.addSub('
|
|
18
|
+
this.addSub('datadog:mysql2:outerquery:start', ({ sql }) => this.analyze(sql, undefined, 'MYSQL'))
|
|
19
19
|
this.addSub('apm:pg:query:start', ({ query }) => this.analyze(query.text, undefined, 'POSTGRES'))
|
|
20
20
|
|
|
21
21
|
this.addSub(
|
|
@@ -85,7 +85,7 @@ function hookModule (filename, module, controlsByFile) {
|
|
|
85
85
|
}
|
|
86
86
|
})
|
|
87
87
|
} catch (e) {
|
|
88
|
-
log.error('[ASM] Error initializing IAST security control for %', filename, e)
|
|
88
|
+
log.error('[ASM] Error initializing IAST security control for %s', filename, e)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
return module
|
|
@@ -150,19 +150,18 @@ function addSecureMarks (value, secureMarks, createNewTainted = true) {
|
|
|
150
150
|
|
|
151
151
|
if (typeof value === 'string') {
|
|
152
152
|
return TaintTrackingOperations.addSecureMark(iastContext, value, secureMarks, createNewTainted)
|
|
153
|
-
} else {
|
|
154
|
-
iterateObjectStrings(value, (value, levelKeys, parent, lastKey) => {
|
|
155
|
-
try {
|
|
156
|
-
const securedTainted = TaintTrackingOperations.addSecureMark(iastContext, value, secureMarks, createNewTainted)
|
|
157
|
-
if (createNewTainted) {
|
|
158
|
-
parent[lastKey] = securedTainted
|
|
159
|
-
}
|
|
160
|
-
} catch {
|
|
161
|
-
// if it is a readonly property, do nothing
|
|
162
|
-
}
|
|
163
|
-
})
|
|
164
|
-
return value
|
|
165
153
|
}
|
|
154
|
+
iterateObjectStrings(value, (value, levelKeys, parent, lastKey) => {
|
|
155
|
+
try {
|
|
156
|
+
const securedTainted = TaintTrackingOperations.addSecureMark(iastContext, value, secureMarks, createNewTainted)
|
|
157
|
+
if (createNewTainted) {
|
|
158
|
+
parent[lastKey] = securedTainted
|
|
159
|
+
}
|
|
160
|
+
} catch {
|
|
161
|
+
// if it is a readonly property, do nothing
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
return value
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
function disable () {
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const TaintedUtils = require('@datadog/native-iast-taint-tracking')
|
|
4
4
|
const { IAST_TRANSACTION_ID } = require('../iast-context')
|
|
5
|
+
const { HTTP_REQUEST_PARAMETER } = require('./source-types')
|
|
5
6
|
const log = require('../../../log')
|
|
6
7
|
|
|
8
|
+
const SEPARATOR = '\u0000' // Unit Separator (cannot be in URL keys)
|
|
9
|
+
|
|
7
10
|
function taintObject (iastContext, object, type) {
|
|
8
11
|
let result = object
|
|
9
12
|
const transactionId = iastContext?.[IAST_TRANSACTION_ID]
|
|
@@ -40,6 +43,46 @@ function taintObject (iastContext, object, type) {
|
|
|
40
43
|
return result
|
|
41
44
|
}
|
|
42
45
|
|
|
46
|
+
function taintQueryWithCache (iastContext, query) {
|
|
47
|
+
const transactionId = iastContext?.[IAST_TRANSACTION_ID]
|
|
48
|
+
if (!transactionId || !query) return query
|
|
49
|
+
|
|
50
|
+
iastContext.queryCache ??= new Map() // key: "a.b.c", value: tainted string
|
|
51
|
+
|
|
52
|
+
traverseAndTaint(query, '', iastContext.queryCache, transactionId)
|
|
53
|
+
return query
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function traverseAndTaint (node, path, cache, transactionId) {
|
|
57
|
+
if (node == null) return node
|
|
58
|
+
|
|
59
|
+
if (typeof node === 'string') {
|
|
60
|
+
const cachedValue = cache.get(path)
|
|
61
|
+
|
|
62
|
+
if (cachedValue === node) {
|
|
63
|
+
return cachedValue
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const tainted = TaintedUtils.newTaintedString(transactionId, node, path, HTTP_REQUEST_PARAMETER)
|
|
67
|
+
cache.set(path, tainted)
|
|
68
|
+
|
|
69
|
+
return tainted
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (typeof node === 'object') {
|
|
73
|
+
const keys = Array.isArray(node) ? node.keys() : Object.keys(node)
|
|
74
|
+
|
|
75
|
+
for (const key of keys) {
|
|
76
|
+
const childPath = path ? `${path}${SEPARATOR}${key}` : String(key)
|
|
77
|
+
const tainted = traverseAndTaint(node[key], childPath, cache, transactionId)
|
|
78
|
+
node[key] = tainted
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return node
|
|
83
|
+
}
|
|
84
|
+
|
|
43
85
|
module.exports = {
|
|
44
|
-
taintObject
|
|
86
|
+
taintObject,
|
|
87
|
+
taintQueryWithCache
|
|
45
88
|
}
|
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
getTaintTrackingNoop,
|
|
12
12
|
lodashTaintTrackingHandler
|
|
13
13
|
} = require('./taint-tracking-impl')
|
|
14
|
-
const { taintObject } = require('./operations-taint-object')
|
|
14
|
+
const { taintObject, taintQueryWithCache } = require('./operations-taint-object')
|
|
15
15
|
|
|
16
16
|
const lodashOperationCh = dc.channel('datadog:lodash:operation')
|
|
17
17
|
|
|
@@ -98,6 +98,7 @@ module.exports = {
|
|
|
98
98
|
newTaintedString,
|
|
99
99
|
newTaintedObject,
|
|
100
100
|
taintObject,
|
|
101
|
+
taintQueryWithCache,
|
|
101
102
|
isTainted,
|
|
102
103
|
getRanges,
|
|
103
104
|
enableTaintOperations,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { SourceIastPlugin } = require('../iast-plugin')
|
|
4
4
|
const { getIastContext } = require('../iast-context')
|
|
5
5
|
const { storage } = require('../../../../../datadog-core')
|
|
6
|
-
const { taintObject, newTaintedString, getRanges } = require('./operations')
|
|
6
|
+
const { taintObject, newTaintedString, getRanges, taintQueryWithCache } = require('./operations')
|
|
7
7
|
const {
|
|
8
8
|
HTTP_REQUEST_BODY,
|
|
9
9
|
HTTP_REQUEST_COOKIE_VALUE,
|
|
@@ -63,7 +63,12 @@ class TaintTrackingPlugin extends SourceIastPlugin {
|
|
|
63
63
|
|
|
64
64
|
this.addSub(
|
|
65
65
|
{ channelName: 'datadog:express:query:finish', tag: HTTP_REQUEST_PARAMETER },
|
|
66
|
-
({ query }) =>
|
|
66
|
+
({ query }) => {
|
|
67
|
+
const iastContext = getIastContext(storage('legacy').getStore())
|
|
68
|
+
if (!iastContext || !query) return
|
|
69
|
+
|
|
70
|
+
taintQueryWithCache(iastContext, query)
|
|
71
|
+
}
|
|
67
72
|
)
|
|
68
73
|
|
|
69
74
|
this.addSub(
|
|
@@ -207,7 +212,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
|
|
|
207
212
|
|
|
208
213
|
if (Array.isArray(result)) {
|
|
209
214
|
for (let i = 0; i < result.length && i < this._rowsToTaint; i++) {
|
|
210
|
-
const nextName = name ? `${name}.${i}` :
|
|
215
|
+
const nextName = name ? `${name}.${i}` : String(i)
|
|
211
216
|
result[i] = this._taintDatabaseResult(result[i], dbOrigin, iastContext, nextName)
|
|
212
217
|
}
|
|
213
218
|
} else if (result && typeof result === 'object') {
|
|
@@ -14,6 +14,7 @@ const log = require('../../../log')
|
|
|
14
14
|
const { isMainThread } = require('worker_threads')
|
|
15
15
|
const { LOG_MESSAGE, REWRITTEN_MESSAGE } = require('./constants')
|
|
16
16
|
const orchestrionConfig = require('../../../../../datadog-instrumentations/src/orchestrion-config')
|
|
17
|
+
const { getEnvironmentVariable } = require('../../../config-helper')
|
|
17
18
|
|
|
18
19
|
let config
|
|
19
20
|
const hardcodedSecretCh = dc.channel('datadog:secrets:result')
|
|
@@ -26,7 +27,7 @@ let kSymbolPrepareStackTrace
|
|
|
26
27
|
function noop () {}
|
|
27
28
|
|
|
28
29
|
function isFlagPresent (flag) {
|
|
29
|
-
return
|
|
30
|
+
return getEnvironmentVariable('NODE_OPTIONS')?.includes(flag) ||
|
|
30
31
|
process.execArgv?.some(arg => arg.includes(flag))
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -19,9 +19,8 @@ function getVerbosity (verbosity) {
|
|
|
19
19
|
if (verbosity) {
|
|
20
20
|
verbosity = verbosity.toUpperCase()
|
|
21
21
|
return Verbosity[verbosity] === undefined ? Verbosity.INFORMATION : Verbosity[verbosity]
|
|
22
|
-
} else {
|
|
23
|
-
return Verbosity.INFORMATION
|
|
24
22
|
}
|
|
23
|
+
return Verbosity.INFORMATION
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
function getName (verbosityValue) {
|
|
@@ -16,18 +16,17 @@ function remove (range, rangeToRemove) {
|
|
|
16
16
|
return [range]
|
|
17
17
|
} else if (contains(rangeToRemove, range)) {
|
|
18
18
|
return []
|
|
19
|
-
} else {
|
|
20
|
-
const result = []
|
|
21
|
-
if (rangeToRemove.start > range.start) {
|
|
22
|
-
const offset = rangeToRemove.start - range.start
|
|
23
|
-
result.push({ start: range.start, end: range.start + offset })
|
|
24
|
-
}
|
|
25
|
-
if (rangeToRemove.end < range.end) {
|
|
26
|
-
const offset = range.end - rangeToRemove.end
|
|
27
|
-
result.push({ start: rangeToRemove.end, end: rangeToRemove.end + offset })
|
|
28
|
-
}
|
|
29
|
-
return result
|
|
30
19
|
}
|
|
20
|
+
const result = []
|
|
21
|
+
if (rangeToRemove.start > range.start) {
|
|
22
|
+
const offset = rangeToRemove.start - range.start
|
|
23
|
+
result.push({ start: range.start, end: range.start + offset })
|
|
24
|
+
}
|
|
25
|
+
if (rangeToRemove.end < range.end) {
|
|
26
|
+
const offset = range.end - rangeToRemove.end
|
|
27
|
+
result.push({ start: rangeToRemove.end, end: rangeToRemove.end + offset })
|
|
28
|
+
}
|
|
29
|
+
return result
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
module.exports = {
|
|
@@ -8,7 +8,6 @@ const { contains, intersects, remove } = require('./range-utils')
|
|
|
8
8
|
|
|
9
9
|
const commandSensitiveAnalyzer = require('./sensitive-analyzers/command-sensitive-analyzer')
|
|
10
10
|
const hardcodedPasswordAnalyzer = require('./sensitive-analyzers/hardcoded-password-analyzer')
|
|
11
|
-
const headerSensitiveAnalyzer = require('./sensitive-analyzers/header-sensitive-analyzer')
|
|
12
11
|
const jsonSensitiveAnalyzer = require('./sensitive-analyzers/json-sensitive-analyzer')
|
|
13
12
|
const ldapSensitiveAnalyzer = require('./sensitive-analyzers/ldap-sensitive-analyzer')
|
|
14
13
|
const sqlSensitiveAnalyzer = require('./sensitive-analyzers/sql-sensitive-analyzer')
|
|
@@ -30,9 +29,6 @@ class SensitiveHandler {
|
|
|
30
29
|
this._sensitiveAnalyzers.set(vulnerabilities.HARDCODED_PASSWORD, (evidence) => {
|
|
31
30
|
return hardcodedPasswordAnalyzer(evidence, this._valuePattern)
|
|
32
31
|
})
|
|
33
|
-
this._sensitiveAnalyzers.set(vulnerabilities.HEADER_INJECTION, (evidence) => {
|
|
34
|
-
return headerSensitiveAnalyzer(evidence, this._namePattern, this._valuePattern)
|
|
35
|
-
})
|
|
36
32
|
this._sensitiveAnalyzers.set(vulnerabilities.LDAP_INJECTION, ldapSensitiveAnalyzer)
|
|
37
33
|
this._sensitiveAnalyzers.set(vulnerabilities.NOSQL_MONGODB_INJECTION, jsonSensitiveAnalyzer)
|
|
38
34
|
this._sensitiveAnalyzers.set(vulnerabilities.SQL_INJECTION, sqlSensitiveAnalyzer)
|
|
@@ -3,7 +3,6 @@ module.exports = {
|
|
|
3
3
|
CODE_INJECTION: 'CODE_INJECTION',
|
|
4
4
|
HARDCODED_PASSWORD: 'HARDCODED_PASSWORD',
|
|
5
5
|
HARDCODED_SECRET: 'HARDCODED_SECRET',
|
|
6
|
-
HEADER_INJECTION: 'HEADER_INJECTION',
|
|
7
6
|
HSTS_HEADER_MISSING: 'HSTS_HEADER_MISSING',
|
|
8
7
|
INSECURE_COOKIE: 'INSECURE_COOKIE',
|
|
9
8
|
LDAP_INJECTION: 'LDAP_INJECTION',
|
|
@@ -37,6 +37,7 @@ const rasp = require('./rasp')
|
|
|
37
37
|
const { isInServerlessEnvironment } = require('../serverless')
|
|
38
38
|
|
|
39
39
|
const responseAnalyzedSet = new WeakSet()
|
|
40
|
+
const storedResponseHeaders = new WeakMap()
|
|
40
41
|
|
|
41
42
|
let isEnabled = false
|
|
42
43
|
let config
|
|
@@ -45,7 +46,7 @@ function enable (_config) {
|
|
|
45
46
|
if (isEnabled) return
|
|
46
47
|
|
|
47
48
|
try {
|
|
48
|
-
appsecTelemetry.enable(_config
|
|
49
|
+
appsecTelemetry.enable(_config)
|
|
49
50
|
graphql.enable()
|
|
50
51
|
|
|
51
52
|
if (_config.appsec.rasp.enabled) {
|
|
@@ -139,7 +140,7 @@ function incomingHttpStartTranslator ({ req, res, abortController }) {
|
|
|
139
140
|
[HTTP_CLIENT_IP]: clientIp
|
|
140
141
|
})
|
|
141
142
|
|
|
142
|
-
const requestHeaders =
|
|
143
|
+
const requestHeaders = { ...req.headers }
|
|
143
144
|
delete requestHeaders.cookie
|
|
144
145
|
|
|
145
146
|
const persistent = {
|
|
@@ -187,7 +188,13 @@ function incomingHttpEndTranslator ({ req, res }) {
|
|
|
187
188
|
|
|
188
189
|
waf.disposeContext(req)
|
|
189
190
|
|
|
190
|
-
|
|
191
|
+
const storedHeaders = storedResponseHeaders.get(req) || {}
|
|
192
|
+
|
|
193
|
+
Reporter.finishRequest(req, res, storedHeaders)
|
|
194
|
+
|
|
195
|
+
if (storedHeaders) {
|
|
196
|
+
storedResponseHeaders.delete(req)
|
|
197
|
+
}
|
|
191
198
|
}
|
|
192
199
|
|
|
193
200
|
function onPassportVerify ({ framework, login, user, success, abortController }) {
|
|
@@ -285,6 +292,10 @@ function onResponseBody ({ req, res, body }) {
|
|
|
285
292
|
}
|
|
286
293
|
|
|
287
294
|
function onResponseWriteHead ({ req, res, abortController, statusCode, responseHeaders }) {
|
|
295
|
+
if (Object.keys(responseHeaders).length) {
|
|
296
|
+
storedResponseHeaders.set(req, responseHeaders)
|
|
297
|
+
}
|
|
298
|
+
|
|
288
299
|
// avoid "write after end" error
|
|
289
300
|
if (isBlocked(res)) {
|
|
290
301
|
abortController?.abort()
|
|
@@ -299,12 +310,12 @@ function onResponseWriteHead ({ req, res, abortController, statusCode, responseH
|
|
|
299
310
|
const rootSpan = web.root(req)
|
|
300
311
|
if (!rootSpan) return
|
|
301
312
|
|
|
302
|
-
responseHeaders =
|
|
313
|
+
responseHeaders = { ...responseHeaders }
|
|
303
314
|
delete responseHeaders['set-cookie']
|
|
304
315
|
|
|
305
316
|
const results = waf.run({
|
|
306
317
|
persistent: {
|
|
307
|
-
[addresses.HTTP_INCOMING_RESPONSE_CODE]:
|
|
318
|
+
[addresses.HTTP_INCOMING_RESPONSE_CODE]: String(statusCode),
|
|
308
319
|
[addresses.HTTP_INCOMING_RESPONSE_HEADERS]: responseHeaders
|
|
309
320
|
}
|
|
310
321
|
}, req)
|