dd-trace 3.38.1 → 3.40.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 -2
- package/README.md +3 -3
- package/ext/kinds.d.ts +1 -0
- package/ext/kinds.js +2 -1
- package/ext/tags.d.ts +2 -1
- package/ext/tags.js +6 -1
- package/index.d.ts +9 -1
- package/package.json +8 -8
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-esbuild/index.js +1 -20
- package/packages/datadog-instrumentations/src/cucumber.js +5 -0
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +39 -10
- package/packages/datadog-instrumentations/src/knex.js +24 -17
- package/packages/datadog-instrumentations/src/mocha.js +16 -1
- package/packages/datadog-instrumentations/src/next.js +58 -23
- package/packages/datadog-instrumentations/src/playwright.js +11 -6
- package/packages/datadog-instrumentations/src/restify.js +14 -1
- package/packages/datadog-plugin-http/src/client.js +2 -0
- package/packages/datadog-plugin-jest/src/index.js +11 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -6
- package/packages/datadog-plugin-kafkajs/src/producer.js +9 -6
- package/packages/datadog-plugin-mocha/src/index.js +7 -1
- package/packages/datadog-plugin-next/src/index.js +4 -3
- package/packages/datadog-plugin-playwright/src/index.js +4 -1
- package/packages/dd-trace/src/appsec/channels.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +269 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +5 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +22 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +9 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/iast-log.js +9 -4
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +7 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +13 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +1 -14
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +19 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +2 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +5 -1
- package/packages/dd-trace/src/appsec/recommended.json +272 -48
- package/packages/dd-trace/src/appsec/reporter.js +31 -34
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +16 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -0
- package/packages/dd-trace/src/config.js +35 -17
- package/packages/dd-trace/src/datastreams/processor.js +60 -15
- package/packages/dd-trace/src/format.js +6 -1
- package/packages/dd-trace/src/git_properties.js +16 -15
- package/packages/dd-trace/src/iitm.js +1 -1
- package/packages/dd-trace/src/log/channels.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +95 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
- package/packages/dd-trace/src/opentracing/span.js +4 -0
- package/packages/dd-trace/src/opentracing/span_context.js +5 -2
- package/packages/dd-trace/src/plugin_manager.js +1 -1
- package/packages/dd-trace/src/plugins/database.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +6 -19
- package/packages/dd-trace/src/plugins/util/git.js +2 -1
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
- package/packages/dd-trace/src/plugins/util/test.js +29 -1
- package/packages/dd-trace/src/plugins/util/url.js +26 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -14
- package/packages/dd-trace/src/profiling/config.js +23 -20
- package/packages/dd-trace/src/profiling/profilers/events.js +161 -0
- package/packages/dd-trace/src/profiling/profilers/shared.js +9 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +84 -47
- package/packages/dd-trace/src/ritm.js +1 -1
- package/packages/dd-trace/src/span_processor.js +4 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/index.js +5 -1
- package/packages/dd-trace/src/telemetry/logs/index.js +65 -0
- package/packages/dd-trace/src/{appsec/iast/telemetry/log → telemetry/logs}/log-collector.js +9 -22
- package/packages/dd-trace/src/tracer.js +4 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/log/index.js +0 -87
- package/packages/diagnostics_channel/index.js +0 -3
- package/packages/diagnostics_channel/src/index.js +0 -121
|
@@ -7,6 +7,7 @@ const { getNodeModulesPaths } = require('../path-line')
|
|
|
7
7
|
const { getNextSecureMark } = require('../taint-tracking/secure-marks-generator')
|
|
8
8
|
const { storage } = require('../../../../../datadog-core')
|
|
9
9
|
const { getIastContext } = require('../iast-context')
|
|
10
|
+
const { HTTP_REQUEST_PARAMETER, HTTP_REQUEST_BODY } = require('../taint-tracking/source-types')
|
|
10
11
|
|
|
11
12
|
const EXCLUDED_PATHS_FROM_STACK = getNodeModulesPaths('mongodb', 'mongoose')
|
|
12
13
|
const MONGODB_NOSQL_SECURE_MARK = getNextSecureMark()
|
|
@@ -113,6 +114,12 @@ class NosqlInjectionMongodbAnalyzer extends InjectionAnalyzer {
|
|
|
113
114
|
})
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
_isVulnerableRange (range) {
|
|
118
|
+
const rangeType = range?.iinfo?.type
|
|
119
|
+
const isVulnerableType = rangeType === HTTP_REQUEST_PARAMETER || rangeType === HTTP_REQUEST_BODY
|
|
120
|
+
return isVulnerableType && (range.secureMarks & MONGODB_NOSQL_SECURE_MARK) !== MONGODB_NOSQL_SECURE_MARK
|
|
121
|
+
}
|
|
122
|
+
|
|
116
123
|
_isVulnerable (value, iastContext) {
|
|
117
124
|
if (value?.filter && iastContext) {
|
|
118
125
|
let isVulnerable = false
|
|
@@ -124,13 +131,13 @@ class NosqlInjectionMongodbAnalyzer extends InjectionAnalyzer {
|
|
|
124
131
|
const rangesByKey = {}
|
|
125
132
|
const allRanges = []
|
|
126
133
|
|
|
127
|
-
iterateObjectStrings(value.filter,
|
|
134
|
+
iterateObjectStrings(value.filter, (val, nextLevelKeys) => {
|
|
128
135
|
const ranges = getRanges(iastContext, val)
|
|
129
136
|
if (ranges?.length) {
|
|
130
137
|
const filteredRanges = []
|
|
131
138
|
|
|
132
139
|
for (const range of ranges) {
|
|
133
|
-
if ((range
|
|
140
|
+
if (this._isVulnerableRange(range)) {
|
|
134
141
|
isVulnerable = true
|
|
135
142
|
filteredRanges.push(range)
|
|
136
143
|
}
|
|
@@ -11,8 +11,8 @@ class XcontenttypeHeaderMissingAnalyzer extends MissingHeaderAnalyzer {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
_isVulnerableFromRequestAndResponse (req, res) {
|
|
14
|
-
const
|
|
15
|
-
return
|
|
14
|
+
const headerValues = this._getHeaderValues(res, XCONTENTTYPEOPTIONS_HEADER_NAME)
|
|
15
|
+
return headerValues.length === 0 || headerValues.some(headerValue => headerValue.trim().toLowerCase() !== 'nosniff')
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const dc = require('dc-polyfill')
|
|
3
4
|
const log = require('../../log')
|
|
4
|
-
const telemetryLogs = require('./telemetry/log')
|
|
5
5
|
const { calculateDDBasePath } = require('../../util')
|
|
6
6
|
|
|
7
|
+
const telemetryLog = dc.channel('datadog:telemetry:log')
|
|
8
|
+
|
|
7
9
|
const ddBasePath = calculateDDBasePath(__dirname)
|
|
8
10
|
const EOL = '\n'
|
|
9
11
|
const STACK_FRAME_LINE_REGEX = /^\s*at\s/gm
|
|
@@ -80,9 +82,8 @@ const iastLog = {
|
|
|
80
82
|
},
|
|
81
83
|
|
|
82
84
|
publish (data, level) {
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
telemetryLogs.publish(telemetryLog)
|
|
85
|
+
if (telemetryLog.hasSubscribers) {
|
|
86
|
+
telemetryLog.publish(getTelemetryLog(data, level))
|
|
86
87
|
}
|
|
87
88
|
return this
|
|
88
89
|
},
|
|
@@ -92,6 +93,10 @@ const iastLog = {
|
|
|
92
93
|
return this.publish(data, 'DEBUG')
|
|
93
94
|
},
|
|
94
95
|
|
|
96
|
+
/**
|
|
97
|
+
* forward 'INFO' log level to 'DEBUG' telemetry log level
|
|
98
|
+
* see also {@link ../../telemetry/logs#isLevelEnabled } method
|
|
99
|
+
*/
|
|
95
100
|
infoAndPublish (data) {
|
|
96
101
|
this.info(data)
|
|
97
102
|
return this.publish(data, 'DEBUG')
|
|
@@ -3,7 +3,7 @@ const { enableAllAnalyzers, disableAllAnalyzers } = require('./analyzers')
|
|
|
3
3
|
const web = require('../../plugins/util/web')
|
|
4
4
|
const { storage } = require('../../../../datadog-core')
|
|
5
5
|
const overheadController = require('./overhead-controller')
|
|
6
|
-
const dc = require('
|
|
6
|
+
const dc = require('dc-polyfill')
|
|
7
7
|
const iastContextFunctions = require('./iast-context')
|
|
8
8
|
const {
|
|
9
9
|
enableTaintTracking,
|
|
@@ -6,13 +6,14 @@ const { calculateDDBasePath } = require('../../util')
|
|
|
6
6
|
const pathLine = {
|
|
7
7
|
getFirstNonDDPathAndLine,
|
|
8
8
|
getNodeModulesPaths,
|
|
9
|
+
getRelativePath,
|
|
9
10
|
getFirstNonDDPathAndLineFromCallsites, // Exported only for test purposes
|
|
10
11
|
calculateDDBasePath, // Exported only for test purposes
|
|
11
12
|
ddBasePath: calculateDDBasePath(__dirname) // Only for test purposes
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const EXCLUDED_PATHS = [
|
|
15
|
-
path.join(path.sep, 'node_modules', '
|
|
16
|
+
path.join(path.sep, 'node_modules', 'dc-polyfill')
|
|
16
17
|
]
|
|
17
18
|
const EXCLUDED_PATH_PREFIXES = [
|
|
18
19
|
'node:diagnostics_channel',
|
|
@@ -45,7 +46,7 @@ function getFirstNonDDPathAndLineFromCallsites (callsites, externallyExcludedPat
|
|
|
45
46
|
const filepath = callsite.getFileName()
|
|
46
47
|
if (!isExcluded(callsite, externallyExcludedPaths) && filepath.indexOf(pathLine.ddBasePath) === -1) {
|
|
47
48
|
return {
|
|
48
|
-
path:
|
|
49
|
+
path: getRelativePath(filepath),
|
|
49
50
|
line: callsite.getLineNumber(),
|
|
50
51
|
column: callsite.getColumnNumber(),
|
|
51
52
|
isInternal: !path.isAbsolute(filepath)
|
|
@@ -56,6 +57,10 @@ function getFirstNonDDPathAndLineFromCallsites (callsites, externallyExcludedPat
|
|
|
56
57
|
return null
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
function getRelativePath (filepath) {
|
|
61
|
+
return path.relative(process.cwd(), filepath)
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
function isExcluded (callsite, externallyExcludedPaths) {
|
|
60
65
|
if (callsite.isNative()) return true
|
|
61
66
|
const filename = callsite.getFileName()
|
|
@@ -7,7 +7,9 @@ const { isPrivateModule, isNotLibraryFile } = require('./filter')
|
|
|
7
7
|
const { csiMethods } = require('./csi-methods')
|
|
8
8
|
const { getName } = require('../telemetry/verbosity')
|
|
9
9
|
const { getRewriteFunction } = require('./rewriter-telemetry')
|
|
10
|
+
const dc = require('dc-polyfill')
|
|
10
11
|
|
|
12
|
+
const hardcodedSecretCh = dc.channel('datadog:secrets:result')
|
|
11
13
|
let rewriter
|
|
12
14
|
let getPrepareStackTrace
|
|
13
15
|
|
|
@@ -50,7 +52,11 @@ function getRewriter (telemetryVerbosity) {
|
|
|
50
52
|
getGetOriginalPathAndLineFromSourceMapFunction(chainSourceMap, getOriginalPathAndLineFromSourceMap)
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
rewriter = new Rewriter({
|
|
55
|
+
rewriter = new Rewriter({
|
|
56
|
+
csiMethods,
|
|
57
|
+
telemetryVerbosity: getName(telemetryVerbosity),
|
|
58
|
+
chainSourceMap
|
|
59
|
+
})
|
|
54
60
|
} catch (e) {
|
|
55
61
|
iastLog.error('Unable to initialize TaintTracking Rewriter')
|
|
56
62
|
.errorAndPublish(e)
|
|
@@ -80,7 +86,12 @@ function getCompileMethodFn (compileMethod) {
|
|
|
80
86
|
try {
|
|
81
87
|
if (isPrivateModule(filename) && isNotLibraryFile(filename)) {
|
|
82
88
|
const rewritten = rewriteFn(content, filename)
|
|
83
|
-
|
|
89
|
+
|
|
90
|
+
if (rewritten?.literalsResult && hardcodedSecretCh.hasSubscribers) {
|
|
91
|
+
hardcodedSecretCh.publish(rewritten.literalsResult)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (rewritten?.content) {
|
|
84
95
|
return compileMethod.apply(this, [rewritten.content, filename])
|
|
85
96
|
}
|
|
86
97
|
}
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const telemetryMetrics = require('../../../telemetry/metrics')
|
|
4
|
-
const telemetryLogs = require('./log')
|
|
5
4
|
const { Verbosity, getVerbosity } = require('./verbosity')
|
|
6
5
|
const { initRequestNamespace, finalizeRequestNamespace, globalNamespace } = require('./namespaces')
|
|
7
6
|
|
|
8
|
-
function isIastMetricsEnabled (metrics) {
|
|
9
|
-
// TODO: let DD_TELEMETRY_METRICS_ENABLED as undefined in config.js to avoid read here the env property
|
|
10
|
-
return process.env.DD_TELEMETRY_METRICS_ENABLED !== undefined ? metrics : true
|
|
11
|
-
}
|
|
12
|
-
|
|
13
7
|
class Telemetry {
|
|
14
8
|
configure (config, verbosity) {
|
|
15
|
-
const telemetryAndMetricsEnabled = config &&
|
|
16
|
-
config.telemetry &&
|
|
17
|
-
config.telemetry.enabled &&
|
|
18
|
-
isIastMetricsEnabled(config.telemetry.metrics)
|
|
9
|
+
const telemetryAndMetricsEnabled = config?.telemetry?.enabled && config.telemetry.metrics
|
|
19
10
|
|
|
20
11
|
this.verbosity = telemetryAndMetricsEnabled ? getVerbosity(verbosity) : Verbosity.OFF
|
|
21
12
|
this.enabled = this.verbosity !== Verbosity.OFF
|
|
@@ -23,15 +14,11 @@ class Telemetry {
|
|
|
23
14
|
if (this.enabled) {
|
|
24
15
|
telemetryMetrics.manager.set('iast', globalNamespace)
|
|
25
16
|
}
|
|
26
|
-
|
|
27
|
-
telemetryLogs.start()
|
|
28
17
|
}
|
|
29
18
|
|
|
30
19
|
stop () {
|
|
31
20
|
this.enabled = false
|
|
32
21
|
telemetryMetrics.manager.delete('iast')
|
|
33
|
-
|
|
34
|
-
telemetryLogs.stop()
|
|
35
22
|
}
|
|
36
23
|
|
|
37
24
|
isEnabled () {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const iastLog = require('../../iast-log')
|
|
3
4
|
const vulnerabilities = require('../../vulnerabilities')
|
|
4
5
|
|
|
5
6
|
const { contains, intersects, remove } = require('./range-utils')
|
|
@@ -263,6 +264,24 @@ class SensitiveHandler {
|
|
|
263
264
|
valueParts.push({ redacted: true })
|
|
264
265
|
}
|
|
265
266
|
}
|
|
267
|
+
|
|
268
|
+
setRedactionPatterns (redactionNamePattern, redactionValuePattern) {
|
|
269
|
+
if (redactionNamePattern) {
|
|
270
|
+
try {
|
|
271
|
+
this._namePattern = new RegExp(redactionNamePattern, 'gmi')
|
|
272
|
+
} catch (e) {
|
|
273
|
+
iastLog.warn('Redaction name pattern is not valid')
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (redactionValuePattern) {
|
|
278
|
+
try {
|
|
279
|
+
this._valuePattern = new RegExp(redactionValuePattern, 'gmi')
|
|
280
|
+
} catch (e) {
|
|
281
|
+
iastLog.warn('Redaction value pattern is not valid')
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
266
285
|
}
|
|
267
286
|
|
|
268
287
|
module.exports = new SensitiveHandler()
|
|
@@ -8,8 +8,9 @@ class VulnerabilityFormatter {
|
|
|
8
8
|
this._redactVulnearbilities = true
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
setRedactVulnerabilities (shouldRedactVulnerabilities) {
|
|
11
|
+
setRedactVulnerabilities (shouldRedactVulnerabilities, redactionNamePattern, redactionValuePattern) {
|
|
12
12
|
this._redactVulnearbilities = shouldRedactVulnerabilities
|
|
13
|
+
sensitiveHandler.setRedactionPatterns(redactionNamePattern, redactionValuePattern)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
extractSourcesFromVulnerability (vulnerability) {
|
|
@@ -95,7 +95,11 @@ function deduplicateVulnerabilities (vulnerabilities) {
|
|
|
95
95
|
|
|
96
96
|
function start (config, _tracer) {
|
|
97
97
|
deduplicationEnabled = config.iast.deduplicationEnabled
|
|
98
|
-
vulnerabilitiesFormatter.setRedactVulnerabilities(
|
|
98
|
+
vulnerabilitiesFormatter.setRedactVulnerabilities(
|
|
99
|
+
config.iast.redactionEnabled,
|
|
100
|
+
config.iast.redactionNamePattern,
|
|
101
|
+
config.iast.redactionValuePattern
|
|
102
|
+
)
|
|
99
103
|
if (deduplicationEnabled) {
|
|
100
104
|
startClearCacheTimer()
|
|
101
105
|
}
|