dd-trace 4.20.0 → 4.22.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/index.d.ts +29 -0
- package/package.json +8 -7
- package/packages/datadog-instrumentations/src/aerospike.js +47 -0
- package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
- package/packages/datadog-instrumentations/src/graphql.js +18 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/http/client.js +10 -0
- package/packages/datadog-instrumentations/src/jest.js +11 -5
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/next.js +18 -6
- package/packages/datadog-instrumentations/src/restify.js +1 -1
- package/packages/datadog-instrumentations/src/rhea.js +15 -9
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +26 -18
- package/packages/datadog-plugin-http/src/client.js +19 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +51 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +55 -0
- package/packages/datadog-plugin-next/src/index.js +40 -14
- package/packages/dd-trace/src/appsec/activation.js +29 -0
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +48 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
- package/packages/dd-trace/src/appsec/blocking.js +95 -43
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/graphql.js +146 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +105 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +12 -19
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +20 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +6 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +18 -25
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +79 -85
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +27 -36
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +14 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +32 -31
- package/packages/dd-trace/src/appsec/recommended.json +1395 -2
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +36 -15
- package/packages/dd-trace/src/appsec/reporter.js +19 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +28 -13
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +17 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +75 -56
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +15 -9
- package/packages/dd-trace/src/config.js +36 -2
- package/packages/dd-trace/src/datastreams/processor.js +107 -12
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/git.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +3 -2
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +3 -2
- package/packages/dd-trace/src/profiler.js +5 -3
- package/packages/dd-trace/src/profiling/config.js +8 -0
- package/packages/dd-trace/src/profiling/profiler.js +17 -10
- package/packages/dd-trace/src/profiling/profilers/events.js +181 -83
- package/packages/dd-trace/src/profiling/profilers/shared.js +33 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +2 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +17 -12
- package/packages/dd-trace/src/proxy.js +25 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
- package/packages/dd-trace/src/spanleak.js +98 -0
- package/packages/dd-trace/src/startup-log.js +7 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +55 -9
- package/packages/dd-trace/src/telemetry/index.js +135 -43
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/send-data.js +47 -5
- package/packages/dd-trace/src/tracer.js +4 -0
- package/scripts/install_plugin_modules.js +11 -3
|
@@ -23,96 +23,90 @@ const NUMERIC_LITERAL =
|
|
|
23
23
|
})`
|
|
24
24
|
const ORACLE_ESCAPED_LITERAL = 'q\'<.*?>\'|q\'\\(.*?\\)\'|q\'\\{.*?\\}\'|q\'\\[.*?\\]\'|q\'(?<ESCAPE>.).*?\\k<ESCAPE>\''
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this._patterns.SQLITE = this._patterns.MYSQL
|
|
67
|
-
this._patterns.MARIADB = this._patterns.MYSQL
|
|
68
|
-
}
|
|
26
|
+
const patterns = {
|
|
27
|
+
ANSI: new RegExp( // Default
|
|
28
|
+
[
|
|
29
|
+
NUMERIC_LITERAL,
|
|
30
|
+
STRING_LITERAL,
|
|
31
|
+
LINE_COMMENT,
|
|
32
|
+
BLOCK_COMMENT
|
|
33
|
+
].join('|'),
|
|
34
|
+
'gmi'
|
|
35
|
+
),
|
|
36
|
+
MYSQL: new RegExp(
|
|
37
|
+
[
|
|
38
|
+
NUMERIC_LITERAL,
|
|
39
|
+
MYSQL_STRING_LITERAL,
|
|
40
|
+
LINE_COMMENT,
|
|
41
|
+
BLOCK_COMMENT
|
|
42
|
+
].join('|'),
|
|
43
|
+
'gmi'
|
|
44
|
+
),
|
|
45
|
+
POSTGRES: new RegExp(
|
|
46
|
+
[
|
|
47
|
+
NUMERIC_LITERAL,
|
|
48
|
+
POSTGRESQL_ESCAPED_LITERAL,
|
|
49
|
+
STRING_LITERAL,
|
|
50
|
+
LINE_COMMENT,
|
|
51
|
+
BLOCK_COMMENT
|
|
52
|
+
].join('|'),
|
|
53
|
+
'gmi'
|
|
54
|
+
),
|
|
55
|
+
ORACLE: new RegExp([
|
|
56
|
+
NUMERIC_LITERAL,
|
|
57
|
+
ORACLE_ESCAPED_LITERAL,
|
|
58
|
+
STRING_LITERAL,
|
|
59
|
+
LINE_COMMENT,
|
|
60
|
+
BLOCK_COMMENT
|
|
61
|
+
].join('|'),
|
|
62
|
+
'gmi')
|
|
63
|
+
}
|
|
64
|
+
patterns.SQLITE = patterns.MYSQL
|
|
65
|
+
patterns.MARIADB = patterns.MYSQL
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
module.exports = function extractSensitiveRanges (evidence) {
|
|
68
|
+
try {
|
|
69
|
+
let pattern = patterns[evidence.dialect]
|
|
70
|
+
if (!pattern) {
|
|
71
|
+
pattern = patterns['ANSI']
|
|
72
|
+
}
|
|
73
|
+
pattern.lastIndex = 0
|
|
74
|
+
const tokens = []
|
|
78
75
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
76
|
+
let regexResult = pattern.exec(evidence.value)
|
|
77
|
+
while (regexResult != null) {
|
|
78
|
+
let start = regexResult.index
|
|
79
|
+
let end = regexResult.index + regexResult[0].length
|
|
80
|
+
const startChar = evidence.value.charAt(start)
|
|
81
|
+
if (startChar === '\'' || startChar === '"') {
|
|
82
|
+
start++
|
|
83
|
+
end--
|
|
84
|
+
} else if (end > start + 1) {
|
|
85
|
+
const nextChar = evidence.value.charAt(start + 1)
|
|
86
|
+
if (startChar === '/' && nextChar === '*') {
|
|
87
|
+
start += 2
|
|
88
|
+
end -= 2
|
|
89
|
+
} else if (startChar === '-' && startChar === nextChar) {
|
|
90
|
+
start += 2
|
|
91
|
+
} else if (startChar.toLowerCase() === 'q' && nextChar === '\'') {
|
|
92
|
+
start += 3
|
|
93
|
+
end -= 2
|
|
94
|
+
} else if (startChar === '$') {
|
|
95
|
+
const match = regexResult[0]
|
|
96
|
+
const size = match.indexOf('$', 1) + 1
|
|
97
|
+
if (size > 1) {
|
|
98
|
+
start += size
|
|
99
|
+
end -= size
|
|
104
100
|
}
|
|
105
101
|
}
|
|
106
|
-
|
|
107
|
-
tokens.push({ start, end })
|
|
108
|
-
regexResult = pattern.exec(evidence.value)
|
|
109
102
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
|
|
104
|
+
tokens.push({ start, end })
|
|
105
|
+
regexResult = pattern.exec(evidence.value)
|
|
113
106
|
}
|
|
114
|
-
return
|
|
107
|
+
return tokens
|
|
108
|
+
} catch (e) {
|
|
109
|
+
iastLog.debug(e)
|
|
115
110
|
}
|
|
111
|
+
return []
|
|
116
112
|
}
|
|
117
|
-
|
|
118
|
-
module.exports = SqlSensitiveAnalyzer
|
|
@@ -4,46 +4,37 @@ const iastLog = require('../../../iast-log')
|
|
|
4
4
|
|
|
5
5
|
const AUTHORITY = '^(?:[^:]+:)?//([^@]+)@'
|
|
6
6
|
const QUERY_FRAGMENT = '[?#&]([^=&;]+)=([^?#&]+)'
|
|
7
|
+
const pattern = new RegExp([AUTHORITY, QUERY_FRAGMENT].join('|'), 'gmi')
|
|
8
|
+
|
|
9
|
+
module.exports = function extractSensitiveRanges (evidence) {
|
|
10
|
+
try {
|
|
11
|
+
const ranges = []
|
|
12
|
+
let regexResult = pattern.exec(evidence.value)
|
|
13
|
+
|
|
14
|
+
while (regexResult != null) {
|
|
15
|
+
if (typeof regexResult[1] === 'string') {
|
|
16
|
+
// AUTHORITY regex match always ends by group + @
|
|
17
|
+
// it means that the match last chars - 1 are always the group
|
|
18
|
+
const end = regexResult.index + (regexResult[0].length - 1)
|
|
19
|
+
const start = end - regexResult[1].length
|
|
20
|
+
ranges.push({ start, end })
|
|
21
|
+
}
|
|
7
22
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
const pattern = this._pattern
|
|
16
|
-
|
|
17
|
-
const ranges = []
|
|
18
|
-
let regexResult = pattern.exec(evidence.value)
|
|
19
|
-
|
|
20
|
-
while (regexResult != null) {
|
|
21
|
-
if (typeof regexResult[1] === 'string') {
|
|
22
|
-
// AUTHORITY regex match always ends by group + @
|
|
23
|
-
// it means that the match last chars - 1 are always the group
|
|
24
|
-
const end = regexResult.index + (regexResult[0].length - 1)
|
|
25
|
-
const start = end - regexResult[1].length
|
|
26
|
-
ranges.push({ start, end })
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (typeof regexResult[3] === 'string') {
|
|
30
|
-
// QUERY_FRAGMENT regex always ends with the group
|
|
31
|
-
// it means that the match last chars are always the group
|
|
32
|
-
const end = regexResult.index + regexResult[0].length
|
|
33
|
-
const start = end - regexResult[3].length
|
|
34
|
-
ranges.push({ start, end })
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
regexResult = pattern.exec(evidence.value)
|
|
23
|
+
if (typeof regexResult[3] === 'string') {
|
|
24
|
+
// QUERY_FRAGMENT regex always ends with the group
|
|
25
|
+
// it means that the match last chars are always the group
|
|
26
|
+
const end = regexResult.index + regexResult[0].length
|
|
27
|
+
const start = end - regexResult[3].length
|
|
28
|
+
ranges.push({ start, end })
|
|
38
29
|
}
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
} catch (e) {
|
|
42
|
-
iastLog.debug(e)
|
|
31
|
+
regexResult = pattern.exec(evidence.value)
|
|
43
32
|
}
|
|
44
33
|
|
|
45
|
-
return
|
|
34
|
+
return ranges
|
|
35
|
+
} catch (e) {
|
|
36
|
+
iastLog.debug(e)
|
|
46
37
|
}
|
|
47
|
-
}
|
|
48
38
|
|
|
49
|
-
|
|
39
|
+
return []
|
|
40
|
+
}
|
|
@@ -5,11 +5,12 @@ const vulnerabilities = require('../../vulnerabilities')
|
|
|
5
5
|
|
|
6
6
|
const { contains, intersects, remove } = require('./range-utils')
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
8
|
+
const commandSensitiveAnalyzer = require('./sensitive-analyzers/command-sensitive-analyzer')
|
|
9
|
+
const headerSensitiveAnalyzer = require('./sensitive-analyzers/header-sensitive-analyzer')
|
|
10
|
+
const jsonSensitiveAnalyzer = require('./sensitive-analyzers/json-sensitive-analyzer')
|
|
11
|
+
const ldapSensitiveAnalyzer = require('./sensitive-analyzers/ldap-sensitive-analyzer')
|
|
12
|
+
const sqlSensitiveAnalyzer = require('./sensitive-analyzers/sql-sensitive-analyzer')
|
|
13
|
+
const urlSensitiveAnalyzer = require('./sensitive-analyzers/url-sensitive-analyzer')
|
|
13
14
|
|
|
14
15
|
const { DEFAULT_IAST_REDACTION_NAME_PATTERN, DEFAULT_IAST_REDACTION_VALUE_PATTERN } = require('./sensitive-regex')
|
|
15
16
|
|
|
@@ -21,13 +22,15 @@ class SensitiveHandler {
|
|
|
21
22
|
this._valuePattern = new RegExp(DEFAULT_IAST_REDACTION_VALUE_PATTERN, 'gmi')
|
|
22
23
|
|
|
23
24
|
this._sensitiveAnalyzers = new Map()
|
|
24
|
-
this._sensitiveAnalyzers.set(vulnerabilities.COMMAND_INJECTION,
|
|
25
|
-
this._sensitiveAnalyzers.set(vulnerabilities.NOSQL_MONGODB_INJECTION,
|
|
26
|
-
this._sensitiveAnalyzers.set(vulnerabilities.LDAP_INJECTION,
|
|
27
|
-
this._sensitiveAnalyzers.set(vulnerabilities.SQL_INJECTION,
|
|
28
|
-
const urlSensitiveAnalyzer = new UrlSensitiveAnalyzer()
|
|
25
|
+
this._sensitiveAnalyzers.set(vulnerabilities.COMMAND_INJECTION, commandSensitiveAnalyzer)
|
|
26
|
+
this._sensitiveAnalyzers.set(vulnerabilities.NOSQL_MONGODB_INJECTION, jsonSensitiveAnalyzer)
|
|
27
|
+
this._sensitiveAnalyzers.set(vulnerabilities.LDAP_INJECTION, ldapSensitiveAnalyzer)
|
|
28
|
+
this._sensitiveAnalyzers.set(vulnerabilities.SQL_INJECTION, sqlSensitiveAnalyzer)
|
|
29
29
|
this._sensitiveAnalyzers.set(vulnerabilities.SSRF, urlSensitiveAnalyzer)
|
|
30
30
|
this._sensitiveAnalyzers.set(vulnerabilities.UNVALIDATED_REDIRECT, urlSensitiveAnalyzer)
|
|
31
|
+
this._sensitiveAnalyzers.set(vulnerabilities.HEADER_INJECTION, (evidence) => {
|
|
32
|
+
return headerSensitiveAnalyzer(evidence, this._namePattern, this._valuePattern)
|
|
33
|
+
})
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
isSensibleName (name) {
|
|
@@ -47,7 +50,7 @@ class SensitiveHandler {
|
|
|
47
50
|
scrubEvidence (vulnerabilityType, evidence, sourcesIndexes, sources) {
|
|
48
51
|
const sensitiveAnalyzer = this._sensitiveAnalyzers.get(vulnerabilityType)
|
|
49
52
|
if (sensitiveAnalyzer) {
|
|
50
|
-
const sensitiveRanges = sensitiveAnalyzer
|
|
53
|
+
const sensitiveRanges = sensitiveAnalyzer(evidence)
|
|
51
54
|
return this.toRedactedJson(evidence, sensitiveRanges, sourcesIndexes, sources)
|
|
52
55
|
}
|
|
53
56
|
return null
|
|
@@ -6,7 +6,6 @@ const remoteConfig = require('./remote_config')
|
|
|
6
6
|
const {
|
|
7
7
|
bodyParser,
|
|
8
8
|
cookieParser,
|
|
9
|
-
graphqlFinishExecute,
|
|
10
9
|
incomingHttpRequestStart,
|
|
11
10
|
incomingHttpRequestEnd,
|
|
12
11
|
passportVerify,
|
|
@@ -18,12 +17,14 @@ const waf = require('./waf')
|
|
|
18
17
|
const addresses = require('./addresses')
|
|
19
18
|
const Reporter = require('./reporter')
|
|
20
19
|
const appsecTelemetry = require('./telemetry')
|
|
20
|
+
const apiSecuritySampler = require('./api_security_sampler')
|
|
21
21
|
const web = require('../plugins/util/web')
|
|
22
22
|
const { extractIp } = require('../plugins/util/ip_extractor')
|
|
23
23
|
const { HTTP_CLIENT_IP } = require('../../../../ext/tags')
|
|
24
24
|
const { block, setTemplates } = require('./blocking')
|
|
25
25
|
const { passportTrackEvent } = require('./passport')
|
|
26
26
|
const { storage } = require('../../../datadog-core')
|
|
27
|
+
const graphql = require('./graphql')
|
|
27
28
|
|
|
28
29
|
let isEnabled = false
|
|
29
30
|
let config
|
|
@@ -33,6 +34,7 @@ function enable (_config) {
|
|
|
33
34
|
|
|
34
35
|
try {
|
|
35
36
|
appsecTelemetry.enable(_config.telemetry)
|
|
37
|
+
graphql.enable()
|
|
36
38
|
|
|
37
39
|
setTemplates(_config)
|
|
38
40
|
|
|
@@ -42,6 +44,8 @@ function enable (_config) {
|
|
|
42
44
|
|
|
43
45
|
Reporter.setRateLimit(_config.appsec.rateLimit)
|
|
44
46
|
|
|
47
|
+
apiSecuritySampler.configure(_config.appsec)
|
|
48
|
+
|
|
45
49
|
incomingHttpRequestStart.subscribe(incomingHttpStartTranslator)
|
|
46
50
|
incomingHttpRequestEnd.subscribe(incomingHttpEndTranslator)
|
|
47
51
|
bodyParser.subscribe(onRequestBodyParsed)
|
|
@@ -49,7 +53,6 @@ function enable (_config) {
|
|
|
49
53
|
nextQueryParsed.subscribe(onRequestQueryParsed)
|
|
50
54
|
queryParser.subscribe(onRequestQueryParsed)
|
|
51
55
|
cookieParser.subscribe(onRequestCookieParser)
|
|
52
|
-
graphqlFinishExecute.subscribe(onGraphqlFinishExecute)
|
|
53
56
|
|
|
54
57
|
if (_config.appsec.eventTracking.enabled) {
|
|
55
58
|
passportVerify.subscribe(onPassportVerify)
|
|
@@ -80,17 +83,21 @@ function incomingHttpStartTranslator ({ req, res, abortController }) {
|
|
|
80
83
|
const requestHeaders = Object.assign({}, req.headers)
|
|
81
84
|
delete requestHeaders.cookie
|
|
82
85
|
|
|
83
|
-
const
|
|
86
|
+
const persistent = {
|
|
84
87
|
[addresses.HTTP_INCOMING_URL]: req.url,
|
|
85
88
|
[addresses.HTTP_INCOMING_HEADERS]: requestHeaders,
|
|
86
89
|
[addresses.HTTP_INCOMING_METHOD]: req.method
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
if (clientIp) {
|
|
90
|
-
|
|
93
|
+
persistent[addresses.HTTP_CLIENT_IP] = clientIp
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (apiSecuritySampler.sampleRequest()) {
|
|
97
|
+
persistent[addresses.WAF_CONTEXT_PROCESSOR] = { 'extract-schema': true }
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
const actions = waf.run(
|
|
100
|
+
const actions = waf.run({ persistent }, req)
|
|
94
101
|
|
|
95
102
|
handleResults(actions, req, res, rootSpan, abortController)
|
|
96
103
|
}
|
|
@@ -100,32 +107,32 @@ function incomingHttpEndTranslator ({ req, res }) {
|
|
|
100
107
|
const responseHeaders = Object.assign({}, res.getHeaders())
|
|
101
108
|
delete responseHeaders['set-cookie']
|
|
102
109
|
|
|
103
|
-
const
|
|
104
|
-
[addresses.HTTP_INCOMING_RESPONSE_CODE]: res.statusCode,
|
|
110
|
+
const persistent = {
|
|
111
|
+
[addresses.HTTP_INCOMING_RESPONSE_CODE]: '' + res.statusCode,
|
|
105
112
|
[addresses.HTTP_INCOMING_RESPONSE_HEADERS]: responseHeaders
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
// we need to keep this to support other body parsers
|
|
109
116
|
// TODO: no need to analyze it if it was already done by the body-parser hook
|
|
110
117
|
if (req.body !== undefined && req.body !== null) {
|
|
111
|
-
|
|
118
|
+
persistent[addresses.HTTP_INCOMING_BODY] = req.body
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
// TODO: temporary express instrumentation, will use express plugin later
|
|
115
122
|
if (req.params && typeof req.params === 'object') {
|
|
116
|
-
|
|
123
|
+
persistent[addresses.HTTP_INCOMING_PARAMS] = req.params
|
|
117
124
|
}
|
|
118
125
|
|
|
119
126
|
// we need to keep this to support other cookie parsers
|
|
120
127
|
if (req.cookies && typeof req.cookies === 'object') {
|
|
121
|
-
|
|
128
|
+
persistent[addresses.HTTP_INCOMING_COOKIES] = req.cookies
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
if (req.query && typeof req.query === 'object') {
|
|
125
|
-
|
|
132
|
+
persistent[addresses.HTTP_INCOMING_QUERY] = req.query
|
|
126
133
|
}
|
|
127
134
|
|
|
128
|
-
waf.run(
|
|
135
|
+
waf.run({ persistent }, req)
|
|
129
136
|
|
|
130
137
|
waf.disposeContext(req)
|
|
131
138
|
|
|
@@ -144,7 +151,9 @@ function onRequestBodyParsed ({ req, res, body, abortController }) {
|
|
|
144
151
|
if (!rootSpan) return
|
|
145
152
|
|
|
146
153
|
const results = waf.run({
|
|
147
|
-
|
|
154
|
+
persistent: {
|
|
155
|
+
[addresses.HTTP_INCOMING_BODY]: body
|
|
156
|
+
}
|
|
148
157
|
}, req)
|
|
149
158
|
|
|
150
159
|
handleResults(results, req, res, rootSpan, abortController)
|
|
@@ -162,7 +171,9 @@ function onRequestQueryParsed ({ req, res, query, abortController }) {
|
|
|
162
171
|
if (!rootSpan) return
|
|
163
172
|
|
|
164
173
|
const results = waf.run({
|
|
165
|
-
|
|
174
|
+
persistent: {
|
|
175
|
+
[addresses.HTTP_INCOMING_QUERY]: query
|
|
176
|
+
}
|
|
166
177
|
}, req)
|
|
167
178
|
|
|
168
179
|
handleResults(results, req, res, rootSpan, abortController)
|
|
@@ -175,7 +186,9 @@ function onRequestCookieParser ({ req, res, abortController, cookies }) {
|
|
|
175
186
|
if (!rootSpan) return
|
|
176
187
|
|
|
177
188
|
const results = waf.run({
|
|
178
|
-
|
|
189
|
+
persistent: {
|
|
190
|
+
[addresses.HTTP_INCOMING_COOKIES]: cookies
|
|
191
|
+
}
|
|
179
192
|
}, req)
|
|
180
193
|
|
|
181
194
|
handleResults(results, req, res, rootSpan, abortController)
|
|
@@ -183,7 +196,7 @@ function onRequestCookieParser ({ req, res, abortController, cookies }) {
|
|
|
183
196
|
|
|
184
197
|
function onPassportVerify ({ credentials, user }) {
|
|
185
198
|
const store = storage.getStore()
|
|
186
|
-
const rootSpan = store
|
|
199
|
+
const rootSpan = store?.req && web.root(store.req)
|
|
187
200
|
|
|
188
201
|
if (!rootSpan) {
|
|
189
202
|
log.warn('No rootSpan found in onPassportVerify')
|
|
@@ -193,20 +206,6 @@ function onPassportVerify ({ credentials, user }) {
|
|
|
193
206
|
passportTrackEvent(credentials, user, rootSpan, config.appsec.eventTracking.mode)
|
|
194
207
|
}
|
|
195
208
|
|
|
196
|
-
function onGraphqlFinishExecute ({ context }) {
|
|
197
|
-
const store = storage.getStore()
|
|
198
|
-
const req = store?.req
|
|
199
|
-
|
|
200
|
-
if (!req) return
|
|
201
|
-
|
|
202
|
-
const resolvers = context?.resolvers
|
|
203
|
-
|
|
204
|
-
if (!resolvers || typeof resolvers !== 'object') return
|
|
205
|
-
|
|
206
|
-
// Don't collect blocking result because it only works in monitor mode.
|
|
207
|
-
waf.run({ [addresses.HTTP_INCOMING_GRAPHQL_RESOLVERS]: resolvers }, req)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
209
|
function handleResults (actions, req, res, rootSpan, abortController) {
|
|
211
210
|
if (!actions || !req || !res || !rootSpan || !abortController) return
|
|
212
211
|
|
|
@@ -222,12 +221,14 @@ function disable () {
|
|
|
222
221
|
RuleManager.clearAllRules()
|
|
223
222
|
|
|
224
223
|
appsecTelemetry.disable()
|
|
224
|
+
graphql.disable()
|
|
225
225
|
|
|
226
226
|
remoteConfig.disableWafUpdate()
|
|
227
227
|
|
|
228
|
+
apiSecuritySampler.disable()
|
|
229
|
+
|
|
228
230
|
// Channel#unsubscribe() is undefined for non active channels
|
|
229
231
|
if (bodyParser.hasSubscribers) bodyParser.unsubscribe(onRequestBodyParsed)
|
|
230
|
-
if (graphqlFinishExecute.hasSubscribers) graphqlFinishExecute.unsubscribe(onGraphqlFinishExecute)
|
|
231
232
|
if (incomingHttpRequestStart.hasSubscribers) incomingHttpRequestStart.unsubscribe(incomingHttpStartTranslator)
|
|
232
233
|
if (incomingHttpRequestEnd.hasSubscribers) incomingHttpRequestEnd.unsubscribe(incomingHttpEndTranslator)
|
|
233
234
|
if (queryParser.hasSubscribers) queryParser.unsubscribe(onRequestQueryParsed)
|