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.
Files changed (91) hide show
  1. package/MIGRATING.md +65 -0
  2. package/NOTICE +4 -0
  3. package/ci/cypress/plugin.js +3 -0
  4. package/ci/cypress/support.js +1 -0
  5. package/ci/init.js +13 -0
  6. package/ci/jest/env.js +14 -0
  7. package/index.d.ts +35 -48
  8. package/package.json +7 -4
  9. package/packages/datadog-instrumentations/index.js +10 -0
  10. package/packages/datadog-instrumentations/src/bluebird.js +26 -0
  11. package/packages/datadog-instrumentations/src/dns.js +94 -0
  12. package/packages/datadog-instrumentations/src/helpers/instrument.js +120 -0
  13. package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
  14. package/packages/datadog-instrumentations/src/memcached.js +53 -0
  15. package/packages/datadog-instrumentations/src/mysql.js +67 -0
  16. package/packages/datadog-instrumentations/src/promise-js.js +15 -0
  17. package/packages/datadog-instrumentations/src/promise.js +14 -0
  18. package/packages/datadog-instrumentations/src/q.js +13 -0
  19. package/packages/datadog-instrumentations/src/when.js +14 -0
  20. package/packages/datadog-plugin-cucumber/src/index.js +4 -4
  21. package/packages/datadog-plugin-cypress/src/plugin.js +12 -2
  22. package/packages/datadog-plugin-cypress/src/support.js +21 -6
  23. package/packages/datadog-plugin-dns/src/index.js +65 -178
  24. package/packages/datadog-plugin-fs/src/index.js +7 -3
  25. package/packages/datadog-plugin-http/src/client.js +9 -24
  26. package/packages/datadog-plugin-http/src/server.js +5 -0
  27. package/packages/datadog-plugin-http2/src/client.js +1 -24
  28. package/packages/datadog-plugin-http2/src/server.js +2 -2
  29. package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
  30. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
  31. package/packages/datadog-plugin-knex/src/index.js +3 -3
  32. package/packages/datadog-plugin-memcached/src/index.js +41 -63
  33. package/packages/datadog-plugin-mocha/src/index.js +3 -2
  34. package/packages/datadog-plugin-moleculer/src/client.js +60 -0
  35. package/packages/datadog-plugin-moleculer/src/index.js +8 -0
  36. package/packages/datadog-plugin-moleculer/src/server.js +61 -0
  37. package/packages/datadog-plugin-moleculer/src/util.js +21 -0
  38. package/packages/datadog-plugin-mongoose/src/index.js +2 -2
  39. package/packages/datadog-plugin-mysql/src/index.js +37 -89
  40. package/packages/datadog-plugin-net/src/index.js +5 -0
  41. package/packages/datadog-plugin-pino/src/index.js +25 -1
  42. package/packages/datadog-plugin-redis/src/index.js +31 -1
  43. package/packages/datadog-plugin-router/src/index.js +28 -3
  44. package/packages/dd-trace/lib/version.js +1 -1
  45. package/packages/dd-trace/src/appsec/addresses.js +11 -4
  46. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +5 -8
  47. package/packages/dd-trace/src/{gateway → appsec/gateway}/als.js +1 -0
  48. package/packages/dd-trace/src/appsec/gateway/channels.js +11 -0
  49. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/engine.js +20 -30
  50. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/index.js +0 -0
  51. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/runner.js +2 -0
  52. package/packages/dd-trace/src/appsec/index.js +54 -38
  53. package/packages/dd-trace/src/appsec/recommended.json +1 -1
  54. package/packages/dd-trace/src/appsec/reporter.js +27 -10
  55. package/packages/dd-trace/src/config.js +31 -27
  56. package/packages/dd-trace/src/constants.js +6 -3
  57. package/packages/dd-trace/src/exporters/agent/request.js +8 -0
  58. package/packages/dd-trace/src/format.js +26 -39
  59. package/packages/dd-trace/src/instrumenter.js +6 -1
  60. package/packages/dd-trace/src/log.js +6 -15
  61. package/packages/dd-trace/src/noop/span_context.js +0 -1
  62. package/packages/dd-trace/src/noop/tracer.js +0 -6
  63. package/packages/dd-trace/src/opentracing/propagation/text_map.js +79 -46
  64. package/packages/dd-trace/src/opentracing/span.js +2 -7
  65. package/packages/dd-trace/src/opentracing/span_context.js +2 -4
  66. package/packages/dd-trace/src/opentracing/tracer.js +5 -23
  67. package/packages/dd-trace/src/plugin_manager.js +65 -0
  68. package/packages/dd-trace/src/plugins/index.js +1 -5
  69. package/packages/dd-trace/src/plugins/plugin.js +63 -0
  70. package/packages/dd-trace/src/plugins/util/ci.js +13 -4
  71. package/packages/dd-trace/src/plugins/util/redis.js +0 -2
  72. package/packages/dd-trace/src/plugins/util/test.js +9 -4
  73. package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -2
  74. package/packages/dd-trace/src/plugins/util/web.js +6 -16
  75. package/packages/dd-trace/src/priority_sampler.js +71 -19
  76. package/packages/dd-trace/src/profiling/exporters/agent.js +35 -34
  77. package/packages/dd-trace/src/proxy.js +39 -35
  78. package/packages/dd-trace/src/ritm.js +40 -16
  79. package/packages/dd-trace/src/span_processor.js +0 -7
  80. package/packages/dd-trace/src/tracer.js +5 -6
  81. package/scripts/install_plugin_modules.js +30 -1
  82. package/packages/datadog-plugin-bluebird/src/index.js +0 -69
  83. package/packages/datadog-plugin-promise/src/index.js +0 -17
  84. package/packages/datadog-plugin-promise-js/src/index.js +0 -20
  85. package/packages/datadog-plugin-q/src/index.js +0 -16
  86. package/packages/datadog-plugin-when/src/index.js +0 -17
  87. package/packages/dd-trace/src/gateway/channels.js +0 -8
  88. package/packages/dd-trace/src/gateway/dc_block.js +0 -68
  89. package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -36
  90. package/packages/dd-trace/src/plugins/util/promise.js +0 -31
  91. 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 (!error && layer.path && !isFastStar(layer) && !isFastSlash(layer)) {
86
- web.exitRoute(req)
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
- web.enterRoute(req, matchers[i].path)
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-pre'
1
+ module.exports = '2.0.0'
@@ -1,11 +1,18 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = {
4
- HTTP_INCOMING_URL: 'server.request.uri.raw',
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
- HTTP_INCOMING_REMOTE_IP: 'server.request.client_ip',
8
- HTTP_INCOMING_REMOTE_PORT: 'server.request.client_port',
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('../../gateway/engine')
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
- if (!warned) {
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.warn('Error while running the AppSec WAF')
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
  }
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ // TODO: use datadog-core storage instead
3
4
  const { AsyncLocalStorage } = require('async_hooks')
4
5
 
5
6
  module.exports = new AsyncLocalStorage()
@@ -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
- for (let i = 0; i < newAddresses.length; ++i) {
47
- const matchedSubscriptions = this.addressToSubscriptions.get(newAddresses[i])
46
+ newAddresses.forEach((newAddress) => {
47
+ const matchedSubscriptions = this.addressToSubscriptions.get(newAddress)
48
48
 
49
- if (matchedSubscriptions === undefined) continue
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 { addresses, subscriptions } = this.matchSubscriptions(newAddresses, allAddresses)
73
+ const matches = this.matchSubscriptions(newAddresses, allAddresses)
74
74
 
75
75
  // TODO: possible optimization
76
- // if(!subscriptions.size) return []
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 = [] // TODO: maybe this should be a Set
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
- const oldValue = this.store.get(address)
109
- if (oldValue === value) return this
110
-
111
- this.store.set(address, value)
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
- return this
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.length === 0) return []
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
  }
@@ -12,6 +12,8 @@ function runSubscriptions (subscriptions, params) {
12
12
 
13
13
  const store = als.getStore()
14
14
 
15
+ // TODO: possible optimization
16
+ // can we deduplicate those before ?
15
17
  const executedCallbacks = new Set()
16
18
 
17
19
  for (const subscription of subscriptions) {
@@ -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 { INCOMING_HTTP_REQUEST_START, INCOMING_HTTP_REQUEST_END } = require('../gateway/channels')
7
- const Gateway = require('../gateway/engine/index')
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(`Unable to apply AppSec rules: ${err}`)
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
- INCOMING_HTTP_REQUEST_START.subscribe(incomingHttpStartTranslator)
28
- INCOMING_HTTP_REQUEST_END.subscribe(incomingHttpEndTranslator)
28
+ Reporter.setRateLimit(config.appsec.rateLimit)
29
29
 
30
- config.tags['_dd.appsec.enabled'] = 1
31
- config.tags['_dd.runtime_family'] = 'nodejs'
30
+ incomingHttpRequestStart.subscribe(incomingHttpStartTranslator)
31
+ incomingHttpRequestEnd.subscribe(incomingHttpEndTranslator)
32
32
 
33
- // add needed fields for HTTP context reporting
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.HTTP_INCOMING_METHOD)
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 headers = Object.assign({}, data.res.getHeaders())
70
- delete headers['set-cookie']
65
+ const responseHeaders = Object.assign({}, data.res.getHeaders())
66
+ delete responseHeaders['set-cookie']
71
67
 
72
- Gateway.propagate({
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]: headers
75
- }, context)
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
- if (INCOMING_HTTP_REQUEST_START.hasSubscribers) INCOMING_HTTP_REQUEST_START.unsubscribe(incomingHttpStartTranslator)
84
- if (INCOMING_HTTP_REQUEST_END.hasSubscribers) INCOMING_HTTP_REQUEST_END.unsubscribe(incomingHttpEndTranslator)
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 = {