dd-trace 5.38.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +1 -0
- package/index.d.ts +30 -21
- package/package.json +4 -2
- package/packages/datadog-instrumentations/src/apollo-server-core.js +1 -1
- package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
- package/packages/datadog-instrumentations/src/express-session.js +41 -0
- package/packages/datadog-instrumentations/src/fetch.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/fetch.js +6 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +16 -10
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -1
- package/packages/datadog-instrumentations/src/nyc.js +2 -1
- package/packages/datadog-instrumentations/src/vitest.js +4 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +9 -8
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -4
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +5 -2
- package/packages/datadog-plugin-kafkajs/src/producer.js +4 -3
- package/packages/datadog-plugin-mongodb-core/src/index.js +10 -13
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -2
- package/packages/datadog-shimmer/src/shimmer.js +95 -95
- package/packages/dd-trace/src/appsec/addresses.js +1 -0
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/iast-context.js +2 -2
- package/packages/dd-trace/src/appsec/iast/index.js +0 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -5
- package/packages/dd-trace/src/appsec/index.js +23 -1
- package/packages/dd-trace/src/appsec/reporter.js +3 -8
- package/packages/dd-trace/src/appsec/rule_manager.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/set_user.js +9 -5
- package/packages/dd-trace/src/appsec/sdk/track_event.js +2 -4
- package/packages/dd-trace/src/appsec/telemetry/common.js +24 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +126 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +35 -0
- package/packages/dd-trace/src/appsec/telemetry/user.js +24 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +92 -0
- package/packages/dd-trace/src/appsec/user_tracking.js +2 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +16 -4
- package/packages/dd-trace/src/config.js +31 -14
- package/packages/dd-trace/src/constants.js +1 -1
- package/packages/dd-trace/src/{data_streams.js → datastreams/checkpointer.js} +1 -1
- package/packages/dd-trace/src/{data_streams_context.js → datastreams/context.js} +2 -2
- package/packages/dd-trace/src/datastreams/index.js +104 -0
- package/packages/dd-trace/src/datastreams/manager.js +27 -0
- package/packages/dd-trace/src/datastreams/processor.js +1 -44
- package/packages/dd-trace/src/datastreams/size.js +53 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +22 -15
- package/packages/dd-trace/src/dogstatsd.js +23 -4
- package/packages/dd-trace/src/exporters/agent/index.js +2 -2
- package/packages/dd-trace/src/flare/index.js +3 -0
- package/packages/dd-trace/src/noop/dogstatsd.js +6 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +45 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +11 -47
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +1 -1
- package/packages/dd-trace/src/opentracing/span.js +12 -2
- package/packages/dd-trace/src/payload-tagging/config/aws.json +8 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -2
- package/packages/dd-trace/src/priority_sampler.js +5 -3
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +15 -4
- package/packages/dd-trace/src/proxy.js +41 -22
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/capabilities.js +1 -0
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/index.js +8 -5
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/manager.js +5 -5
- package/packages/dd-trace/src/runtime_metrics/index.js +34 -0
- package/packages/dd-trace/src/{runtime_metrics.js → runtime_metrics/runtime_metrics.js} +4 -4
- package/packages/dd-trace/src/serverless.js +10 -1
- package/packages/dd-trace/src/service-naming/index.js +12 -4
- package/packages/dd-trace/src/span_processor.js +7 -4
- package/packages/dd-trace/src/span_stats.js +1 -2
- package/packages/dd-trace/src/standalone/index.js +70 -0
- package/packages/dd-trace/src/standalone/product.js +24 -0
- package/packages/dd-trace/src/standalone/tracesource.js +22 -0
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +47 -0
- package/packages/dd-trace/src/telemetry/index.js +16 -387
- package/packages/dd-trace/src/telemetry/telemetry.js +394 -0
- package/packages/dd-trace/src/tracer.js +7 -15
- package/packages/dd-trace/src/appsec/standalone.js +0 -130
- package/packages/dd-trace/src/appsec/telemetry.js +0 -218
- package/packages/dd-trace/src/service-naming/schemas/index.js +0 -6
- /package/packages/dd-trace/src/{appsec/remote_config → remote_config}/apply_states.js +0 -0
- /package/packages/dd-trace/src/{appsec/remote_config → remote_config}/scheduler.js +0 -0
|
@@ -25,7 +25,7 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
25
25
|
'out.port': options.port
|
|
26
26
|
}
|
|
27
27
|
})
|
|
28
|
-
ops = this.
|
|
28
|
+
ops.comment = this.injectDbmComment(span, ops.comment, service)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
getPeerService (tags) {
|
|
@@ -37,28 +37,25 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
37
37
|
return super.getPeerService(tags)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
injectDbmComment (span, comment, serviceName) {
|
|
41
41
|
const dbmTraceComment = this.createDbmComment(span, serviceName)
|
|
42
42
|
|
|
43
43
|
if (!dbmTraceComment) {
|
|
44
|
-
return
|
|
44
|
+
return comment
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
const dbmTracedCommand = { ...command }
|
|
49
|
-
|
|
50
|
-
if (dbmTracedCommand.comment) {
|
|
47
|
+
if (comment) {
|
|
51
48
|
// if the command already has a comment, append the dbm trace comment
|
|
52
|
-
if (typeof
|
|
53
|
-
|
|
54
|
-
} else if (Array.isArray(
|
|
55
|
-
|
|
49
|
+
if (typeof comment === 'string') {
|
|
50
|
+
comment += `,${dbmTraceComment}`
|
|
51
|
+
} else if (Array.isArray(comment)) {
|
|
52
|
+
comment.push(dbmTraceComment)
|
|
56
53
|
} // do nothing if the comment is not a string or an array
|
|
57
54
|
} else {
|
|
58
|
-
|
|
55
|
+
comment = dbmTraceComment
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
return
|
|
58
|
+
return comment
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
|
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
const log = require('../../dd-trace/src/log')
|
|
11
11
|
const {
|
|
12
12
|
SchemaBuilder
|
|
13
|
-
} = require('../../dd-trace/src/datastreams
|
|
13
|
+
} = require('../../dd-trace/src/datastreams')
|
|
14
14
|
|
|
15
15
|
class SchemaExtractor {
|
|
16
16
|
constructor (schema) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
|
-
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams
|
|
5
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams')
|
|
6
6
|
|
|
7
7
|
class RheaConsumerPlugin extends ConsumerPlugin {
|
|
8
8
|
static get id () { return 'rhea' }
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
4
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
|
-
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams
|
|
6
|
-
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
5
|
+
const { getAmqpMessageSize, DsmPathwayCodec } = require('../../dd-trace/src/datastreams')
|
|
7
6
|
|
|
8
7
|
class RheaProducerPlugin extends ProducerPlugin {
|
|
9
8
|
static get id () { return 'rhea' }
|
|
@@ -26,10 +26,10 @@ function copyProperties (original, wrapped) {
|
|
|
26
26
|
|
|
27
27
|
function wrapFunction (original, wrapper) {
|
|
28
28
|
if (typeof original === 'function') assertNotClass(original)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
|
|
30
|
+
let delegate = safeMode
|
|
31
|
+
? safeWrapper(original, wrapper)
|
|
32
|
+
: wrapper(original)
|
|
33
33
|
|
|
34
34
|
const shim = function shim () {
|
|
35
35
|
return delegate.apply(this, arguments)
|
|
@@ -85,98 +85,10 @@ function wrapMethod (target, name, wrapper, noAssert) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const original = target[name]
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// In this mode, we make a best-effort attempt to handle errors that are thrown
|
|
92
|
-
// by us, rather than wrapped code. With such errors, we log them, and then attempt
|
|
93
|
-
// to return the result as if no wrapping was done at all.
|
|
94
|
-
//
|
|
95
|
-
// Caveats:
|
|
96
|
-
// * If the original function is called in a later iteration of the event loop,
|
|
97
|
-
// and we throw _then_, then it won't be caught by this. In practice, we always call
|
|
98
|
-
// the original function synchronously, so this is not a problem.
|
|
99
|
-
// * While async errors are dealt with here, errors in callbacks are not. This
|
|
100
|
-
// is because we don't necessarily know _for sure_ that any function arguments
|
|
101
|
-
// are wrapped by us. We could wrap them all anyway and just make that assumption,
|
|
102
|
-
// or just assume that the last argument is always a callback set by us if it's a
|
|
103
|
-
// function, but those don't seem like things we can rely on. We could add a
|
|
104
|
-
// `shimmer.markCallbackAsWrapped()` function that's a no-op outside safe-mode,
|
|
105
|
-
// but that means modifying every instrumentation. Even then, the complexity of
|
|
106
|
-
// this code increases because then we'd need to effectively do the reverse of
|
|
107
|
-
// what we're doing for synchronous functions. This is a TODO.
|
|
108
|
-
|
|
109
|
-
// We're going to hold on to current callState in this variable in this scope,
|
|
110
|
-
// which is fine because any time we reference it, we're referencing it synchronously.
|
|
111
|
-
// We'll use it in the our wrapper (which, again, is called syncrhonously), and in the
|
|
112
|
-
// errorHandler, which will already have been bound to this callState.
|
|
113
|
-
let currentCallState
|
|
114
|
-
|
|
115
|
-
// Rather than calling the original function directly from the shim wrapper, we wrap
|
|
116
|
-
// it again so that we can track if it was called and if it returned. This is because
|
|
117
|
-
// we need to know if an error was thrown by the original function, or by us.
|
|
118
|
-
// We could do this inside the `wrapper` function defined below, which would simplify
|
|
119
|
-
// managing the callState, but then we'd be calling `wrapper` on each invocation, so
|
|
120
|
-
// instead we do it here, once.
|
|
121
|
-
const innerWrapped = wrapper(function (...args) {
|
|
122
|
-
// We need to stash the callState here because of recursion.
|
|
123
|
-
const callState = currentCallState
|
|
124
|
-
callState.startCall()
|
|
125
|
-
const retVal = original.apply(this, args)
|
|
126
|
-
if (isPromise(retVal)) {
|
|
127
|
-
retVal.then(callState.endCall.bind(callState))
|
|
128
|
-
} else {
|
|
129
|
-
callState.endCall(retVal)
|
|
130
|
-
}
|
|
131
|
-
return retVal
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
// This is the crux of what we're doing in safe mode. It handles errors
|
|
135
|
-
// that _we_ cause, by logging them, and transparently providing results
|
|
136
|
-
// as if no wrapping was done at all. That means detecting (via callState)
|
|
137
|
-
// whether the function has already run or not, and if it has, returning
|
|
138
|
-
// the result, and otherwise calling the original function unwrapped.
|
|
139
|
-
const handleError = function (args, callState, e) {
|
|
140
|
-
if (callState.completed) {
|
|
141
|
-
// error was thrown after original function returned/resolved, so
|
|
142
|
-
// it was us. log it.
|
|
143
|
-
log.error('Shimmer error was thrown after original function returned/resolved', e)
|
|
144
|
-
// original ran and returned something. return it.
|
|
145
|
-
return callState.retVal
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (!callState.called) {
|
|
149
|
-
// error was thrown before original function was called, so
|
|
150
|
-
// it was us. log it.
|
|
151
|
-
log.error('Shimmer error was thrown before original function was called', e)
|
|
152
|
-
// original never ran. call it unwrapped.
|
|
153
|
-
return original.apply(this, args)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// error was thrown during original function execution, so
|
|
157
|
-
// it was them. throw.
|
|
158
|
-
throw e
|
|
159
|
-
}
|
|
88
|
+
const wrapped = safeMode && original
|
|
89
|
+
? safeWrapper(original, wrapper)
|
|
90
|
+
: wrapper(original)
|
|
160
91
|
|
|
161
|
-
// The wrapped function is the one that will be called by the user.
|
|
162
|
-
// It calls our version of the original function, which manages the
|
|
163
|
-
// callState. That way when we use the errorHandler, it can tell where
|
|
164
|
-
// the error originated.
|
|
165
|
-
wrapped = function (...args) {
|
|
166
|
-
currentCallState = new CallState()
|
|
167
|
-
const errorHandler = handleError.bind(this, args, currentCallState)
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
const retVal = innerWrapped.apply(this, args)
|
|
171
|
-
return isPromise(retVal) ? retVal.catch(errorHandler) : retVal
|
|
172
|
-
} catch (e) {
|
|
173
|
-
return errorHandler(e)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
} else {
|
|
177
|
-
// In non-safe mode, we just wrap the original function directly.
|
|
178
|
-
wrapped = wrapper(original)
|
|
179
|
-
}
|
|
180
92
|
const descriptor = Object.getOwnPropertyDescriptor(target, name)
|
|
181
93
|
|
|
182
94
|
const attributes = {
|
|
@@ -212,6 +124,94 @@ function wrapMethod (target, name, wrapper, noAssert) {
|
|
|
212
124
|
return target
|
|
213
125
|
}
|
|
214
126
|
|
|
127
|
+
function safeWrapper (original, wrapper) {
|
|
128
|
+
// In this mode, we make a best-effort attempt to handle errors that are thrown
|
|
129
|
+
// by us, rather than wrapped code. With such errors, we log them, and then attempt
|
|
130
|
+
// to return the result as if no wrapping was done at all.
|
|
131
|
+
//
|
|
132
|
+
// Caveats:
|
|
133
|
+
// * If the original function is called in a later iteration of the event loop,
|
|
134
|
+
// and we throw _then_, then it won't be caught by this. In practice, we always call
|
|
135
|
+
// the original function synchronously, so this is not a problem.
|
|
136
|
+
// * While async errors are dealt with here, errors in callbacks are not. This
|
|
137
|
+
// is because we don't necessarily know _for sure_ that any function arguments
|
|
138
|
+
// are wrapped by us. We could wrap them all anyway and just make that assumption,
|
|
139
|
+
// or just assume that the last argument is always a callback set by us if it's a
|
|
140
|
+
// function, but those don't seem like things we can rely on. We could add a
|
|
141
|
+
// `shimmer.markCallbackAsWrapped()` function that's a no-op outside safe-mode,
|
|
142
|
+
// but that means modifying every instrumentation. Even then, the complexity of
|
|
143
|
+
// this code increases because then we'd need to effectively do the reverse of
|
|
144
|
+
// what we're doing for synchronous functions. This is a TODO.
|
|
145
|
+
|
|
146
|
+
// We're going to hold on to current callState in this variable in this scope,
|
|
147
|
+
// which is fine because any time we reference it, we're referencing it synchronously.
|
|
148
|
+
// We'll use it in the our wrapper (which, again, is called syncrhonously), and in the
|
|
149
|
+
// errorHandler, which will already have been bound to this callState.
|
|
150
|
+
let currentCallState
|
|
151
|
+
|
|
152
|
+
// Rather than calling the original function directly from the shim wrapper, we wrap
|
|
153
|
+
// it again so that we can track if it was called and if it returned. This is because
|
|
154
|
+
// we need to know if an error was thrown by the original function, or by us.
|
|
155
|
+
// We could do this inside the `wrapper` function defined below, which would simplify
|
|
156
|
+
// managing the callState, but then we'd be calling `wrapper` on each invocation, so
|
|
157
|
+
// instead we do it here, once.
|
|
158
|
+
const innerWrapped = wrapper(function (...args) {
|
|
159
|
+
// We need to stash the callState here because of recursion.
|
|
160
|
+
const callState = currentCallState
|
|
161
|
+
callState.startCall()
|
|
162
|
+
const retVal = original.apply(this, args)
|
|
163
|
+
if (isPromise(retVal)) {
|
|
164
|
+
retVal.then(callState.endCall.bind(callState))
|
|
165
|
+
} else {
|
|
166
|
+
callState.endCall(retVal)
|
|
167
|
+
}
|
|
168
|
+
return retVal
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
// This is the crux of what we're doing in safe mode. It handles errors
|
|
172
|
+
// that _we_ cause, by logging them, and transparently providing results
|
|
173
|
+
// as if no wrapping was done at all. That means detecting (via callState)
|
|
174
|
+
// whether the function has already run or not, and if it has, returning
|
|
175
|
+
// the result, and otherwise calling the original function unwrapped.
|
|
176
|
+
const handleError = function (args, callState, e) {
|
|
177
|
+
if (callState.completed) {
|
|
178
|
+
// error was thrown after original function returned/resolved, so
|
|
179
|
+
// it was us. log it.
|
|
180
|
+
log.error('Shimmer error was thrown after original function returned/resolved', e)
|
|
181
|
+
// original ran and returned something. return it.
|
|
182
|
+
return callState.retVal
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!callState.called) {
|
|
186
|
+
// error was thrown before original function was called, so
|
|
187
|
+
// it was us. log it.
|
|
188
|
+
log.error('Shimmer error was thrown before original function was called', e)
|
|
189
|
+
// original never ran. call it unwrapped.
|
|
190
|
+
return original.apply(this, args)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// error was thrown during original function execution, so
|
|
194
|
+
// it was them. throw.
|
|
195
|
+
throw e
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// The wrapped function is the one that will be called by the user.
|
|
199
|
+
// It calls our version of the original function, which manages the
|
|
200
|
+
// callState. That way when we use the errorHandler, it can tell where
|
|
201
|
+
// the error originated.
|
|
202
|
+
return function (...args) {
|
|
203
|
+
currentCallState = new CallState()
|
|
204
|
+
const errorHandler = handleError.bind(this, args, currentCallState)
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const retVal = innerWrapped.apply(this, args)
|
|
208
|
+
return isPromise(retVal) ? retVal.catch(errorHandler) : retVal
|
|
209
|
+
} catch (e) {
|
|
210
|
+
return errorHandler(e)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
215
|
function wrap (target, name, wrapper) {
|
|
216
216
|
return typeof name === 'function'
|
|
217
217
|
? wrapFn(target, name)
|
|
@@ -15,6 +15,7 @@ module.exports = {
|
|
|
15
15
|
incomingHttpRequestEnd: dc.channel('dd-trace:incomingHttpRequestEnd'),
|
|
16
16
|
passportVerify: dc.channel('datadog:passport:verify:finish'),
|
|
17
17
|
passportUser: dc.channel('datadog:passport:deserializeUser:finish'),
|
|
18
|
+
expressSession: dc.channel('datadog:express-session:middleware:finish'),
|
|
18
19
|
queryParser: dc.channel('datadog:query:read:finish'),
|
|
19
20
|
setCookieChannel: dc.channel('datadog:iast:set-cookie'),
|
|
20
21
|
nextBodyParsed: dc.channel('apm:next:body-parsed'),
|
|
@@ -10,14 +10,14 @@ function getIastContext (store, topContext) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function getIastStackTraceId (iastContext) {
|
|
13
|
-
if (!iastContext) return 0
|
|
13
|
+
if (!iastContext) return '0'
|
|
14
14
|
|
|
15
15
|
if (!iastContext.stackTraceId) {
|
|
16
16
|
iastContext.stackTraceId = 0
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
iastContext.stackTraceId += 1
|
|
20
|
-
return iastContext.stackTraceId
|
|
20
|
+
return String(iastContext.stackTraceId)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/* TODO Fix storage problem when the close event is called without
|
|
@@ -22,7 +22,6 @@ const securityControls = require('./security-controls')
|
|
|
22
22
|
const requestStart = dc.channel('dd-trace:incomingHttpRequestStart')
|
|
23
23
|
const requestClose = dc.channel('dd-trace:incomingHttpRequestEnd')
|
|
24
24
|
const iastResponseEnd = dc.channel('datadog:iast:response-end')
|
|
25
|
-
|
|
26
25
|
let isEnabled = false
|
|
27
26
|
|
|
28
27
|
function enable (config, _tracer) {
|
|
@@ -81,12 +81,11 @@ class VulnerabilityFormatter {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
formatVulnerability (vulnerability, sourcesIndexes, sources) {
|
|
84
|
-
const { type, hash,
|
|
84
|
+
const { type, hash, evidence, location } = vulnerability
|
|
85
85
|
|
|
86
86
|
const formattedVulnerability = {
|
|
87
87
|
type,
|
|
88
88
|
hash,
|
|
89
|
-
stackId,
|
|
90
89
|
evidence: this.formatEvidence(type, evidence, sourcesIndexes, sources),
|
|
91
90
|
location
|
|
92
91
|
}
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
const LRU = require('lru-cache')
|
|
4
4
|
const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
|
|
5
5
|
const { IAST_ENABLED_TAG_KEY, IAST_JSON_TAG_KEY } = require('./tags')
|
|
6
|
-
const standalone = require('../standalone')
|
|
7
|
-
const { SAMPLING_MECHANISM_APPSEC } = require('../../constants')
|
|
8
6
|
const { keepTrace } = require('../../priority_sampler')
|
|
9
7
|
const { reportStackTrace, getCallsiteFrames, canReportStackTrace, STACK_TRACE_NAMESPACES } = require('../stack_trace')
|
|
10
8
|
const { getOriginalPathAndLineFromSourceMap } = require('./taint-tracking/rewriter')
|
|
9
|
+
const { ASM } = require('../../standalone/product')
|
|
11
10
|
|
|
12
11
|
const VULNERABILITIES_KEY = 'vulnerabilities'
|
|
13
12
|
const VULNERABILITY_HASHES_MAX_SIZE = 1000
|
|
@@ -51,15 +50,14 @@ function addVulnerability (iastContext, vulnerability, callSiteFrames) {
|
|
|
51
50
|
|
|
52
51
|
if (!span) return
|
|
53
52
|
|
|
54
|
-
keepTrace(span,
|
|
55
|
-
standalone.sample(span)
|
|
53
|
+
keepTrace(span, ASM)
|
|
56
54
|
|
|
57
55
|
if (stackTraceEnabled && canReportStackTrace(span, maxStackTraces, STACK_TRACE_NAMESPACES.IAST)) {
|
|
58
56
|
const originalCallSiteList = callSiteFrames.map(callsite => replaceCallSiteFromSourceMap(callsite))
|
|
59
57
|
|
|
60
58
|
reportStackTrace(
|
|
61
59
|
span,
|
|
62
|
-
vulnerability.stackId,
|
|
60
|
+
vulnerability.location.stackId,
|
|
63
61
|
originalCallSiteList,
|
|
64
62
|
STACK_TRACE_NAMESPACES.IAST
|
|
65
63
|
)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../log')
|
|
4
4
|
const RuleManager = require('./rule_manager')
|
|
5
|
-
const remoteConfig = require('
|
|
5
|
+
const remoteConfig = require('../remote_config')
|
|
6
6
|
const {
|
|
7
7
|
bodyParser,
|
|
8
8
|
cookieParser,
|
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
incomingHttpRequestEnd,
|
|
12
12
|
passportVerify,
|
|
13
13
|
passportUser,
|
|
14
|
+
expressSession,
|
|
14
15
|
queryParser,
|
|
15
16
|
nextBodyParsed,
|
|
16
17
|
nextQueryParsed,
|
|
@@ -69,6 +70,7 @@ function enable (_config) {
|
|
|
69
70
|
incomingHttpRequestEnd.subscribe(incomingHttpEndTranslator)
|
|
70
71
|
passportVerify.subscribe(onPassportVerify) // possible optimization: only subscribe if collection mode is enabled
|
|
71
72
|
passportUser.subscribe(onPassportDeserializeUser)
|
|
73
|
+
expressSession.subscribe(onExpressSession)
|
|
72
74
|
queryParser.subscribe(onRequestQueryParsed)
|
|
73
75
|
nextBodyParsed.subscribe(onRequestBodyParsed)
|
|
74
76
|
nextQueryParsed.subscribe(onRequestQueryParsed)
|
|
@@ -213,6 +215,25 @@ function onPassportDeserializeUser ({ user, abortController }) {
|
|
|
213
215
|
handleResults(results, store.req, store.req.res, rootSpan, abortController)
|
|
214
216
|
}
|
|
215
217
|
|
|
218
|
+
function onExpressSession ({ req, res, sessionId, abortController }) {
|
|
219
|
+
const rootSpan = web.root(req)
|
|
220
|
+
if (!rootSpan) {
|
|
221
|
+
log.warn('[ASM] No rootSpan found in onExpressSession')
|
|
222
|
+
return
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const isSdkCalled = rootSpan.context()._tags['usr.session_id']
|
|
226
|
+
if (isSdkCalled) return
|
|
227
|
+
|
|
228
|
+
const results = waf.run({
|
|
229
|
+
persistent: {
|
|
230
|
+
[addresses.USER_SESSION_ID]: sessionId
|
|
231
|
+
}
|
|
232
|
+
}, req)
|
|
233
|
+
|
|
234
|
+
handleResults(results, req, res, rootSpan, abortController)
|
|
235
|
+
}
|
|
236
|
+
|
|
216
237
|
function onRequestQueryParsed ({ req, res, query, abortController }) {
|
|
217
238
|
if (!query || typeof query !== 'object') return
|
|
218
239
|
|
|
@@ -327,6 +348,7 @@ function disable () {
|
|
|
327
348
|
if (incomingHttpRequestEnd.hasSubscribers) incomingHttpRequestEnd.unsubscribe(incomingHttpEndTranslator)
|
|
328
349
|
if (passportVerify.hasSubscribers) passportVerify.unsubscribe(onPassportVerify)
|
|
329
350
|
if (passportUser.hasSubscribers) passportUser.unsubscribe(onPassportDeserializeUser)
|
|
351
|
+
if (expressSession.hasSubscribers) expressSession.unsubscribe(onExpressSession)
|
|
330
352
|
if (queryParser.hasSubscribers) queryParser.unsubscribe(onRequestQueryParsed)
|
|
331
353
|
if (nextBodyParsed.hasSubscribers) nextBodyParsed.unsubscribe(onRequestBodyParsed)
|
|
332
354
|
if (nextQueryParsed.hasSubscribers) nextQueryParsed.unsubscribe(onRequestQueryParsed)
|
|
@@ -13,9 +13,8 @@ const {
|
|
|
13
13
|
getRequestMetrics
|
|
14
14
|
} = require('./telemetry')
|
|
15
15
|
const zlib = require('zlib')
|
|
16
|
-
const standalone = require('./standalone')
|
|
17
|
-
const { SAMPLING_MECHANISM_APPSEC } = require('../constants')
|
|
18
16
|
const { keepTrace } = require('../priority_sampler')
|
|
17
|
+
const { ASM } = require('../standalone/product')
|
|
19
18
|
|
|
20
19
|
// default limiter, configurable with setRateLimit()
|
|
21
20
|
let limiter = new Limiter(100)
|
|
@@ -129,9 +128,7 @@ function reportAttack (attackData) {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
if (limiter.isAllowed()) {
|
|
132
|
-
keepTrace(rootSpan,
|
|
133
|
-
|
|
134
|
-
standalone.sample(rootSpan)
|
|
131
|
+
keepTrace(rootSpan, ASM)
|
|
135
132
|
}
|
|
136
133
|
|
|
137
134
|
// TODO: maybe add this to format.js later (to take decision as late as possible)
|
|
@@ -186,9 +183,7 @@ function finishRequest (req, res) {
|
|
|
186
183
|
if (metricsQueue.size) {
|
|
187
184
|
rootSpan.addTags(Object.fromEntries(metricsQueue))
|
|
188
185
|
|
|
189
|
-
keepTrace(rootSpan,
|
|
190
|
-
|
|
191
|
-
standalone.sample(rootSpan)
|
|
186
|
+
keepTrace(rootSpan, ASM)
|
|
192
187
|
|
|
193
188
|
metricsQueue.clear()
|
|
194
189
|
}
|
|
@@ -26,11 +26,15 @@ function setUser (tracer, user) {
|
|
|
26
26
|
setUserTags(user, rootSpan)
|
|
27
27
|
rootSpan.setTag('_dd.appsec.user.collection_mode', 'sdk')
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
const persistent = {
|
|
30
|
+
[addresses.USER_ID]: '' + user.id
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (user.session_id && typeof user.session_id === 'string') {
|
|
34
|
+
persistent[addresses.USER_SESSION_ID] = user.session_id
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
waf.run({ persistent })
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
module.exports = {
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
const log = require('../../log')
|
|
4
4
|
const { getRootSpan } = require('./utils')
|
|
5
5
|
const { setUserTags } = require('./set_user')
|
|
6
|
-
const standalone = require('../standalone')
|
|
7
6
|
const waf = require('../waf')
|
|
8
|
-
const { SAMPLING_MECHANISM_APPSEC } = require('../../constants')
|
|
9
7
|
const { keepTrace } = require('../../priority_sampler')
|
|
10
8
|
const addresses = require('../addresses')
|
|
9
|
+
const { ASM } = require('../../standalone/product')
|
|
11
10
|
|
|
12
11
|
function trackUserLoginSuccessEvent (tracer, user, metadata) {
|
|
13
12
|
// TODO: better user check here and in _setUser() ?
|
|
@@ -79,8 +78,7 @@ function trackEvent (eventName, fields, sdkMethodName, rootSpan) {
|
|
|
79
78
|
|
|
80
79
|
rootSpan.addTags(tags)
|
|
81
80
|
|
|
82
|
-
keepTrace(rootSpan,
|
|
83
|
-
standalone.sample(rootSpan)
|
|
81
|
+
keepTrace(rootSpan, ASM)
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
function runWaf (eventName, user) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strinct'
|
|
2
|
+
|
|
3
|
+
const DD_TELEMETRY_REQUEST_METRICS = Symbol('_dd.appsec.telemetry.request.metrics')
|
|
4
|
+
|
|
5
|
+
const tags = {
|
|
6
|
+
REQUEST_BLOCKED: 'request_blocked',
|
|
7
|
+
RULE_TRIGGERED: 'rule_triggered',
|
|
8
|
+
WAF_TIMEOUT: 'waf_timeout',
|
|
9
|
+
WAF_VERSION: 'waf_version',
|
|
10
|
+
EVENT_RULES_VERSION: 'event_rules_version'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getVersionsTags (wafVersion, rulesVersion) {
|
|
14
|
+
return {
|
|
15
|
+
[tags.WAF_VERSION]: wafVersion,
|
|
16
|
+
[tags.EVENT_RULES_VERSION]: rulesVersion
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
tags,
|
|
22
|
+
getVersionsTags,
|
|
23
|
+
DD_TELEMETRY_REQUEST_METRICS
|
|
24
|
+
}
|