dd-trace 2.0.0-appsec-beta.3 → 2.0.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/MIGRATING.md +65 -0
- package/NOTICE +4 -0
- package/ci/cypress/plugin.js +3 -0
- package/ci/cypress/support.js +1 -0
- package/ci/init.js +13 -0
- package/ci/jest/env.js +14 -0
- package/index.d.ts +35 -48
- package/package.json +7 -4
- package/packages/datadog-instrumentations/index.js +10 -0
- package/packages/datadog-instrumentations/src/bluebird.js +26 -0
- package/packages/datadog-instrumentations/src/dns.js +94 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +120 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
- package/packages/datadog-instrumentations/src/memcached.js +53 -0
- package/packages/datadog-instrumentations/src/mysql.js +67 -0
- package/packages/datadog-instrumentations/src/promise-js.js +15 -0
- package/packages/datadog-instrumentations/src/promise.js +14 -0
- package/packages/datadog-instrumentations/src/q.js +13 -0
- package/packages/datadog-instrumentations/src/when.js +14 -0
- package/packages/datadog-plugin-cucumber/src/index.js +4 -4
- package/packages/datadog-plugin-cypress/src/plugin.js +12 -2
- package/packages/datadog-plugin-cypress/src/support.js +21 -6
- package/packages/datadog-plugin-dns/src/index.js +65 -178
- package/packages/datadog-plugin-fs/src/index.js +7 -3
- package/packages/datadog-plugin-http/src/client.js +9 -24
- package/packages/datadog-plugin-http/src/server.js +5 -0
- package/packages/datadog-plugin-http2/src/client.js +1 -24
- package/packages/datadog-plugin-http2/src/server.js +2 -2
- package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
- package/packages/datadog-plugin-knex/src/index.js +3 -3
- package/packages/datadog-plugin-memcached/src/index.js +41 -63
- package/packages/datadog-plugin-mocha/src/index.js +3 -2
- package/packages/datadog-plugin-moleculer/src/client.js +60 -0
- package/packages/datadog-plugin-moleculer/src/index.js +8 -0
- package/packages/datadog-plugin-moleculer/src/server.js +61 -0
- package/packages/datadog-plugin-moleculer/src/util.js +21 -0
- package/packages/datadog-plugin-mongoose/src/index.js +2 -2
- package/packages/datadog-plugin-mysql/src/index.js +37 -89
- package/packages/datadog-plugin-net/src/index.js +5 -0
- package/packages/datadog-plugin-pino/src/index.js +25 -1
- package/packages/datadog-plugin-redis/src/index.js +31 -1
- package/packages/datadog-plugin-router/src/index.js +28 -3
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/addresses.js +11 -4
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +5 -8
- package/packages/dd-trace/src/{gateway → appsec/gateway}/als.js +1 -0
- package/packages/dd-trace/src/appsec/gateway/channels.js +11 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/engine.js +20 -30
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/index.js +0 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/runner.js +2 -0
- package/packages/dd-trace/src/appsec/index.js +54 -38
- package/packages/dd-trace/src/appsec/recommended.json +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +27 -10
- package/packages/dd-trace/src/config.js +31 -27
- package/packages/dd-trace/src/constants.js +6 -3
- package/packages/dd-trace/src/exporters/agent/request.js +8 -0
- package/packages/dd-trace/src/format.js +26 -39
- package/packages/dd-trace/src/instrumenter.js +6 -1
- package/packages/dd-trace/src/log.js +6 -15
- package/packages/dd-trace/src/noop/span_context.js +0 -1
- package/packages/dd-trace/src/noop/tracer.js +0 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +79 -46
- package/packages/dd-trace/src/opentracing/span.js +2 -7
- package/packages/dd-trace/src/opentracing/span_context.js +2 -4
- package/packages/dd-trace/src/opentracing/tracer.js +5 -23
- package/packages/dd-trace/src/plugin_manager.js +65 -0
- package/packages/dd-trace/src/plugins/index.js +1 -5
- package/packages/dd-trace/src/plugins/plugin.js +63 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -4
- package/packages/dd-trace/src/plugins/util/redis.js +0 -2
- package/packages/dd-trace/src/plugins/util/test.js +9 -4
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -2
- package/packages/dd-trace/src/plugins/util/web.js +6 -16
- package/packages/dd-trace/src/priority_sampler.js +71 -19
- package/packages/dd-trace/src/profiling/exporters/agent.js +35 -34
- package/packages/dd-trace/src/proxy.js +39 -35
- package/packages/dd-trace/src/ritm.js +40 -16
- package/packages/dd-trace/src/span_processor.js +0 -7
- package/packages/dd-trace/src/tracer.js +5 -6
- package/scripts/install_plugin_modules.js +30 -1
- package/packages/datadog-plugin-bluebird/src/index.js +0 -69
- package/packages/datadog-plugin-promise/src/index.js +0 -17
- package/packages/datadog-plugin-promise-js/src/index.js +0 -20
- package/packages/datadog-plugin-q/src/index.js +0 -16
- package/packages/datadog-plugin-when/src/index.js +0 -17
- package/packages/dd-trace/src/gateway/channels.js +0 -8
- package/packages/dd-trace/src/gateway/dc_block.js +0 -68
- package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -36
- package/packages/dd-trace/src/plugins/util/promise.js +0 -31
- package/packages/dd-trace/src/scope/noop/scope_manager.js +0 -28
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// TODO: always use uppercase for command names
|
|
4
|
+
|
|
3
5
|
const tx = require('../../dd-trace/src/plugins/util/redis')
|
|
4
6
|
|
|
7
|
+
function createWrapAddCommand (tracer, config) {
|
|
8
|
+
return function wrapAddCommand (addCommand) {
|
|
9
|
+
return function addCommandWithTrace (command) {
|
|
10
|
+
const name = command[0]
|
|
11
|
+
const args = command.slice(1)
|
|
12
|
+
|
|
13
|
+
if (!config.filter(name)) return addCommand.apply(this, arguments)
|
|
14
|
+
|
|
15
|
+
const scope = tracer.scope()
|
|
16
|
+
const span = startSpan(tracer, config, this, name, args)
|
|
17
|
+
|
|
18
|
+
return tx.wrap(span, scope.bind(addCommand, span).apply(this, arguments))
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
5
23
|
function createWrapInternalSendCommand (tracer, config) {
|
|
6
24
|
return function wrapInternalSendCommand (internalSendCommand) {
|
|
7
25
|
return function internalSendCommandWithTrace (options) {
|
|
@@ -49,9 +67,21 @@ function startSpan (tracer, config, client, command, args) {
|
|
|
49
67
|
}
|
|
50
68
|
|
|
51
69
|
module.exports = [
|
|
70
|
+
{
|
|
71
|
+
name: '@node-redis/client',
|
|
72
|
+
versions: ['>=1'],
|
|
73
|
+
file: 'dist/lib/client/commands-queue.js',
|
|
74
|
+
patch (redis, tracer, config) {
|
|
75
|
+
config = tx.normalizeConfig(config)
|
|
76
|
+
this.wrap(redis.default.prototype, 'addCommand', createWrapAddCommand(tracer, config))
|
|
77
|
+
},
|
|
78
|
+
unpatch (redis) {
|
|
79
|
+
this.unwrap(redis.default.prototype, 'addCommand')
|
|
80
|
+
}
|
|
81
|
+
},
|
|
52
82
|
{
|
|
53
83
|
name: 'redis',
|
|
54
|
-
versions: ['>=2.6'],
|
|
84
|
+
versions: ['>=2.6 <4'],
|
|
55
85
|
patch (redis, tracer, config) {
|
|
56
86
|
config = tx.normalizeConfig(config)
|
|
57
87
|
this.wrap(redis.RedisClient.prototype, 'internal_send_command', createWrapInternalSendCommand(tracer, config))
|
|
@@ -5,6 +5,9 @@ const pathToRegExp = require('path-to-regexp')
|
|
|
5
5
|
const shimmer = require('../../datadog-shimmer')
|
|
6
6
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
7
7
|
|
|
8
|
+
// TODO: clean this up to not use web util internals
|
|
9
|
+
// TODO: stop checking for fast star and fast slash
|
|
10
|
+
|
|
8
11
|
const regexpCache = Object.create(null)
|
|
9
12
|
|
|
10
13
|
function createWrapHandle (tracer, config) {
|
|
@@ -12,6 +15,19 @@ function createWrapHandle (tracer, config) {
|
|
|
12
15
|
return function handleWithTrace (req, res, done) {
|
|
13
16
|
web.patch(req)
|
|
14
17
|
|
|
18
|
+
if (!req._datadog.router) {
|
|
19
|
+
const context = {
|
|
20
|
+
route: '',
|
|
21
|
+
stack: []
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
web.beforeEnd(req, () => {
|
|
25
|
+
req._datadog.paths = [context.route]
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
req._datadog.router = context
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
return handle.apply(this, arguments)
|
|
16
32
|
}
|
|
17
33
|
}
|
|
@@ -82,8 +98,8 @@ function wrapNext (layer, req, next) {
|
|
|
82
98
|
const originalNext = next
|
|
83
99
|
|
|
84
100
|
return function (error) {
|
|
85
|
-
if (
|
|
86
|
-
|
|
101
|
+
if (layer.path && !isFastStar(layer) && !isFastSlash(layer)) {
|
|
102
|
+
req._datadog.router.stack.pop()
|
|
87
103
|
}
|
|
88
104
|
|
|
89
105
|
web.finish(req, error)
|
|
@@ -99,7 +115,16 @@ function callHandle (layer, handle, req, args) {
|
|
|
99
115
|
// Try to guess which path actually matched
|
|
100
116
|
for (let i = 0; i < matchers.length; i++) {
|
|
101
117
|
if (matchers[i].test(layer)) {
|
|
102
|
-
|
|
118
|
+
const context = req._datadog.router
|
|
119
|
+
|
|
120
|
+
context.stack.push(matchers[i].path)
|
|
121
|
+
|
|
122
|
+
const route = context.stack.join('')
|
|
123
|
+
|
|
124
|
+
// Longer route is more likely to be the actual route handler route.
|
|
125
|
+
if (route.length > context.route.length) {
|
|
126
|
+
context.route = route
|
|
127
|
+
}
|
|
103
128
|
|
|
104
129
|
break
|
|
105
130
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = '2.0.0
|
|
1
|
+
module.exports = '2.0.0'
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
|
-
|
|
4
|
+
HTTP_INCOMING_BODY: 'server.request.body',
|
|
5
|
+
HTTP_INCOMING_QUERY: 'server.request.query',
|
|
5
6
|
HTTP_INCOMING_HEADERS: 'server.request.headers.no_cookies',
|
|
7
|
+
// TODO: 'server.request.trailers',
|
|
8
|
+
HTTP_INCOMING_URL: 'server.request.uri.raw',
|
|
6
9
|
HTTP_INCOMING_METHOD: 'server.request.method',
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
HTTP_INCOMING_ENDPOINT: 'server.request.framework_endpoint',
|
|
11
|
+
HTTP_INCOMING_PARAMS: 'server.request.path_params',
|
|
12
|
+
HTTP_INCOMING_COOKIES: 'server.request.cookies',
|
|
9
13
|
HTTP_INCOMING_RESPONSE_CODE: 'server.response.status',
|
|
10
|
-
HTTP_INCOMING_RESPONSE_HEADERS: 'server.response.headers.no_cookies'
|
|
14
|
+
HTTP_INCOMING_RESPONSE_HEADERS: 'server.response.headers.no_cookies',
|
|
15
|
+
// TODO: 'server.response.trailers',
|
|
16
|
+
HTTP_INCOMING_REMOTE_IP: 'server.request.client_ip',
|
|
17
|
+
HTTP_INCOMING_REMOTE_PORT: 'server.request.client_port'
|
|
11
18
|
}
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../../log')
|
|
4
4
|
const addresses = require('../addresses')
|
|
5
|
-
const Gateway = require('
|
|
5
|
+
const Gateway = require('../gateway/engine')
|
|
6
6
|
const Reporter = require('../reporter')
|
|
7
7
|
|
|
8
|
-
let warned = false
|
|
9
|
-
|
|
10
8
|
const validAddressSet = new Set(Object.values(addresses))
|
|
11
9
|
|
|
12
10
|
const DEFAULT_MAX_BUDGET = 5e3 // µs
|
|
@@ -20,10 +18,7 @@ class WAFCallback {
|
|
|
20
18
|
|
|
21
19
|
return new DDWAF(rules)
|
|
22
20
|
} catch (err) {
|
|
23
|
-
|
|
24
|
-
log.warn('AppSec could not load native package. In-app WAF features will not be available.')
|
|
25
|
-
warned = true
|
|
26
|
-
}
|
|
21
|
+
log.error('AppSec could not load native package. In-app WAF features will not be available.')
|
|
27
22
|
|
|
28
23
|
throw err
|
|
29
24
|
}
|
|
@@ -90,7 +85,8 @@ class WAFCallback {
|
|
|
90
85
|
|
|
91
86
|
return this.applyResult(result, store)
|
|
92
87
|
} catch (err) {
|
|
93
|
-
log.
|
|
88
|
+
log.error('Error while running the AppSec WAF')
|
|
89
|
+
log.error(err)
|
|
94
90
|
}
|
|
95
91
|
}
|
|
96
92
|
|
|
@@ -99,6 +95,7 @@ class WAFCallback {
|
|
|
99
95
|
Reporter.reportAttack(result.data, store)
|
|
100
96
|
}
|
|
101
97
|
|
|
98
|
+
// TODO: use these values later for budget management
|
|
102
99
|
// result.perfData
|
|
103
100
|
// result.perfTotalRuntime
|
|
104
101
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const dc = require('diagnostics_channel')
|
|
4
|
+
|
|
5
|
+
// TODO: use TBD naming convention
|
|
6
|
+
// or directly use http plugin's channels
|
|
7
|
+
// when it gets converted to new plugin system
|
|
8
|
+
module.exports = {
|
|
9
|
+
incomingHttpRequestStart: dc.channel('dd-trace:incomingHttpRequestStart'),
|
|
10
|
+
incomingHttpRequestEnd: dc.channel('dd-trace:incomingHttpRequestEnd')
|
|
11
|
+
}
|
|
@@ -43,10 +43,10 @@ class SubscriptionManager {
|
|
|
43
43
|
const knownSubscriptions = new Set()
|
|
44
44
|
|
|
45
45
|
// TODO: possible optimization: collect matchedSubscriptions on the fly in Context#setValue
|
|
46
|
-
|
|
47
|
-
const matchedSubscriptions = this.addressToSubscriptions.get(
|
|
46
|
+
newAddresses.forEach((newAddress) => {
|
|
47
|
+
const matchedSubscriptions = this.addressToSubscriptions.get(newAddress)
|
|
48
48
|
|
|
49
|
-
if (matchedSubscriptions === undefined)
|
|
49
|
+
if (matchedSubscriptions === undefined) return
|
|
50
50
|
|
|
51
51
|
for (let j = 0; j < matchedSubscriptions.length; ++j) {
|
|
52
52
|
const subscription = matchedSubscriptions[j]
|
|
@@ -64,24 +64,24 @@ class SubscriptionManager {
|
|
|
64
64
|
subscriptions.add(subscription)
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
}
|
|
67
|
+
})
|
|
68
68
|
|
|
69
69
|
return { addresses, subscriptions }
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
dispatch (newAddresses, allAddresses, context) {
|
|
73
|
-
const
|
|
73
|
+
const matches = this.matchSubscriptions(newAddresses, allAddresses)
|
|
74
74
|
|
|
75
75
|
// TODO: possible optimization
|
|
76
|
-
// if
|
|
76
|
+
// check if matches.subscriptions is empty here instead of in runner.js
|
|
77
77
|
|
|
78
78
|
const params = {}
|
|
79
79
|
|
|
80
|
-
addresses.forEach((address) => {
|
|
80
|
+
matches.addresses.forEach((address) => {
|
|
81
81
|
params[address] = context.resolve(address)
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
return Runner.runSubscriptions(subscriptions, params)
|
|
84
|
+
return Runner.runSubscriptions(matches.subscriptions, params)
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -91,50 +91,40 @@ class Context {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
constructor () {
|
|
94
|
+
// TODO: this probably don't need to be a Map()
|
|
94
95
|
this.store = new Map()
|
|
95
96
|
this.allAddresses = new Set()
|
|
96
|
-
this.newAddresses =
|
|
97
|
+
this.newAddresses = new Set()
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
clear () {
|
|
100
101
|
this.store = new Map()
|
|
101
102
|
this.allAddresses = new Set()
|
|
102
|
-
this.newAddresses =
|
|
103
|
+
this.newAddresses = new Set()
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
setValue (address, value) {
|
|
106
107
|
if (this.allAddresses.size >= MAX_CONTEXT_SIZE) return this
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (!this.newAddresses.includes(address)) {
|
|
114
|
-
this.allAddresses.add(address)
|
|
115
|
-
this.newAddresses.push(address)
|
|
109
|
+
// cannot optimize for objects because they're pointers
|
|
110
|
+
if (typeof value !== 'object') {
|
|
111
|
+
const oldValue = this.store.get(address)
|
|
112
|
+
if (oldValue === value) return this
|
|
116
113
|
}
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
setMultipleValues (params) {
|
|
122
|
-
const addresses = Object.keys(params)
|
|
123
|
-
|
|
124
|
-
for (let i = 0; i < addresses.length; ++i) {
|
|
125
|
-
const address = addresses[i]
|
|
126
|
-
this.setValue(address, params[address])
|
|
127
|
-
}
|
|
115
|
+
this.store.set(address, value)
|
|
116
|
+
this.allAddresses.add(address)
|
|
117
|
+
this.newAddresses.add(address)
|
|
128
118
|
|
|
129
119
|
return this
|
|
130
120
|
}
|
|
131
121
|
|
|
132
122
|
dispatch () {
|
|
133
|
-
if (this.newAddresses.
|
|
123
|
+
if (this.newAddresses.size === 0) return []
|
|
134
124
|
|
|
135
125
|
const result = Context.manager.dispatch(this.newAddresses, this.allAddresses, this)
|
|
136
126
|
|
|
137
|
-
this.newAddresses
|
|
127
|
+
this.newAddresses.clear()
|
|
138
128
|
|
|
139
129
|
return result
|
|
140
130
|
}
|
|
File without changes
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const log = require('../log')
|
|
5
5
|
const RuleManager = require('./rule_manager')
|
|
6
|
-
const {
|
|
7
|
-
const Gateway = require('
|
|
6
|
+
const { incomingHttpRequestStart, incomingHttpRequestEnd } = require('./gateway/channels')
|
|
7
|
+
const Gateway = require('./gateway/engine')
|
|
8
8
|
const addresses = require('./addresses')
|
|
9
9
|
const Reporter = require('./reporter')
|
|
10
10
|
|
|
@@ -17,47 +17,40 @@ function enable (config) {
|
|
|
17
17
|
|
|
18
18
|
RuleManager.applyRules(rules)
|
|
19
19
|
} catch (err) {
|
|
20
|
-
log.error(
|
|
20
|
+
log.error('Unable to start AppSec')
|
|
21
|
+
log.error(err)
|
|
21
22
|
|
|
22
23
|
// abort AppSec start
|
|
23
24
|
RuleManager.clearAllRules()
|
|
24
25
|
return
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
INCOMING_HTTP_REQUEST_END.subscribe(incomingHttpEndTranslator)
|
|
28
|
+
Reporter.setRateLimit(config.appsec.rateLimit)
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
incomingHttpRequestStart.subscribe(incomingHttpStartTranslator)
|
|
31
|
+
incomingHttpRequestEnd.subscribe(incomingHttpEndTranslator)
|
|
32
32
|
|
|
33
|
-
// add needed
|
|
34
|
-
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_URL)
|
|
33
|
+
// add fields needed for HTTP context reporting
|
|
35
34
|
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_HEADERS)
|
|
36
|
-
Gateway.manager.addresses.add(addresses.
|
|
37
|
-
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_REMOTE_IP)
|
|
38
|
-
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_REMOTE_PORT)
|
|
39
|
-
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_RESPONSE_CODE)
|
|
35
|
+
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_ENDPOINT)
|
|
40
36
|
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_RESPONSE_HEADERS)
|
|
37
|
+
Gateway.manager.addresses.add(addresses.HTTP_INCOMING_REMOTE_IP)
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
function incomingHttpStartTranslator (data) {
|
|
41
|
+
// TODO: get span from datadog-core storage instead
|
|
42
|
+
const topSpan = data.req._datadog && data.req._datadog.span
|
|
43
|
+
if (topSpan) {
|
|
44
|
+
topSpan.addTags({
|
|
45
|
+
'_dd.appsec.enabled': 1,
|
|
46
|
+
'_dd.runtime_family': 'nodejs'
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
const store = Gateway.startContext()
|
|
45
51
|
|
|
46
52
|
store.set('req', data.req)
|
|
47
53
|
store.set('res', data.res)
|
|
48
|
-
|
|
49
|
-
const headers = Object.assign({}, data.req.headers)
|
|
50
|
-
delete headers.cookie
|
|
51
|
-
|
|
52
|
-
const context = store.get('context')
|
|
53
|
-
|
|
54
|
-
Gateway.propagate({
|
|
55
|
-
[addresses.HTTP_INCOMING_URL]: data.req.url,
|
|
56
|
-
[addresses.HTTP_INCOMING_HEADERS]: headers,
|
|
57
|
-
[addresses.HTTP_INCOMING_METHOD]: data.req.method,
|
|
58
|
-
[addresses.HTTP_INCOMING_REMOTE_IP]: data.req.socket.remoteAddress,
|
|
59
|
-
[addresses.HTTP_INCOMING_REMOTE_PORT]: data.req.socket.remotePort
|
|
60
|
-
}, context)
|
|
61
54
|
}
|
|
62
55
|
|
|
63
56
|
function incomingHttpEndTranslator (data) {
|
|
@@ -65,14 +58,41 @@ function incomingHttpEndTranslator (data) {
|
|
|
65
58
|
|
|
66
59
|
if (!context) return
|
|
67
60
|
|
|
61
|
+
const requestHeaders = Object.assign({}, data.req.headers)
|
|
62
|
+
delete requestHeaders.cookie
|
|
63
|
+
|
|
68
64
|
// TODO: this doesn't support headers sent with res.writeHead()
|
|
69
|
-
const
|
|
70
|
-
delete
|
|
65
|
+
const responseHeaders = Object.assign({}, data.res.getHeaders())
|
|
66
|
+
delete responseHeaders['set-cookie']
|
|
71
67
|
|
|
72
|
-
|
|
68
|
+
const payload = {
|
|
69
|
+
[addresses.HTTP_INCOMING_URL]: data.req.url,
|
|
70
|
+
[addresses.HTTP_INCOMING_HEADERS]: requestHeaders,
|
|
71
|
+
[addresses.HTTP_INCOMING_METHOD]: data.req.method,
|
|
72
|
+
[addresses.HTTP_INCOMING_REMOTE_IP]: data.req.socket.remoteAddress,
|
|
73
|
+
[addresses.HTTP_INCOMING_REMOTE_PORT]: data.req.socket.remotePort,
|
|
73
74
|
[addresses.HTTP_INCOMING_RESPONSE_CODE]: data.res.statusCode,
|
|
74
|
-
[addresses.HTTP_INCOMING_RESPONSE_HEADERS]:
|
|
75
|
-
}
|
|
75
|
+
[addresses.HTTP_INCOMING_RESPONSE_HEADERS]: responseHeaders
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// TODO: temporary express instrumentation, will use express plugin later
|
|
79
|
+
if (data.req.query && typeof data.req.query === 'object') {
|
|
80
|
+
payload[addresses.HTTP_INCOMING_QUERY] = data.req.query
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (data.req.route && typeof data.req.route.path === 'string') {
|
|
84
|
+
payload[addresses.HTTP_INCOMING_ENDPOINT] = data.req.route.path
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (data.req.params && typeof data.req.params === 'object') {
|
|
88
|
+
payload[addresses.HTTP_INCOMING_PARAMS] = data.req.params
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (data.req.cookies && typeof data.req.cookies === 'object') {
|
|
92
|
+
payload[addresses.HTTP_INCOMING_COOKIES] = data.req.cookies
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Gateway.propagate(payload, context)
|
|
76
96
|
|
|
77
97
|
Reporter.finishAttacks(data.req, context)
|
|
78
98
|
}
|
|
@@ -80,13 +100,9 @@ function incomingHttpEndTranslator (data) {
|
|
|
80
100
|
function disable () {
|
|
81
101
|
RuleManager.clearAllRules()
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
const tags = global._ddtrace._tracer._tags
|
|
87
|
-
|
|
88
|
-
delete tags['_dd.appsec.enabled']
|
|
89
|
-
delete tags['_dd.runtime_family']
|
|
103
|
+
// Channel#unsubscribe() is undefined for non active channels
|
|
104
|
+
if (incomingHttpRequestStart.hasSubscribers) incomingHttpRequestStart.unsubscribe(incomingHttpStartTranslator)
|
|
105
|
+
if (incomingHttpRequestEnd.hasSubscribers) incomingHttpRequestEnd.unsubscribe(incomingHttpEndTranslator)
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
module.exports = {
|