dd-trace 4.18.0 → 4.23.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 +3 -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 +29 -0
- package/package.json +12 -11
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-esbuild/index.js +1 -20
- 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/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/couchbase.js +5 -4
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/graphql.js +18 -4
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +10 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +19 -3
- package/packages/datadog-instrumentations/src/http/client.js +12 -2
- package/packages/datadog-instrumentations/src/http/server.js +7 -4
- package/packages/datadog-instrumentations/src/http2/client.js +3 -1
- package/packages/datadog-instrumentations/src/http2/server.js +3 -1
- package/packages/datadog-instrumentations/src/jest.js +12 -6
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-instrumentations/src/next.js +18 -6
- package/packages/datadog-instrumentations/src/restify.js +14 -1
- package/packages/datadog-instrumentations/src/rhea.js +15 -9
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-cucumber/src/index.js +34 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
- package/packages/datadog-plugin-graphql/src/resolve.js +26 -18
- package/packages/datadog-plugin-http/src/client.js +19 -2
- package/packages/datadog-plugin-jest/src/index.js +38 -4
- package/packages/datadog-plugin-kafkajs/src/consumer.js +59 -6
- package/packages/datadog-plugin-kafkajs/src/producer.js +64 -6
- package/packages/datadog-plugin-mocha/src/index.js +32 -1
- package/packages/datadog-plugin-next/src/index.js +40 -14
- package/packages/datadog-plugin-playwright/src/index.js +17 -1
- 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 +5 -2
- 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/iast-log.js +1 -1
- 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 +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- 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 +33 -32
- package/packages/dd-trace/src/appsec/recommended.json +1737 -120
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +40 -15
- package/packages/dd-trace/src/appsec/reporter.js +50 -34
- package/packages/dd-trace/src/appsec/rule_manager.js +9 -6
- 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/agentless/coverage-writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -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 +110 -59
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +40 -7
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +26 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
- package/packages/dd-trace/src/config.js +145 -63
- package/packages/dd-trace/src/datastreams/processor.js +166 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
- package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
- package/packages/dd-trace/src/format.js +6 -1
- package/packages/dd-trace/src/id.js +12 -0
- package/packages/dd-trace/src/iitm.js +1 -1
- package/packages/dd-trace/src/log/channels.js +1 -1
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- 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/propagation/text_map.js +14 -5
- package/packages/dd-trace/src/opentracing/span.js +6 -0
- package/packages/dd-trace/src/opentracing/span_context.js +5 -2
- package/packages/dd-trace/src/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +46 -9
- package/packages/dd-trace/src/plugins/database.js +1 -1
- package/packages/dd-trace/src/plugins/index.js +6 -0
- 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/exec.js +23 -2
- package/packages/dd-trace/src/plugins/util/git.js +98 -22
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
- package/packages/dd-trace/src/plugins/util/test.js +3 -2
- package/packages/dd-trace/src/plugins/util/url.js +26 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +4 -16
- package/packages/dd-trace/src/priority_sampler.js +30 -38
- package/packages/dd-trace/src/profiler.js +5 -3
- package/packages/dd-trace/src/profiling/config.js +26 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/profiler.js +17 -10
- package/packages/dd-trace/src/profiling/profilers/events.js +264 -0
- package/packages/dd-trace/src/profiling/profilers/shared.js +39 -0
- package/packages/dd-trace/src/profiling/profilers/space.js +2 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +121 -58
- package/packages/dd-trace/src/proxy.js +25 -1
- package/packages/dd-trace/src/ritm.js +1 -1
- package/packages/dd-trace/src/sampling_rule.js +130 -0
- 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/span_processor.js +4 -0
- package/packages/dd-trace/src/span_sampler.js +6 -64
- 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 +56 -10
- package/packages/dd-trace/src/telemetry/index.js +171 -41
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +47 -5
- package/packages/dd-trace/src/tracer.js +8 -2
- package/scripts/install_plugin_modules.js +11 -3
- package/packages/diagnostics_channel/index.js +0 -3
- package/packages/diagnostics_channel/src/index.js +0 -121
|
@@ -9,5 +9,10 @@ module.exports = {
|
|
|
9
9
|
ASM_USER_BLOCKING: 1n << 7n,
|
|
10
10
|
ASM_CUSTOM_RULES: 1n << 8n,
|
|
11
11
|
ASM_CUSTOM_BLOCKING_RESPONSE: 1n << 9n,
|
|
12
|
-
ASM_TRUSTED_IPS: 1n << 10n
|
|
12
|
+
ASM_TRUSTED_IPS: 1n << 10n,
|
|
13
|
+
ASM_API_SECURITY_SAMPLE_RATE: 1n << 11n,
|
|
14
|
+
APM_TRACING_SAMPLE_RATE: 1n << 12n,
|
|
15
|
+
APM_TRACING_LOGS_INJECTION: 1n << 13n,
|
|
16
|
+
APM_TRACING_HTTP_HEADER_TAGS: 1n << 14n,
|
|
17
|
+
APM_TRACING_CUSTOM_TAGS: 1n << 15n
|
|
13
18
|
}
|
|
@@ -1,38 +1,63 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const Activation = require('../activation')
|
|
4
|
+
|
|
3
5
|
const RemoteConfigManager = require('./manager')
|
|
4
6
|
const RemoteConfigCapabilities = require('./capabilities')
|
|
7
|
+
const apiSecuritySampler = require('../api_security_sampler')
|
|
5
8
|
|
|
6
9
|
let rc
|
|
7
10
|
|
|
8
11
|
function enable (config) {
|
|
9
12
|
rc = new RemoteConfigManager(config)
|
|
13
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_CUSTOM_TAGS, true)
|
|
14
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_HTTP_HEADER_TAGS, true)
|
|
15
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
|
|
16
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
17
|
+
|
|
18
|
+
const activation = Activation.fromConfig(config)
|
|
10
19
|
|
|
11
|
-
if (
|
|
12
|
-
|
|
20
|
+
if (activation !== Activation.DISABLED) {
|
|
21
|
+
if (activation === Activation.ONECLICK) {
|
|
22
|
+
rc.updateCapabilities(RemoteConfigCapabilities.ASM_ACTIVATION, true)
|
|
23
|
+
}
|
|
13
24
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
if (config.appsec.apiSecurity?.enabled) {
|
|
26
|
+
rc.updateCapabilities(RemoteConfigCapabilities.ASM_API_SECURITY_SAMPLE_RATE, true)
|
|
27
|
+
}
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} else {
|
|
21
|
-
shouldEnable = config.appsec.enabled // give back control to local config
|
|
22
|
-
}
|
|
29
|
+
rc.on('ASM_FEATURES', (action, rcConfig) => {
|
|
30
|
+
if (!rcConfig) return
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} else {
|
|
27
|
-
require('..').disable()
|
|
28
|
-
}
|
|
32
|
+
if (activation === Activation.ONECLICK) {
|
|
33
|
+
enableOrDisableAppsec(action, rcConfig, config)
|
|
29
34
|
}
|
|
35
|
+
|
|
36
|
+
apiSecuritySampler.setRequestSampling(rcConfig.api_security?.request_sample_rate)
|
|
30
37
|
})
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
return rc
|
|
34
41
|
}
|
|
35
42
|
|
|
43
|
+
function enableOrDisableAppsec (action, rcConfig, config) {
|
|
44
|
+
if (typeof rcConfig.asm?.enabled === 'boolean') {
|
|
45
|
+
let shouldEnable
|
|
46
|
+
|
|
47
|
+
if (action === 'apply' || action === 'modify') {
|
|
48
|
+
shouldEnable = rcConfig.asm.enabled // take control
|
|
49
|
+
} else {
|
|
50
|
+
shouldEnable = config.appsec.enabled // give back control to local config
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (shouldEnable) {
|
|
54
|
+
require('..').enable(config)
|
|
55
|
+
} else {
|
|
56
|
+
require('..').disable()
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
36
61
|
function enableWafUpdate (appsecConfig) {
|
|
37
62
|
if (rc && appsecConfig && !appsecConfig.customRulesProvided) {
|
|
38
63
|
// dirty require to make startup faster for serverless
|
|
@@ -3,64 +3,61 @@
|
|
|
3
3
|
const Limiter = require('../rate_limiter')
|
|
4
4
|
const { storage } = require('../../../datadog-core')
|
|
5
5
|
const web = require('../plugins/util/web')
|
|
6
|
+
const { ipHeaderList } = require('../plugins/util/ip_extractor')
|
|
6
7
|
const {
|
|
7
8
|
incrementWafInitMetric,
|
|
8
9
|
updateWafRequestsMetricTags,
|
|
9
10
|
incrementWafUpdatesMetric,
|
|
10
11
|
incrementWafRequestsMetric
|
|
11
12
|
} = require('./telemetry')
|
|
13
|
+
const zlib = require('zlib')
|
|
12
14
|
|
|
13
15
|
// default limiter, configurable with setRateLimit()
|
|
14
16
|
let limiter = new Limiter(100)
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'accept-encoding',
|
|
20
|
-
'accept-language',
|
|
18
|
+
const metricsQueue = new Map()
|
|
19
|
+
|
|
20
|
+
const contentHeaderList = [
|
|
21
21
|
'content-encoding',
|
|
22
22
|
'content-language',
|
|
23
23
|
'content-length',
|
|
24
|
-
'content-type'
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
'content-type'
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const REQUEST_HEADERS_MAP = mapHeaderAndTags([
|
|
28
|
+
'accept',
|
|
29
|
+
'accept-encoding',
|
|
30
|
+
'accept-language',
|
|
27
31
|
'host',
|
|
28
|
-
'true-client-ip',
|
|
29
32
|
'user-agent',
|
|
33
|
+
'forwarded',
|
|
30
34
|
'via',
|
|
31
|
-
'x-client-ip',
|
|
32
|
-
'x-cluster-client-ip',
|
|
33
|
-
'x-forwarded',
|
|
34
|
-
'x-forwarded-for',
|
|
35
|
-
'x-real-ip'
|
|
36
|
-
]
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'content-length',
|
|
42
|
-
'content-type'
|
|
43
|
-
]
|
|
36
|
+
...ipHeaderList,
|
|
37
|
+
...contentHeaderList
|
|
38
|
+
], 'http.request.headers.')
|
|
44
39
|
|
|
45
|
-
const
|
|
40
|
+
const RESPONSE_HEADERS_MAP = mapHeaderAndTags(contentHeaderList, 'http.response.headers.')
|
|
46
41
|
|
|
47
|
-
function
|
|
42
|
+
function mapHeaderAndTags (headerList, tagPrefix) {
|
|
43
|
+
return new Map(headerList.map(headerName => [headerName, `${tagPrefix}${formatHeaderName(headerName)}`]))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function filterHeaders (headers, map) {
|
|
48
47
|
const result = {}
|
|
49
48
|
|
|
50
49
|
if (!headers) return result
|
|
51
50
|
|
|
52
|
-
for (
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
result[`${prefix}${formatHeaderName(headerName)}`] = '' + headers[headerName]
|
|
51
|
+
for (const [headerName, tagName] of map) {
|
|
52
|
+
const headerValue = headers[headerName]
|
|
53
|
+
if (headerValue) {
|
|
54
|
+
result[tagName] = '' + headerValue
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
return result
|
|
61
59
|
}
|
|
62
60
|
|
|
63
|
-
// TODO: this can be precomputed at start time
|
|
64
61
|
function formatHeaderName (name) {
|
|
65
62
|
return name
|
|
66
63
|
.trim()
|
|
@@ -86,7 +83,7 @@ function reportWafInit (wafVersion, rulesVersion, diagnosticsRules = {}) {
|
|
|
86
83
|
function reportMetrics (metrics) {
|
|
87
84
|
// TODO: metrics should be incremental, there already is an RFC to report metrics
|
|
88
85
|
const store = storage.getStore()
|
|
89
|
-
const rootSpan = store
|
|
86
|
+
const rootSpan = store?.req && web.root(store.req)
|
|
90
87
|
if (!rootSpan) return
|
|
91
88
|
|
|
92
89
|
if (metrics.duration) {
|
|
@@ -106,13 +103,13 @@ function reportMetrics (metrics) {
|
|
|
106
103
|
|
|
107
104
|
function reportAttack (attackData) {
|
|
108
105
|
const store = storage.getStore()
|
|
109
|
-
const req = store
|
|
106
|
+
const req = store?.req
|
|
110
107
|
const rootSpan = web.root(req)
|
|
111
108
|
if (!rootSpan) return
|
|
112
109
|
|
|
113
110
|
const currentTags = rootSpan.context()._tags
|
|
114
111
|
|
|
115
|
-
const newTags = filterHeaders(req.headers,
|
|
112
|
+
const newTags = filterHeaders(req.headers, REQUEST_HEADERS_MAP)
|
|
116
113
|
|
|
117
114
|
newTags['appsec.event'] = 'true'
|
|
118
115
|
|
|
@@ -144,6 +141,23 @@ function reportAttack (attackData) {
|
|
|
144
141
|
rootSpan.addTags(newTags)
|
|
145
142
|
}
|
|
146
143
|
|
|
144
|
+
function reportSchemas (derivatives) {
|
|
145
|
+
if (!derivatives) return
|
|
146
|
+
|
|
147
|
+
const req = storage.getStore()?.req
|
|
148
|
+
const rootSpan = web.root(req)
|
|
149
|
+
|
|
150
|
+
if (!rootSpan) return
|
|
151
|
+
|
|
152
|
+
const tags = {}
|
|
153
|
+
for (const [address, value] of Object.entries(derivatives)) {
|
|
154
|
+
const gzippedValue = zlib.gzipSync(JSON.stringify(value))
|
|
155
|
+
tags[address] = gzippedValue.toString('base64')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
rootSpan.addTags(tags)
|
|
159
|
+
}
|
|
160
|
+
|
|
147
161
|
function finishRequest (req, res) {
|
|
148
162
|
const rootSpan = web.root(req)
|
|
149
163
|
if (!rootSpan) return
|
|
@@ -158,7 +172,7 @@ function finishRequest (req, res) {
|
|
|
158
172
|
|
|
159
173
|
if (!rootSpan.context()._tags['appsec.event']) return
|
|
160
174
|
|
|
161
|
-
const newTags = filterHeaders(res.getHeaders(),
|
|
175
|
+
const newTags = filterHeaders(res.getHeaders(), RESPONSE_HEADERS_MAP)
|
|
162
176
|
|
|
163
177
|
if (req.route && typeof req.route.path === 'string') {
|
|
164
178
|
newTags['http.endpoint'] = req.route.path
|
|
@@ -179,6 +193,8 @@ module.exports = {
|
|
|
179
193
|
reportMetrics,
|
|
180
194
|
reportAttack,
|
|
181
195
|
reportWafUpdate: incrementWafUpdatesMetric,
|
|
196
|
+
reportSchemas,
|
|
182
197
|
finishRequest,
|
|
183
|
-
setRateLimit
|
|
198
|
+
setRateLimit,
|
|
199
|
+
mapHeaderAndTags
|
|
184
200
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const fs = require('fs')
|
|
3
4
|
const waf = require('./waf')
|
|
4
5
|
const { ACKNOWLEDGED, ERROR } = require('./remote_config/apply_states')
|
|
5
6
|
const blocking = require('./blocking')
|
|
@@ -13,13 +14,15 @@ let appliedExclusions = new Map()
|
|
|
13
14
|
let appliedCustomRules = new Map()
|
|
14
15
|
let appliedActions = new Map()
|
|
15
16
|
|
|
16
|
-
function
|
|
17
|
-
defaultRules = rules
|
|
17
|
+
function loadRules (config) {
|
|
18
|
+
defaultRules = config.rules
|
|
19
|
+
? JSON.parse(fs.readFileSync(config.rules))
|
|
20
|
+
: require('./recommended.json')
|
|
18
21
|
|
|
19
|
-
waf.init(
|
|
22
|
+
waf.init(defaultRules, config)
|
|
20
23
|
|
|
21
|
-
if (
|
|
22
|
-
blocking.updateBlockingConfiguration(
|
|
24
|
+
if (defaultRules.actions) {
|
|
25
|
+
blocking.updateBlockingConfiguration(defaultRules.actions.find(action => action.id === 'block'))
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
@@ -252,7 +255,7 @@ function clearAllRules () {
|
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
module.exports = {
|
|
255
|
-
|
|
258
|
+
loadRules,
|
|
256
259
|
updateWafFromRC,
|
|
257
260
|
clearAllRules
|
|
258
261
|
}
|
|
@@ -9,7 +9,7 @@ const { setUserTags } = require('./set_user')
|
|
|
9
9
|
const log = require('../../log')
|
|
10
10
|
|
|
11
11
|
function isUserBlocked (user) {
|
|
12
|
-
const actions = waf.run({ [USER_ID]: user.id })
|
|
12
|
+
const actions = waf.run({ persistent: { [USER_ID]: user.id } })
|
|
13
13
|
|
|
14
14
|
if (!actions) return false
|
|
15
15
|
|
|
@@ -10,37 +10,50 @@ const preventDuplicateAddresses = new Set([
|
|
|
10
10
|
])
|
|
11
11
|
|
|
12
12
|
class WAFContextWrapper {
|
|
13
|
-
constructor (ddwafContext,
|
|
13
|
+
constructor (ddwafContext, wafTimeout, wafVersion, rulesVersion) {
|
|
14
14
|
this.ddwafContext = ddwafContext
|
|
15
|
-
this.requiredAddresses = requiredAddresses
|
|
16
15
|
this.wafTimeout = wafTimeout
|
|
17
16
|
this.wafVersion = wafVersion
|
|
18
17
|
this.rulesVersion = rulesVersion
|
|
19
18
|
this.addressesToSkip = new Set()
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
run (
|
|
21
|
+
run ({ persistent, ephemeral }) {
|
|
22
|
+
const payload = {}
|
|
23
|
+
let payloadHasData = false
|
|
23
24
|
const inputs = {}
|
|
24
|
-
let someInputAdded = false
|
|
25
25
|
const newAddressesToSkip = new Set(this.addressesToSkip)
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
if (persistent && typeof persistent === 'object') {
|
|
28
|
+
// TODO: possible optimization: only send params that haven't already been sent with same value to this wafContext
|
|
29
|
+
for (const key of Object.keys(persistent)) {
|
|
30
|
+
// TODO: requiredAddresses is no longer used due to processor addresses are not included in the list. Check on
|
|
31
|
+
// future versions when the actual addresses are included in the 'loaded' section inside diagnostics.
|
|
32
|
+
if (!this.addressesToSkip.has(key)) {
|
|
33
|
+
inputs[key] = persistent[key]
|
|
34
|
+
if (preventDuplicateAddresses.has(key)) {
|
|
35
|
+
newAddressesToSkip.add(key)
|
|
36
|
+
}
|
|
33
37
|
}
|
|
34
|
-
someInputAdded = true
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
if (
|
|
41
|
+
if (Object.keys(inputs).length) {
|
|
42
|
+
payload['persistent'] = inputs
|
|
43
|
+
payloadHasData = true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (ephemeral && Object.keys(ephemeral).length) {
|
|
47
|
+
payload['ephemeral'] = ephemeral
|
|
48
|
+
payloadHasData = true
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!payloadHasData) return
|
|
39
52
|
|
|
40
53
|
try {
|
|
41
54
|
const start = process.hrtime.bigint()
|
|
42
55
|
|
|
43
|
-
const result = this.ddwafContext.run(
|
|
56
|
+
const result = this.ddwafContext.run(payload, this.wafTimeout)
|
|
44
57
|
|
|
45
58
|
const end = process.hrtime.bigint()
|
|
46
59
|
|
|
@@ -63,6 +76,8 @@ class WAFContextWrapper {
|
|
|
63
76
|
Reporter.reportAttack(JSON.stringify(result.events))
|
|
64
77
|
}
|
|
65
78
|
|
|
79
|
+
Reporter.reportSchemas(result.derivatives)
|
|
80
|
+
|
|
66
81
|
return result.actions
|
|
67
82
|
} catch (err) {
|
|
68
83
|
log.error('Error while running the AppSec WAF')
|
|
@@ -5,6 +5,16 @@ const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
|
5
5
|
|
|
6
6
|
const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
|
|
7
7
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
8
|
+
const {
|
|
9
|
+
incrementCountMetric,
|
|
10
|
+
distributionMetric,
|
|
11
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
|
|
12
|
+
TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
|
|
13
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
14
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
15
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
16
|
+
getErrorTypeFromStatusCode
|
|
17
|
+
} = require('../../../ci-visibility/telemetry')
|
|
8
18
|
|
|
9
19
|
class Writer extends BaseWriter {
|
|
10
20
|
constructor ({ url, evpProxyPrefix = '' }) {
|
|
@@ -34,8 +44,27 @@ class Writer extends BaseWriter {
|
|
|
34
44
|
|
|
35
45
|
log.debug(() => `Request to the intake: ${safeJSONStringify(options)}`)
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
const startRequestTime = Date.now()
|
|
48
|
+
|
|
49
|
+
incrementCountMetric(TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS, { endpoint: 'code_coverage' })
|
|
50
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_BYTES, { endpoint: 'code_coverage' }, form.size())
|
|
51
|
+
|
|
52
|
+
request(form, options, (err, res, statusCode) => {
|
|
53
|
+
distributionMetric(
|
|
54
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
55
|
+
{ endpoint: 'code_coverage' },
|
|
56
|
+
Date.now() - startRequestTime
|
|
57
|
+
)
|
|
38
58
|
if (err) {
|
|
59
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
60
|
+
incrementCountMetric(
|
|
61
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
62
|
+
{ endpoint: 'code_coverage', errorType }
|
|
63
|
+
)
|
|
64
|
+
incrementCountMetric(
|
|
65
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
66
|
+
{ endpoint: 'code_coverage' }
|
|
67
|
+
)
|
|
39
68
|
log.error(err)
|
|
40
69
|
done()
|
|
41
70
|
return
|
|
@@ -5,6 +5,16 @@ const log = require('../../../log')
|
|
|
5
5
|
|
|
6
6
|
const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility')
|
|
7
7
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
8
|
+
const {
|
|
9
|
+
incrementCountMetric,
|
|
10
|
+
distributionMetric,
|
|
11
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
|
|
12
|
+
TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
|
|
13
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
14
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
15
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
16
|
+
getErrorTypeFromStatusCode
|
|
17
|
+
} = require('../../../ci-visibility/telemetry')
|
|
8
18
|
|
|
9
19
|
class Writer extends BaseWriter {
|
|
10
20
|
constructor ({ url, tags, evpProxyPrefix = '' }) {
|
|
@@ -35,8 +45,27 @@ class Writer extends BaseWriter {
|
|
|
35
45
|
|
|
36
46
|
log.debug(() => `Request to the intake: ${safeJSONStringify(options)}`)
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
const startRequestTime = Date.now()
|
|
49
|
+
|
|
50
|
+
incrementCountMetric(TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS, { endpoint: 'test_cycle' })
|
|
51
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_BYTES, { endpoint: 'test_cycle' }, data.length)
|
|
52
|
+
|
|
53
|
+
request(data, options, (err, res, statusCode) => {
|
|
54
|
+
distributionMetric(
|
|
55
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
56
|
+
{ endpoint: 'test_cycle' },
|
|
57
|
+
Date.now() - startRequestTime
|
|
58
|
+
)
|
|
39
59
|
if (err) {
|
|
60
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
61
|
+
incrementCountMetric(
|
|
62
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
63
|
+
{ endpoint: 'test_cycle', errorType }
|
|
64
|
+
)
|
|
65
|
+
incrementCountMetric(
|
|
66
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
67
|
+
{ endpoint: 'test_cycle' }
|
|
68
|
+
)
|
|
40
69
|
log.error(err)
|
|
41
70
|
done()
|
|
42
71
|
return
|
|
@@ -143,7 +143,23 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
143
143
|
* where the tests run in a subprocess, because `getItrConfiguration` is called only once.
|
|
144
144
|
*/
|
|
145
145
|
this._itrConfig = itrConfig
|
|
146
|
-
|
|
146
|
+
|
|
147
|
+
if (err) {
|
|
148
|
+
callback(err, {})
|
|
149
|
+
} else if (itrConfig?.requireGit) {
|
|
150
|
+
// If the backend requires git, we'll wait for the upload to finish and request settings again
|
|
151
|
+
this._gitUploadPromise.then(gitUploadError => {
|
|
152
|
+
if (gitUploadError) {
|
|
153
|
+
return callback(gitUploadError, {})
|
|
154
|
+
}
|
|
155
|
+
getItrConfigurationRequest(configuration, (err, finalItrConfig) => {
|
|
156
|
+
this._itrConfig = finalItrConfig
|
|
157
|
+
callback(err, finalItrConfig)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
} else {
|
|
161
|
+
callback(null, itrConfig)
|
|
162
|
+
}
|
|
147
163
|
})
|
|
148
164
|
})
|
|
149
165
|
}
|