dd-trace 4.51.1 → 4.53.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 +8 -2
- package/ci/init.js +16 -0
- package/index.d.ts +31 -13
- package/init.js +4 -66
- package/initialize.mjs +13 -10
- package/loader-hook.mjs +4 -0
- package/package.json +16 -11
- package/packages/datadog-core/src/storage.js +39 -2
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +29 -3
- package/packages/datadog-instrumentations/src/express.js +38 -4
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +3 -3
- package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +3 -4
- package/packages/datadog-instrumentations/src/http/client.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +27 -8
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
- package/packages/datadog-instrumentations/src/mysql2.js +13 -8
- package/packages/datadog-instrumentations/src/next.js +7 -4
- package/packages/datadog-instrumentations/src/passport-http.js +2 -14
- package/packages/datadog-instrumentations/src/passport-local.js +2 -14
- package/packages/datadog-instrumentations/src/passport-utils.js +43 -19
- package/packages/datadog-instrumentations/src/pg.js +6 -6
- package/packages/datadog-instrumentations/src/playwright.js +17 -4
- package/packages/datadog-instrumentations/src/router.js +97 -1
- package/packages/datadog-instrumentations/src/sequelize.js +9 -4
- package/packages/datadog-instrumentations/src/url.js +4 -0
- package/packages/datadog-instrumentations/src/vitest.js +27 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +8 -3
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +154 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +92 -0
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +39 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +3 -3
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +39 -4
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +36 -2
- package/packages/datadog-plugin-oracledb/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +34 -2
- package/packages/datadog-shimmer/src/shimmer.js +8 -4
- package/packages/dd-trace/src/appsec/addresses.js +3 -0
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +1 -1
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +10 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/template-injection-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +8 -21
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +64 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -8
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +7 -11
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +2 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +32 -37
- package/packages/dd-trace/src/appsec/index.js +18 -13
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +2 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +1 -1
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +1 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +25 -1
- package/packages/dd-trace/src/appsec/remote_config/manager.js +2 -2
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +37 -24
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +4 -4
- package/packages/dd-trace/src/appsec/telemetry.js +10 -0
- package/packages/dd-trace/src/appsec/user_tracking.js +168 -0
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -3
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/azure_metadata.js +4 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +39 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +29 -9
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- package/packages/dd-trace/src/config.js +24 -32
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +3 -2
- package/packages/dd-trace/src/datastreams/processor.js +4 -6
- package/packages/dd-trace/src/datastreams/writer.js +6 -5
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +80 -0
- package/packages/dd-trace/src/debugger/devtools_client/config.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +6 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +63 -8
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +10 -67
- package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +4 -4
- package/packages/dd-trace/src/debugger/index.js +14 -10
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +23 -78
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +0 -32
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -2
- package/packages/dd-trace/src/encode/span-stats.js +0 -30
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -3
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -1
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/index.js +64 -0
- package/packages/dd-trace/src/guardrails/log.js +32 -0
- package/packages/dd-trace/src/guardrails/telemetry.js +78 -0
- package/packages/dd-trace/src/guardrails/util.js +10 -0
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/storage.js +2 -3
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -2
- package/packages/dd-trace/src/{encode → msgpack}/chunk.js +8 -5
- package/packages/dd-trace/src/msgpack/encoder.js +309 -0
- package/packages/dd-trace/src/msgpack/index.js +6 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +12 -9
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +4 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +47 -4
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +7 -7
- package/packages/dd-trace/src/plugins/util/test.js +36 -3
- package/packages/dd-trace/src/plugins/util/web.js +2 -2
- package/packages/dd-trace/src/profiling/config.js +3 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +9 -68
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +76 -0
- package/packages/dd-trace/src/profiling/exporters/file.js +8 -4
- package/packages/dd-trace/src/profiling/profiler.js +62 -10
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +22 -12
- package/packages/dd-trace/src/profiling/profilers/events.js +47 -8
- package/packages/dd-trace/src/profiling/profilers/wall.js +2 -17
- package/packages/dd-trace/src/profiling/webspan-utils.js +23 -0
- package/packages/dd-trace/src/proxy.js +7 -2
- package/packages/dd-trace/src/runtime_metrics.js +107 -4
- package/packages/dd-trace/src/serverless.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +1 -1
- package/packages/dd-trace/src/span_processor.js +10 -10
- package/packages/dd-trace/src/tagger.js +1 -1
- package/packages/dd-trace/src/telemetry/index.js +1 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +10 -2
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- package/packages/dd-trace/src/util.js +5 -16
- package/packages/datadog-instrumentations/src/qs.js +0 -24
- package/packages/dd-trace/src/appsec/iast/iast-log.js +0 -86
- package/packages/dd-trace/src/appsec/passport.js +0 -110
- package/packages/dd-trace/src/telemetry/init-telemetry.js +0 -75
|
@@ -4,10 +4,10 @@ const dc = require('dc-polyfill')
|
|
|
4
4
|
const TaintedUtils = require('@datadog/native-iast-taint-tracking')
|
|
5
5
|
const { storage } = require('../../../../../datadog-core')
|
|
6
6
|
const iastContextFunctions = require('../iast-context')
|
|
7
|
-
const iastLog = require('../iast-log')
|
|
8
7
|
const { EXECUTED_PROPAGATION } = require('../telemetry/iast-metric')
|
|
9
8
|
const { isDebugAllowed } = require('../telemetry/verbosity')
|
|
10
9
|
const { taintObject } = require('./operations-taint-object')
|
|
10
|
+
const log = require('../../../log')
|
|
11
11
|
|
|
12
12
|
const mathRandomCallCh = dc.channel('datadog:random:call')
|
|
13
13
|
const evalCallCh = dc.channel('datadog:eval:call')
|
|
@@ -60,8 +60,7 @@ function getFilteredCsiFn (cb, filter, getContext) {
|
|
|
60
60
|
return cb(transactionId, res, target, ...rest)
|
|
61
61
|
}
|
|
62
62
|
} catch (e) {
|
|
63
|
-
|
|
64
|
-
.errorAndPublish(e)
|
|
63
|
+
log.error('[ASM] Error invoking CSI %s', target, e)
|
|
65
64
|
}
|
|
66
65
|
return res
|
|
67
66
|
}
|
|
@@ -112,8 +111,7 @@ function csiMethodsOverrides (getContext) {
|
|
|
112
111
|
return TaintedUtils.concat(transactionId, res, op1, op2)
|
|
113
112
|
}
|
|
114
113
|
} catch (e) {
|
|
115
|
-
|
|
116
|
-
.errorAndPublish(e)
|
|
114
|
+
log.error('[ASM] Error invoking CSI plusOperator', e)
|
|
117
115
|
}
|
|
118
116
|
return res
|
|
119
117
|
},
|
|
@@ -126,8 +124,7 @@ function csiMethodsOverrides (getContext) {
|
|
|
126
124
|
return TaintedUtils.concat(transactionId, res, ...rest)
|
|
127
125
|
}
|
|
128
126
|
} catch (e) {
|
|
129
|
-
|
|
130
|
-
.errorAndPublish(e)
|
|
127
|
+
log.error('[ASM] Error invoking CSI tplOperator', e)
|
|
131
128
|
}
|
|
132
129
|
return res
|
|
133
130
|
},
|
|
@@ -178,7 +175,7 @@ function csiMethodsOverrides (getContext) {
|
|
|
178
175
|
}
|
|
179
176
|
}
|
|
180
177
|
} catch (e) {
|
|
181
|
-
|
|
178
|
+
log.error('[ASM] Error invoking CSI JSON.parse', e)
|
|
182
179
|
}
|
|
183
180
|
}
|
|
184
181
|
|
|
@@ -194,7 +191,7 @@ function csiMethodsOverrides (getContext) {
|
|
|
194
191
|
res = TaintedUtils.arrayJoin(transactionId, res, target, separator)
|
|
195
192
|
}
|
|
196
193
|
} catch (e) {
|
|
197
|
-
|
|
194
|
+
log.error('[ASM] Error invoking CSI join', e)
|
|
198
195
|
}
|
|
199
196
|
}
|
|
200
197
|
|
|
@@ -250,8 +247,7 @@ function lodashTaintTrackingHandler (message) {
|
|
|
250
247
|
message.result = getLodashTaintedUtilFn(message.operation)(transactionId, message.result, ...message.arguments)
|
|
251
248
|
}
|
|
252
249
|
} catch (e) {
|
|
253
|
-
|
|
254
|
-
.errorAndPublish(e)
|
|
250
|
+
log.error('[ASM] Error invoking CSI lodash %s', message.operation, e)
|
|
255
251
|
}
|
|
256
252
|
}
|
|
257
253
|
|
|
@@ -4,7 +4,6 @@ const log = require('../../../log')
|
|
|
4
4
|
const { Namespace } = require('../../../telemetry/metrics')
|
|
5
5
|
const { addMetricsToSpan } = require('./span-tags')
|
|
6
6
|
const { IAST_TRACE_METRIC_PREFIX } = require('../tags')
|
|
7
|
-
const iastLog = require('../iast-log')
|
|
8
7
|
|
|
9
8
|
const DD_IAST_METRICS_NAMESPACE = Symbol('_dd.iast.request.metrics.namespace')
|
|
10
9
|
|
|
@@ -31,7 +30,7 @@ function finalizeRequestNamespace (context, rootSpan) {
|
|
|
31
30
|
|
|
32
31
|
namespace.clear()
|
|
33
32
|
} catch (e) {
|
|
34
|
-
log.error(e)
|
|
33
|
+
log.error('[ASM] Error merging request metrics', e)
|
|
35
34
|
} finally {
|
|
36
35
|
if (context) {
|
|
37
36
|
delete context[DD_IAST_METRICS_NAMESPACE]
|
|
@@ -79,7 +78,7 @@ class IastNamespace extends Namespace {
|
|
|
79
78
|
|
|
80
79
|
if (metrics.size === this.maxMetricTagsSize) {
|
|
81
80
|
metrics.clear()
|
|
82
|
-
|
|
81
|
+
log.error('[ASM] Tags cache max size reached for metric %s', name)
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
metrics.set(tags, metric)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../../../../log')
|
|
4
4
|
|
|
5
5
|
const COMMAND_PATTERN = '^(?:\\s*(?:sudo|doas)\\s+)?\\b\\S+\\b\\s(.*)'
|
|
6
6
|
const pattern = new RegExp(COMMAND_PATTERN, 'gmi')
|
|
@@ -16,7 +16,7 @@ module.exports = function extractSensitiveRanges (evidence) {
|
|
|
16
16
|
return [{ start, end }]
|
|
17
17
|
}
|
|
18
18
|
} catch (e) {
|
|
19
|
-
|
|
19
|
+
log.debug('[ASM] Error extracting sensitive ranges', e)
|
|
20
20
|
}
|
|
21
21
|
return []
|
|
22
22
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../../../../log')
|
|
4
4
|
|
|
5
5
|
const LDAP_PATTERN = '\\(.*?(?:~=|=|<=|>=)(?<LITERAL>[^)]+)\\)'
|
|
6
6
|
const pattern = new RegExp(LDAP_PATTERN, 'gmi')
|
|
@@ -22,7 +22,7 @@ module.exports = function extractSensitiveRanges (evidence) {
|
|
|
22
22
|
}
|
|
23
23
|
return tokens
|
|
24
24
|
} catch (e) {
|
|
25
|
-
|
|
25
|
+
log.debug('[ASM] Error extracting sensitive ranges', e)
|
|
26
26
|
}
|
|
27
27
|
return []
|
|
28
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../../../../log')
|
|
4
4
|
|
|
5
5
|
const STRING_LITERAL = '\'(?:\'\'|[^\'])*\''
|
|
6
6
|
const POSTGRESQL_ESCAPED_LITERAL = '\\$([^$]*)\\$.*?\\$\\1\\$'
|
|
@@ -106,7 +106,7 @@ module.exports = function extractSensitiveRanges (evidence) {
|
|
|
106
106
|
}
|
|
107
107
|
return tokens
|
|
108
108
|
} catch (e) {
|
|
109
|
-
|
|
109
|
+
log.debug('[ASM] Error extracting sensitive ranges', e)
|
|
110
110
|
}
|
|
111
111
|
return []
|
|
112
112
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../../../../log')
|
|
4
4
|
|
|
5
5
|
const AUTHORITY = '^(?:[^:]+:)?//([^@]+)@'
|
|
6
6
|
const QUERY_FRAGMENT = '[?#&]([^=&;]+)=([^?#&]+)'
|
|
@@ -33,7 +33,7 @@ module.exports = function extractSensitiveRanges (evidence) {
|
|
|
33
33
|
|
|
34
34
|
return ranges
|
|
35
35
|
} catch (e) {
|
|
36
|
-
|
|
36
|
+
log.debug('[ASM] Error extracting sensitive ranges', e)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const log = require('../../../../log')
|
|
4
4
|
const vulnerabilities = require('../../vulnerabilities')
|
|
5
5
|
|
|
6
6
|
const { contains, intersects, remove } = require('./range-utils')
|
|
@@ -282,7 +282,7 @@ class SensitiveHandler {
|
|
|
282
282
|
try {
|
|
283
283
|
this._namePattern = new RegExp(redactionNamePattern, 'gmi')
|
|
284
284
|
} catch (e) {
|
|
285
|
-
|
|
285
|
+
log.warn('[ASM] Redaction name pattern is not valid')
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
|
|
@@ -290,7 +290,7 @@ class SensitiveHandler {
|
|
|
290
290
|
try {
|
|
291
291
|
this._valuePattern = new RegExp(redactionValuePattern, 'gmi')
|
|
292
292
|
} catch (e) {
|
|
293
|
-
|
|
293
|
+
log.warn('[ASM] Redaction value pattern is not valid')
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// eslint-disable-next-line max-len
|
|
1
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
2
2
|
const DEFAULT_IAST_REDACTION_NAME_PATTERN = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|(?:sur|last)name|user(?:name)?|address|e?mail)'
|
|
3
|
-
// eslint-disable-next-line max-len
|
|
3
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
4
4
|
const DEFAULT_IAST_REDACTION_VALUE_PATTERN = '(?:bearer\\s+[a-z0-9\\._\\-]+|glpat-[\\w\\-]{20}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=\\-]+\\.ey[I-L][\\w=\\-]+(?:\\.[\\w.+/=\\-]+)?|(?:[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY[\\-]{5}|ssh-rsa\\s*[a-z0-9/\\.+]{100,})|[\\w\\.-]+@[a-zA-Z\\d\\.-]+\\.[a-zA-Z]{2,})'
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
@@ -7,7 +7,7 @@ const STRINGIFY_RANGE_KEY = 'DD_' + crypto.randomBytes(20).toString('hex')
|
|
|
7
7
|
const STRINGIFY_SENSITIVE_KEY = STRINGIFY_RANGE_KEY + 'SENSITIVE'
|
|
8
8
|
const STRINGIFY_SENSITIVE_NOT_STRING_KEY = STRINGIFY_SENSITIVE_KEY + 'NOTSTRING'
|
|
9
9
|
|
|
10
|
-
// eslint-disable-next-line max-len
|
|
10
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
11
11
|
const KEYS_REGEX_WITH_SENSITIVE_RANGES = new RegExp(`(?:"(${STRINGIFY_RANGE_KEY}_\\d+_))|(?:"(${STRINGIFY_SENSITIVE_KEY}_\\d+_(\\d+)_))|("${STRINGIFY_SENSITIVE_NOT_STRING_KEY}_\\d+_([\\s0-9.a-zA-Z]*)")`, 'gm')
|
|
12
12
|
const KEYS_REGEX_WITHOUT_SENSITIVE_RANGES = new RegExp(`"(${STRINGIFY_RANGE_KEY}_\\d+_)`, 'gm')
|
|
13
13
|
|
|
@@ -17,13 +17,36 @@ let resetVulnerabilityCacheTimer
|
|
|
17
17
|
let deduplicationEnabled = true
|
|
18
18
|
|
|
19
19
|
function addVulnerability (iastContext, vulnerability) {
|
|
20
|
-
if (vulnerability && vulnerability
|
|
21
|
-
vulnerability
|
|
22
|
-
|
|
20
|
+
if (vulnerability?.evidence && vulnerability?.type && vulnerability?.location) {
|
|
21
|
+
if (deduplicationEnabled && isDuplicatedVulnerability(vulnerability)) return
|
|
22
|
+
|
|
23
|
+
VULNERABILITY_HASHES.set(`${vulnerability.type}${vulnerability.hash}`, true)
|
|
24
|
+
|
|
25
|
+
let span = iastContext?.rootSpan
|
|
26
|
+
|
|
27
|
+
if (!span && tracer) {
|
|
28
|
+
span = tracer.startSpan('vulnerability', {
|
|
29
|
+
type: 'vulnerability'
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
vulnerability.location.spanId = span.context().toSpanId()
|
|
33
|
+
|
|
34
|
+
span.addTags({
|
|
35
|
+
[IAST_ENABLED_TAG_KEY]: 1
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!span) return
|
|
40
|
+
|
|
41
|
+
keepTrace(span, SAMPLING_MECHANISM_APPSEC)
|
|
42
|
+
standalone.sample(span)
|
|
43
|
+
|
|
44
|
+
if (iastContext?.rootSpan) {
|
|
23
45
|
iastContext[VULNERABILITIES_KEY] = iastContext[VULNERABILITIES_KEY] || []
|
|
24
46
|
iastContext[VULNERABILITIES_KEY].push(vulnerability)
|
|
25
47
|
} else {
|
|
26
|
-
sendVulnerabilities([vulnerability])
|
|
48
|
+
sendVulnerabilities([vulnerability], span)
|
|
49
|
+
span.finish()
|
|
27
50
|
}
|
|
28
51
|
}
|
|
29
52
|
}
|
|
@@ -34,36 +57,17 @@ function isValidVulnerability (vulnerability) {
|
|
|
34
57
|
vulnerability.location && vulnerability.location.spanId
|
|
35
58
|
}
|
|
36
59
|
|
|
37
|
-
function sendVulnerabilities (vulnerabilities,
|
|
60
|
+
function sendVulnerabilities (vulnerabilities, span) {
|
|
38
61
|
if (vulnerabilities && vulnerabilities.length) {
|
|
39
|
-
let span = rootSpan
|
|
40
|
-
if (!span && tracer) {
|
|
41
|
-
span = tracer.startSpan('vulnerability', {
|
|
42
|
-
type: 'vulnerability'
|
|
43
|
-
})
|
|
44
|
-
vulnerabilities.forEach((vulnerability) => {
|
|
45
|
-
vulnerability.location.spanId = span.context().toSpanId()
|
|
46
|
-
})
|
|
47
|
-
span.addTags({
|
|
48
|
-
[IAST_ENABLED_TAG_KEY]: 1
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
|
|
52
62
|
if (span && span.addTags) {
|
|
53
|
-
const
|
|
54
|
-
const jsonToSend = vulnerabilitiesFormatter.toJson(
|
|
63
|
+
const validatedVulnerabilities = vulnerabilities.filter(isValidVulnerability)
|
|
64
|
+
const jsonToSend = vulnerabilitiesFormatter.toJson(validatedVulnerabilities)
|
|
55
65
|
|
|
56
66
|
if (jsonToSend.vulnerabilities.length > 0) {
|
|
57
67
|
const tags = {}
|
|
58
68
|
// TODO: Store this outside of the span and set the tag in the exporter.
|
|
59
69
|
tags[IAST_JSON_TAG_KEY] = JSON.stringify(jsonToSend)
|
|
60
70
|
span.addTags(tags)
|
|
61
|
-
|
|
62
|
-
keepTrace(span, SAMPLING_MECHANISM_APPSEC)
|
|
63
|
-
|
|
64
|
-
standalone.sample(span)
|
|
65
|
-
|
|
66
|
-
if (!rootSpan) span.finish()
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
}
|
|
@@ -86,17 +90,8 @@ function stopClearCacheTimer () {
|
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
const deduplicated = vulnerabilities.filter((vulnerability) => {
|
|
92
|
-
const key = `${vulnerability.type}${vulnerability.hash}`
|
|
93
|
-
if (!VULNERABILITY_HASHES.get(key)) {
|
|
94
|
-
VULNERABILITY_HASHES.set(key, true)
|
|
95
|
-
return true
|
|
96
|
-
}
|
|
97
|
-
return false
|
|
98
|
-
})
|
|
99
|
-
return deduplicated
|
|
93
|
+
function isDuplicatedVulnerability (vulnerability) {
|
|
94
|
+
return VULNERABILITY_HASHES.get(`${vulnerability.type}${vulnerability.hash}`)
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
function start (config, _tracer) {
|
|
@@ -16,7 +16,8 @@ const {
|
|
|
16
16
|
expressProcessParams,
|
|
17
17
|
responseBody,
|
|
18
18
|
responseWriteHead,
|
|
19
|
-
responseSetHeader
|
|
19
|
+
responseSetHeader,
|
|
20
|
+
routerParam
|
|
20
21
|
} = require('./channels')
|
|
21
22
|
const waf = require('./waf')
|
|
22
23
|
const addresses = require('./addresses')
|
|
@@ -27,7 +28,7 @@ const web = require('../plugins/util/web')
|
|
|
27
28
|
const { extractIp } = require('../plugins/util/ip_extractor')
|
|
28
29
|
const { HTTP_CLIENT_IP } = require('../../../../ext/tags')
|
|
29
30
|
const { isBlocked, block, setTemplates, getBlockingAction } = require('./blocking')
|
|
30
|
-
const
|
|
31
|
+
const UserTracking = require('./user_tracking')
|
|
31
32
|
const { storage } = require('../../../datadog-core')
|
|
32
33
|
const graphql = require('./graphql')
|
|
33
34
|
const rasp = require('./rasp')
|
|
@@ -58,28 +59,27 @@ function enable (_config) {
|
|
|
58
59
|
|
|
59
60
|
apiSecuritySampler.configure(_config.appsec)
|
|
60
61
|
|
|
62
|
+
UserTracking.setCollectionMode(_config.appsec.eventTracking.mode, false)
|
|
63
|
+
|
|
61
64
|
bodyParser.subscribe(onRequestBodyParsed)
|
|
62
65
|
multerParser.subscribe(onRequestBodyParsed)
|
|
63
66
|
cookieParser.subscribe(onRequestCookieParser)
|
|
64
67
|
incomingHttpRequestStart.subscribe(incomingHttpStartTranslator)
|
|
65
68
|
incomingHttpRequestEnd.subscribe(incomingHttpEndTranslator)
|
|
69
|
+
passportVerify.subscribe(onPassportVerify) // possible optimization: only subscribe if collection mode is enabled
|
|
66
70
|
queryParser.subscribe(onRequestQueryParsed)
|
|
67
71
|
nextBodyParsed.subscribe(onRequestBodyParsed)
|
|
68
72
|
nextQueryParsed.subscribe(onRequestQueryParsed)
|
|
69
73
|
expressProcessParams.subscribe(onRequestProcessParams)
|
|
74
|
+
routerParam.subscribe(onRequestProcessParams)
|
|
70
75
|
responseBody.subscribe(onResponseBody)
|
|
71
76
|
responseWriteHead.subscribe(onResponseWriteHead)
|
|
72
77
|
responseSetHeader.subscribe(onResponseSetHeader)
|
|
73
78
|
|
|
74
|
-
if (_config.appsec.eventTracking.enabled) {
|
|
75
|
-
passportVerify.subscribe(onPassportVerify)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
79
|
isEnabled = true
|
|
79
80
|
config = _config
|
|
80
81
|
} catch (err) {
|
|
81
|
-
log.error('Unable to start AppSec')
|
|
82
|
-
log.error(err)
|
|
82
|
+
log.error('[ASM] Unable to start AppSec', err)
|
|
83
83
|
|
|
84
84
|
disable()
|
|
85
85
|
}
|
|
@@ -164,8 +164,10 @@ function incomingHttpEndTranslator ({ req, res }) {
|
|
|
164
164
|
persistent[addresses.HTTP_INCOMING_COOKIES] = req.cookies
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
// we need to keep this to support nextjs
|
|
168
|
+
const query = req.query
|
|
169
|
+
if (query !== null && typeof query === 'object') {
|
|
170
|
+
persistent[addresses.HTTP_INCOMING_QUERY] = query
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
if (apiSecuritySampler.sampleRequest(req, res, true)) {
|
|
@@ -181,16 +183,18 @@ function incomingHttpEndTranslator ({ req, res }) {
|
|
|
181
183
|
Reporter.finishRequest(req, res)
|
|
182
184
|
}
|
|
183
185
|
|
|
184
|
-
function onPassportVerify ({
|
|
186
|
+
function onPassportVerify ({ framework, login, user, success, abortController }) {
|
|
185
187
|
const store = storage.getStore()
|
|
186
188
|
const rootSpan = store?.req && web.root(store.req)
|
|
187
189
|
|
|
188
190
|
if (!rootSpan) {
|
|
189
|
-
log.warn('No rootSpan found in onPassportVerify')
|
|
191
|
+
log.warn('[ASM] No rootSpan found in onPassportVerify')
|
|
190
192
|
return
|
|
191
193
|
}
|
|
192
194
|
|
|
193
|
-
|
|
195
|
+
const results = UserTracking.trackLogin(framework, login, user, success, rootSpan)
|
|
196
|
+
|
|
197
|
+
handleResults(results, store.req, store.req.res, rootSpan, abortController)
|
|
194
198
|
}
|
|
195
199
|
|
|
196
200
|
function onRequestQueryParsed ({ req, res, query, abortController }) {
|
|
@@ -310,6 +314,7 @@ function disable () {
|
|
|
310
314
|
if (nextBodyParsed.hasSubscribers) nextBodyParsed.unsubscribe(onRequestBodyParsed)
|
|
311
315
|
if (nextQueryParsed.hasSubscribers) nextQueryParsed.unsubscribe(onRequestQueryParsed)
|
|
312
316
|
if (expressProcessParams.hasSubscribers) expressProcessParams.unsubscribe(onRequestProcessParams)
|
|
317
|
+
if (routerParam.hasSubscribers) routerParam.unsubscribe(onRequestProcessParams)
|
|
313
318
|
if (responseBody.hasSubscribers) responseBody.unsubscribe(onResponseBody)
|
|
314
319
|
if (responseWriteHead.hasSubscribers) responseWriteHead.unsubscribe(onResponseWriteHead)
|
|
315
320
|
if (responseSetHeader.hasSubscribers) responseSetHeader.unsubscribe(onResponseSetHeader)
|
|
@@ -70,7 +70,7 @@ function enable (mod) {
|
|
|
70
70
|
fsPlugin.enable()
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
log.info(
|
|
73
|
+
log.info('[ASM] Enabled AppsecFsPlugin for %s', mod)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function disable (mod) {
|
|
@@ -85,7 +85,7 @@ function disable (mod) {
|
|
|
85
85
|
fsPlugin = undefined
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
log.info(
|
|
88
|
+
log.info('[ASM] Disabled AppsecFsPlugin for %s', mod)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
module.exports = {
|
|
@@ -8,7 +8,7 @@ const log = require('../../log')
|
|
|
8
8
|
const abortOnUncaughtException = process.execArgv?.includes('--abort-on-uncaught-exception')
|
|
9
9
|
|
|
10
10
|
if (abortOnUncaughtException) {
|
|
11
|
-
log.warn('The --abort-on-uncaught-exception flag is enabled. The RASP module will not block operations.')
|
|
11
|
+
log.warn('[ASM] The --abort-on-uncaught-exception flag is enabled. The RASP module will not block operations.')
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const RULE_TYPES = {
|
|
@@ -22,6 +22,7 @@ module.exports = {
|
|
|
22
22
|
ASM_RASP_SSRF: 1n << 23n,
|
|
23
23
|
ASM_RASP_SHI: 1n << 24n,
|
|
24
24
|
APM_TRACING_SAMPLE_RULES: 1n << 29n,
|
|
25
|
+
ASM_AUTO_USER_INSTRUM_MODE: 1n << 31n,
|
|
25
26
|
ASM_ENDPOINT_FINGERPRINT: 1n << 32n,
|
|
26
27
|
ASM_NETWORK_FINGERPRINT: 1n << 34n,
|
|
27
28
|
ASM_HEADER_FINGERPRINT: 1n << 35n
|
|
@@ -4,6 +4,8 @@ const Activation = require('../activation')
|
|
|
4
4
|
|
|
5
5
|
const RemoteConfigManager = require('./manager')
|
|
6
6
|
const RemoteConfigCapabilities = require('./capabilities')
|
|
7
|
+
const { setCollectionMode } = require('../user_tracking')
|
|
8
|
+
const log = require('../../log')
|
|
7
9
|
|
|
8
10
|
let rc
|
|
9
11
|
|
|
@@ -23,9 +25,31 @@ function enable (config, appsec) {
|
|
|
23
25
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_ACTIVATION, true)
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
rc.
|
|
28
|
+
rc.updateCapabilities(RemoteConfigCapabilities.ASM_AUTO_USER_INSTRUM_MODE, true)
|
|
29
|
+
|
|
30
|
+
let autoUserInstrumModeId
|
|
31
|
+
|
|
32
|
+
rc.setProductHandler('ASM_FEATURES', (action, rcConfig, configId) => {
|
|
27
33
|
if (!rcConfig) return
|
|
28
34
|
|
|
35
|
+
// this is put before other handlers because it can reject the config
|
|
36
|
+
if (typeof rcConfig.auto_user_instrum?.mode === 'string') {
|
|
37
|
+
if (action === 'apply' || action === 'modify') {
|
|
38
|
+
// check if there is already a config applied with this field
|
|
39
|
+
if (autoUserInstrumModeId && configId !== autoUserInstrumModeId) {
|
|
40
|
+
log.error('[RC] Multiple auto_user_instrum received in ASM_FEATURES. Discarding config')
|
|
41
|
+
// eslint-disable-next-line no-throw-literal
|
|
42
|
+
throw 'Multiple auto_user_instrum.mode received in ASM_FEATURES'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setCollectionMode(rcConfig.auto_user_instrum.mode)
|
|
46
|
+
autoUserInstrumModeId = configId
|
|
47
|
+
} else if (configId === autoUserInstrumModeId) {
|
|
48
|
+
setCollectionMode(config.appsec.eventTracking.mode)
|
|
49
|
+
autoUserInstrumModeId = null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
29
53
|
if (activation === Activation.ONECLICK) {
|
|
30
54
|
enableOrDisableAppsec(action, rcConfig, config, appsec)
|
|
31
55
|
}
|
|
@@ -134,7 +134,7 @@ class RemoteConfigManager extends EventEmitter {
|
|
|
134
134
|
if (statusCode === 404) return cb()
|
|
135
135
|
|
|
136
136
|
if (err) {
|
|
137
|
-
log.error(err)
|
|
137
|
+
log.error('[RC] Error in request', err)
|
|
138
138
|
return cb()
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -148,7 +148,7 @@ class RemoteConfigManager extends EventEmitter {
|
|
|
148
148
|
try {
|
|
149
149
|
this.parseConfig(JSON.parse(data))
|
|
150
150
|
} catch (err) {
|
|
151
|
-
log.error(
|
|
151
|
+
log.error('[RC] Could not parse remote config response', err)
|
|
152
152
|
|
|
153
153
|
this.state.client.state.has_error = true
|
|
154
154
|
this.state.client.state.error = err.toString()
|
|
@@ -148,7 +148,9 @@ function reportAttack (attackData) {
|
|
|
148
148
|
newTags['_dd.appsec.json'] = '{"triggers":' + attackData + '}'
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
if (req.socket) {
|
|
152
|
+
newTags['network.client.ip'] = req.socket.remoteAddress
|
|
153
|
+
}
|
|
152
154
|
|
|
153
155
|
rootSpan.addTags(newTags)
|
|
154
156
|
}
|
|
@@ -11,13 +11,13 @@ function setUserTags (user, rootSpan) {
|
|
|
11
11
|
|
|
12
12
|
function setUser (tracer, user) {
|
|
13
13
|
if (!user || !user.id) {
|
|
14
|
-
log.warn('Invalid user provided to setUser')
|
|
14
|
+
log.warn('[ASM] Invalid user provided to setUser')
|
|
15
15
|
return
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const rootSpan = getRootSpan(tracer)
|
|
19
19
|
if (!rootSpan) {
|
|
20
|
-
log.warn('Root span not available in setUser')
|
|
20
|
+
log.warn('[ASM] Root span not available in setUser')
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -7,67 +7,68 @@ const standalone = require('../standalone')
|
|
|
7
7
|
const waf = require('../waf')
|
|
8
8
|
const { SAMPLING_MECHANISM_APPSEC } = require('../../constants')
|
|
9
9
|
const { keepTrace } = require('../../priority_sampler')
|
|
10
|
+
const addresses = require('../addresses')
|
|
10
11
|
|
|
11
12
|
function trackUserLoginSuccessEvent (tracer, user, metadata) {
|
|
12
13
|
// TODO: better user check here and in _setUser() ?
|
|
13
14
|
if (!user || !user.id) {
|
|
14
|
-
log.warn('Invalid user provided to trackUserLoginSuccessEvent')
|
|
15
|
+
log.warn('[ASM] Invalid user provided to trackUserLoginSuccessEvent')
|
|
15
16
|
return
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
const rootSpan = getRootSpan(tracer)
|
|
19
20
|
if (!rootSpan) {
|
|
20
|
-
log.warn('Root span not available in trackUserLoginSuccessEvent')
|
|
21
|
+
log.warn('[ASM] Root span not available in trackUserLoginSuccessEvent')
|
|
21
22
|
return
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
setUserTags(user, rootSpan)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
const login = user.login ?? user.id
|
|
28
|
+
|
|
29
|
+
metadata = { 'usr.login': login, ...metadata }
|
|
30
|
+
|
|
31
|
+
trackEvent('users.login.success', metadata, 'trackUserLoginSuccessEvent', rootSpan)
|
|
32
|
+
|
|
33
|
+
runWaf('users.login.success', { id: user.id, login })
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
function trackUserLoginFailureEvent (tracer, userId, exists, metadata) {
|
|
30
37
|
if (!userId || typeof userId !== 'string') {
|
|
31
|
-
log.warn('Invalid userId provided to trackUserLoginFailureEvent')
|
|
38
|
+
log.warn('[ASM] Invalid userId provided to trackUserLoginFailureEvent')
|
|
32
39
|
return
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
const fields = {
|
|
36
43
|
'usr.id': userId,
|
|
44
|
+
'usr.login': userId,
|
|
37
45
|
'usr.exists': exists ? 'true' : 'false',
|
|
38
46
|
...metadata
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
trackEvent('users.login.failure', fields, 'trackUserLoginFailureEvent', getRootSpan(tracer)
|
|
49
|
+
trackEvent('users.login.failure', fields, 'trackUserLoginFailureEvent', getRootSpan(tracer))
|
|
50
|
+
|
|
51
|
+
runWaf('users.login.failure', { login: userId })
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
function trackCustomEvent (tracer, eventName, metadata) {
|
|
45
55
|
if (!eventName || typeof eventName !== 'string') {
|
|
46
|
-
log.warn('Invalid eventName provided to trackCustomEvent')
|
|
56
|
+
log.warn('[ASM] Invalid eventName provided to trackCustomEvent')
|
|
47
57
|
return
|
|
48
58
|
}
|
|
49
59
|
|
|
50
|
-
trackEvent(eventName, metadata, 'trackCustomEvent', getRootSpan(tracer)
|
|
60
|
+
trackEvent(eventName, metadata, 'trackCustomEvent', getRootSpan(tracer))
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
function trackEvent (eventName, fields, sdkMethodName, rootSpan
|
|
63
|
+
function trackEvent (eventName, fields, sdkMethodName, rootSpan) {
|
|
54
64
|
if (!rootSpan) {
|
|
55
|
-
log.warn(
|
|
65
|
+
log.warn('[ASM] Root span not available in %s', sdkMethodName)
|
|
56
66
|
return
|
|
57
67
|
}
|
|
58
68
|
|
|
59
|
-
keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)
|
|
60
|
-
|
|
61
69
|
const tags = {
|
|
62
|
-
[`appsec.events.${eventName}.track`]: 'true'
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (mode === 'sdk') {
|
|
66
|
-
tags[`_dd.appsec.events.${eventName}.sdk`] = 'true'
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (mode === 'safe' || mode === 'extended') {
|
|
70
|
-
tags[`_dd.appsec.events.${eventName}.auto.mode`] = mode
|
|
70
|
+
[`appsec.events.${eventName}.track`]: 'true',
|
|
71
|
+
[`_dd.appsec.events.${eventName}.sdk`]: 'true'
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
if (fields) {
|
|
@@ -78,16 +79,28 @@ function trackEvent (eventName, fields, sdkMethodName, rootSpan, mode) {
|
|
|
78
79
|
|
|
79
80
|
rootSpan.addTags(tags)
|
|
80
81
|
|
|
82
|
+
keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)
|
|
81
83
|
standalone.sample(rootSpan)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function runWaf (eventName, user) {
|
|
87
|
+
const persistent = {
|
|
88
|
+
[`server.business_logic.${eventName}`]: null
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (user.id) {
|
|
92
|
+
persistent[addresses.USER_ID] = '' + user.id
|
|
93
|
+
}
|
|
82
94
|
|
|
83
|
-
if (
|
|
84
|
-
|
|
95
|
+
if (user.login) {
|
|
96
|
+
persistent[addresses.USER_LOGIN] = '' + user.login
|
|
85
97
|
}
|
|
98
|
+
|
|
99
|
+
waf.run({ persistent })
|
|
86
100
|
}
|
|
87
101
|
|
|
88
102
|
module.exports = {
|
|
89
103
|
trackUserLoginSuccessEvent,
|
|
90
104
|
trackUserLoginFailureEvent,
|
|
91
|
-
trackCustomEvent
|
|
92
|
-
trackEvent
|
|
105
|
+
trackCustomEvent
|
|
93
106
|
}
|