dd-trace 3.12.1 → 3.15.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/README.md +5 -5
- package/ci/init.js +3 -1
- package/index.d.ts +100 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +86 -0
- package/packages/datadog-instrumentations/src/cucumber.js +74 -15
- package/packages/datadog-instrumentations/src/cypress.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +358 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +24 -23
- package/packages/datadog-instrumentations/src/ldapjs.js +12 -2
- package/packages/datadog-instrumentations/src/mocha.js +10 -7
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +7 -1
- package/packages/datadog-instrumentations/src/mysql2.js +7 -1
- package/packages/datadog-instrumentations/src/next.js +2 -1
- package/packages/datadog-instrumentations/src/playwright.js +263 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -5
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +29 -24
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +31 -16
- package/packages/datadog-plugin-cucumber/src/index.js +42 -11
- package/packages/datadog-plugin-cypress/src/plugin.js +129 -4
- package/packages/datadog-plugin-cypress/src/support.js +5 -0
- package/packages/datadog-plugin-fs/src/index.js +45 -0
- package/packages/datadog-plugin-hapi/src/index.js +5 -1
- package/packages/datadog-plugin-http/src/server.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +40 -70
- package/packages/datadog-plugin-mocha/src/index.js +44 -64
- package/packages/datadog-plugin-mysql/src/index.js +8 -7
- package/packages/datadog-plugin-playwright/src/index.js +112 -0
- package/packages/datadog-shimmer/src/shimmer.js +28 -11
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +35 -9
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +6 -2
- package/packages/dd-trace/src/appsec/iast/index.js +3 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -2
- package/packages/dd-trace/src/appsec/index.js +5 -5
- package/packages/dd-trace/src/appsec/recommended.json +320 -184
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +3 -0
- package/packages/dd-trace/src/appsec/reporter.js +14 -14
- package/packages/dd-trace/src/appsec/sdk/index.js +41 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +17 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +30 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +74 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +73 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +10 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +48 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +5 -3
- package/packages/dd-trace/src/config.js +63 -7
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -4
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +52 -37
- package/packages/dd-trace/src/encode/tags-processors.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +10 -3
- package/packages/dd-trace/src/lambda/handler.js +5 -6
- package/packages/dd-trace/src/log/channels.js +47 -0
- package/packages/dd-trace/src/log/index.js +79 -0
- package/packages/dd-trace/src/log/writer.js +124 -0
- package/packages/dd-trace/src/metrics.js +18 -0
- package/packages/dd-trace/src/noop/proxy.js +5 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +188 -36
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +99 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -1
- package/packages/dd-trace/src/opentracing/span_context.js +6 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +72 -12
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -21
- package/packages/dd-trace/src/plugins/util/exec.js +2 -2
- package/packages/dd-trace/src/plugins/util/git.js +16 -1
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +53 -10
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -7
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/profiler.js +3 -0
- package/packages/dd-trace/src/profiling/config.js +8 -3
- package/packages/dd-trace/src/profiling/exporters/file.js +13 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -6
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_sampler.js +68 -52
- package/packages/dd-trace/src/startup-log.js +3 -6
- package/packages/dd-trace/src/telemetry/index.js +23 -2
- package/packages/dd-trace/src/telemetry/send-data.js +4 -1
- package/packages/dd-trace/src/tracer.js +0 -16
- package/scripts/check-proposal-labels.js +71 -0
- package/packages/dd-trace/src/log.js +0 -143
- /package/packages/dd-trace/src/{appsec → plugins/util}/ip_blocklist.js +0 -0
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const log = require('../log')
|
|
3
4
|
const fs = require('fs')
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
// TODO: move template loading to a proper spot.
|
|
7
|
+
let templateLoaded = false
|
|
8
|
+
let templateHtml = ''
|
|
9
|
+
let templateJson = ''
|
|
10
|
+
|
|
11
|
+
function block (req, res, rootSpan, abortController) {
|
|
12
|
+
if (res.headersSent) {
|
|
13
|
+
log.warn('Cannot send blocking response when headers have already been sent')
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
6
17
|
let type
|
|
7
18
|
let body
|
|
8
19
|
|
|
@@ -17,7 +28,7 @@ function block (req, res, topSpan, abortController) {
|
|
|
17
28
|
body = templateJson
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
|
|
31
|
+
rootSpan.addTags({
|
|
21
32
|
'appsec.blocked': 'true'
|
|
22
33
|
})
|
|
23
34
|
|
|
@@ -26,19 +37,34 @@ function block (req, res, topSpan, abortController) {
|
|
|
26
37
|
res.setHeader('Content-Length', Buffer.byteLength(body))
|
|
27
38
|
res.end(body)
|
|
28
39
|
|
|
29
|
-
abortController
|
|
40
|
+
if (abortController) {
|
|
41
|
+
abortController.abort()
|
|
42
|
+
}
|
|
30
43
|
}
|
|
31
44
|
|
|
32
45
|
function loadTemplates (config) {
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
if (!templateLoaded) {
|
|
47
|
+
templateHtml = fs.readFileSync(config.appsec.blockedTemplateHtml)
|
|
48
|
+
templateJson = fs.readFileSync(config.appsec.blockedTemplateJson)
|
|
49
|
+
templateLoaded = true
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
async function loadTemplatesAsync (config) {
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
if (!templateLoaded) {
|
|
55
|
+
templateHtml = await fs.promises.readFile(config.appsec.blockedTemplateHtml)
|
|
56
|
+
templateJson = await fs.promises.readFile(config.appsec.blockedTemplateJson)
|
|
57
|
+
templateLoaded = true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function resetTemplates () {
|
|
62
|
+
templateLoaded = false
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
module.exports = {
|
|
43
|
-
block,
|
|
66
|
+
block,
|
|
67
|
+
loadTemplates,
|
|
68
|
+
loadTemplatesAsync,
|
|
69
|
+
resetTemplates
|
|
44
70
|
}
|
|
@@ -37,7 +37,7 @@ class WAFCallback {
|
|
|
37
37
|
Reporter.metricsQueue.set('_dd.appsec.event_rules.error_count', failed)
|
|
38
38
|
if (failed) Reporter.metricsQueue.set('_dd.appsec.event_rules.errors', JSON.stringify(errors))
|
|
39
39
|
|
|
40
|
-
Reporter.metricsQueue.set('manual.keep', true)
|
|
40
|
+
Reporter.metricsQueue.set('manual.keep', 'true')
|
|
41
41
|
|
|
42
42
|
this.wafContextCache = new WeakMap()
|
|
43
43
|
|
|
@@ -2,6 +2,7 @@ module.exports = {
|
|
|
2
2
|
'WEAK_CIPHER_ANALYZER': require('./weak-cipher-analyzer'),
|
|
3
3
|
'WEAK_HASH_ANALYZER': require('./weak-hash-analyzer'),
|
|
4
4
|
'SQL_INJECTION_ANALYZER': require('./sql-injection-analyzer'),
|
|
5
|
+
'PATH_TRAVERSAL_ANALYZER': require('./path-traversal-analyzer'),
|
|
5
6
|
'COMMAND_INJECTION_ANALYZER': require('./command-injection-analyzer'),
|
|
6
7
|
'LDAP_ANALYZER': require('./ldap-injection-analyzer')
|
|
7
8
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const { getIastContext } = require('../iast-context')
|
|
3
|
+
const { storage } = require('../../../../../datadog-core')
|
|
4
|
+
const InjectionAnalyzer = require('./injection-analyzer')
|
|
5
|
+
|
|
6
|
+
class PathTraversalAnalyzer extends InjectionAnalyzer {
|
|
7
|
+
constructor () {
|
|
8
|
+
super('PATH_TRAVERSAL')
|
|
9
|
+
this.addSub('apm:fs:operation:start', obj => {
|
|
10
|
+
const pathArguments = []
|
|
11
|
+
if (obj.dest) {
|
|
12
|
+
pathArguments.push(obj.dest)
|
|
13
|
+
}
|
|
14
|
+
if (obj.existingPath) {
|
|
15
|
+
pathArguments.push(obj.existingPath)
|
|
16
|
+
}
|
|
17
|
+
if (obj.file) {
|
|
18
|
+
pathArguments.push(obj.file)
|
|
19
|
+
}
|
|
20
|
+
if (obj.newPath) {
|
|
21
|
+
pathArguments.push(obj.newPath)
|
|
22
|
+
}
|
|
23
|
+
if (obj.oldPath) {
|
|
24
|
+
pathArguments.push(obj.oldPath)
|
|
25
|
+
}
|
|
26
|
+
if (obj.path) {
|
|
27
|
+
pathArguments.push(obj.path)
|
|
28
|
+
}
|
|
29
|
+
if (obj.prefix) {
|
|
30
|
+
pathArguments.push(obj.prefix)
|
|
31
|
+
}
|
|
32
|
+
if (obj.src) {
|
|
33
|
+
pathArguments.push(obj.src)
|
|
34
|
+
}
|
|
35
|
+
if (obj.target) {
|
|
36
|
+
pathArguments.push(obj.target)
|
|
37
|
+
}
|
|
38
|
+
this.analyze(pathArguments)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
analyze (value) {
|
|
43
|
+
const iastContext = getIastContext(storage.getStore())
|
|
44
|
+
if (!iastContext) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (value && value.constructor === Array) {
|
|
49
|
+
for (const val of value) {
|
|
50
|
+
if (this._isVulnerable(val, iastContext)) {
|
|
51
|
+
this._report(val, iastContext)
|
|
52
|
+
// no support several evidences in the same vulnerability, just report the 1st one
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = new PathTraversalAnalyzer()
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const IAST_CONTEXT_KEY = Symbol('_dd.iast.context')
|
|
2
2
|
const IAST_TRANSACTION_ID = Symbol('_dd.iast.transactionId')
|
|
3
3
|
|
|
4
|
-
function getIastContext (store) {
|
|
5
|
-
|
|
4
|
+
function getIastContext (store, topContext) {
|
|
5
|
+
let iastContext = store && store[IAST_CONTEXT_KEY]
|
|
6
|
+
if (!iastContext) {
|
|
7
|
+
iastContext = topContext && topContext[IAST_CONTEXT_KEY]
|
|
8
|
+
}
|
|
9
|
+
return iastContext
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
/* TODO Fix storage problem when the close event is called without
|
|
@@ -58,7 +58,8 @@ function onIncomingHttpRequestStart (data) {
|
|
|
58
58
|
function onIncomingHttpRequestEnd (data) {
|
|
59
59
|
if (data && data.req) {
|
|
60
60
|
const store = storage.getStore()
|
|
61
|
-
const
|
|
61
|
+
const topContext = web.getContext(data.req)
|
|
62
|
+
const iastContext = iastContextFunctions.getIastContext(store, topContext)
|
|
62
63
|
if (iastContext && iastContext.rootSpan) {
|
|
63
64
|
const vulnerabilities = iastContext.vulnerabilities
|
|
64
65
|
const rootSpan = iastContext.rootSpan
|
|
@@ -66,7 +67,7 @@ function onIncomingHttpRequestEnd (data) {
|
|
|
66
67
|
removeTransaction(iastContext)
|
|
67
68
|
}
|
|
68
69
|
// TODO web.getContext(data.req) is required when the request is aborted
|
|
69
|
-
if (iastContextFunctions.cleanIastContext(store,
|
|
70
|
+
if (iastContextFunctions.cleanIastContext(store, topContext, iastContext)) {
|
|
70
71
|
overheadController.releaseRequest()
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -40,10 +40,13 @@ function getCompileMethodFn (compileMethod) {
|
|
|
40
40
|
return function (content, filename) {
|
|
41
41
|
try {
|
|
42
42
|
if (isPrivateModule(filename) && isNotLibraryFile(filename)) {
|
|
43
|
-
|
|
43
|
+
const rewritten = rewriter.rewrite(content, filename)
|
|
44
|
+
if (rewritten && rewritten.content) {
|
|
45
|
+
return compileMethod.apply(this, [rewritten.content, filename])
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
} catch (e) {
|
|
46
|
-
log.
|
|
49
|
+
log.error(e)
|
|
47
50
|
}
|
|
48
51
|
return compileMethod.apply(this, [content, filename])
|
|
49
52
|
}
|
|
@@ -10,7 +10,7 @@ const Gateway = require('./gateway/engine')
|
|
|
10
10
|
const addresses = require('./addresses')
|
|
11
11
|
const Reporter = require('./reporter')
|
|
12
12
|
const web = require('../plugins/util/web')
|
|
13
|
-
const { extractIp } = require('
|
|
13
|
+
const { extractIp } = require('../plugins/util/ip_extractor')
|
|
14
14
|
const { HTTP_CLIENT_IP } = require('../../../../ext/tags')
|
|
15
15
|
const { block, loadTemplates, loadTemplatesAsync } = require('./blocking')
|
|
16
16
|
|
|
@@ -70,12 +70,12 @@ function abortEnable (err) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function incomingHttpStartTranslator ({ req, res, abortController }) {
|
|
73
|
-
const
|
|
74
|
-
if (!
|
|
73
|
+
const rootSpan = web.root(req)
|
|
74
|
+
if (!rootSpan) return
|
|
75
75
|
|
|
76
76
|
const clientIp = extractIp(config, req)
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
rootSpan.addTags({
|
|
79
79
|
'_dd.appsec.enabled': 1,
|
|
80
80
|
'_dd.runtime_family': 'nodejs',
|
|
81
81
|
[HTTP_CLIENT_IP]: clientIp
|
|
@@ -97,7 +97,7 @@ function incomingHttpStartTranslator ({ req, res, abortController }) {
|
|
|
97
97
|
|
|
98
98
|
for (const entry of results) {
|
|
99
99
|
if (entry && entry.includes('block')) {
|
|
100
|
-
block(req, res,
|
|
100
|
+
block(req, res, rootSpan, abortController)
|
|
101
101
|
break
|
|
102
102
|
}
|
|
103
103
|
}
|