dd-trace 2.23.0 → 2.24.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 +17 -1
- package/package.json +7 -6
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/http/server.js +7 -1
- package/packages/datadog-instrumentations/src/ldapjs.js +91 -0
- package/packages/datadog-instrumentations/src/pg.js +1 -2
- package/packages/datadog-plugin-http/src/server.js +7 -3
- package/packages/datadog-plugin-router/src/index.js +6 -3
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +44 -0
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/gateway/engine/engine.js +1 -1
- package/packages/dd-trace/src/appsec/gateway/engine/index.js +6 -1
- package/packages/dd-trace/src/appsec/gateway/engine/runner.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +40 -2
- package/packages/dd-trace/src/appsec/iast/iast-context.js +3 -1
- package/packages/dd-trace/src/appsec/iast/index.js +7 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +6 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +12 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -29
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +16 -15
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +85 -0
- package/packages/dd-trace/src/appsec/index.js +68 -27
- package/packages/dd-trace/src/{plugins/util → appsec}/ip_blocklist.js +0 -0
- package/packages/dd-trace/src/appsec/ip_extractor.js +98 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +2 -1
- package/packages/dd-trace/src/appsec/templates/blocked.html +99 -0
- package/packages/dd-trace/src/appsec/templates/blocked.json +8 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +18 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +12 -6
- package/packages/dd-trace/src/config.js +25 -3
- package/packages/dd-trace/src/plugin_manager.js +1 -11
- package/packages/dd-trace/src/plugins/util/web.js +1 -104
|
@@ -119,10 +119,8 @@ module.exports = class PluginManager {
|
|
|
119
119
|
const {
|
|
120
120
|
logInjection,
|
|
121
121
|
serviceMapping,
|
|
122
|
-
clientIpHeaderDisabled,
|
|
123
|
-
clientIpHeader,
|
|
124
|
-
site,
|
|
125
122
|
queryStringObfuscation,
|
|
123
|
+
site,
|
|
126
124
|
url,
|
|
127
125
|
dbmPropagationMode
|
|
128
126
|
} = this._tracerConfig
|
|
@@ -137,14 +135,6 @@ module.exports = class PluginManager {
|
|
|
137
135
|
sharedConfig.queryStringObfuscation = queryStringObfuscation
|
|
138
136
|
}
|
|
139
137
|
|
|
140
|
-
if (clientIpHeaderDisabled !== undefined) {
|
|
141
|
-
sharedConfig.clientIpHeaderDisabled = clientIpHeaderDisabled
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (clientIpHeader !== undefined) {
|
|
145
|
-
sharedConfig.clientIpHeader = clientIpHeader
|
|
146
|
-
}
|
|
147
|
-
|
|
148
138
|
sharedConfig.dbmPropagationMode = dbmPropagationMode
|
|
149
139
|
|
|
150
140
|
if (serviceMapping && serviceMapping[name]) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const net = require('net')
|
|
4
3
|
const uniq = require('lodash.uniq')
|
|
5
4
|
const analyticsSampler = require('../../analytics_sampler')
|
|
6
5
|
const FORMAT_HTTP_HEADERS = 'http_headers'
|
|
@@ -9,8 +8,6 @@ const tags = require('../../../../../ext/tags')
|
|
|
9
8
|
const types = require('../../../../../ext/types')
|
|
10
9
|
const kinds = require('../../../../../ext/kinds')
|
|
11
10
|
const urlFilter = require('./urlfilter')
|
|
12
|
-
const BlockList = require('./ip_blocklist')
|
|
13
|
-
const { incomingHttpRequestEnd } = require('../../appsec/gateway/channels')
|
|
14
11
|
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../constants')
|
|
15
12
|
|
|
16
13
|
const WEB = types.WEB
|
|
@@ -27,25 +24,12 @@ const HTTP_ROUTE = tags.HTTP_ROUTE
|
|
|
27
24
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
28
25
|
const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
|
|
29
26
|
const HTTP_USERAGENT = tags.HTTP_USERAGENT
|
|
30
|
-
const HTTP_CLIENT_IP = tags.HTTP_CLIENT_IP
|
|
31
27
|
const MANUAL_DROP = tags.MANUAL_DROP
|
|
32
28
|
|
|
33
29
|
const HTTP2_HEADER_AUTHORITY = ':authority'
|
|
34
30
|
const HTTP2_HEADER_SCHEME = ':scheme'
|
|
35
31
|
const HTTP2_HEADER_PATH = ':path'
|
|
36
32
|
|
|
37
|
-
const ipHeaderList = [
|
|
38
|
-
'x-forwarded-for',
|
|
39
|
-
'x-real-ip',
|
|
40
|
-
'client-ip',
|
|
41
|
-
'x-forwarded',
|
|
42
|
-
'x-cluster-client-ip',
|
|
43
|
-
'forwarded-for',
|
|
44
|
-
'forwarded',
|
|
45
|
-
'via',
|
|
46
|
-
'true-client-ip'
|
|
47
|
-
]
|
|
48
|
-
|
|
49
33
|
const contexts = new WeakMap()
|
|
50
34
|
const ends = new WeakMap()
|
|
51
35
|
|
|
@@ -320,56 +304,15 @@ const web = {
|
|
|
320
304
|
},
|
|
321
305
|
|
|
322
306
|
finishAll (context) {
|
|
323
|
-
const { req, res } = context
|
|
324
|
-
|
|
325
307
|
for (const beforeEnd of context.beforeEnd) {
|
|
326
308
|
beforeEnd()
|
|
327
309
|
}
|
|
328
310
|
|
|
329
311
|
web.finishMiddleware(context)
|
|
330
312
|
|
|
331
|
-
if (incomingHttpRequestEnd.hasSubscribers) {
|
|
332
|
-
incomingHttpRequestEnd.publish({ req, res })
|
|
333
|
-
}
|
|
334
|
-
|
|
335
313
|
web.finishSpan(context)
|
|
336
314
|
},
|
|
337
315
|
|
|
338
|
-
extractIp (context) {
|
|
339
|
-
const { req, config } = context
|
|
340
|
-
|
|
341
|
-
if (config.clientIpHeaderDisabled) return
|
|
342
|
-
|
|
343
|
-
const headers = req.headers
|
|
344
|
-
|
|
345
|
-
if (config.clientIpHeader) {
|
|
346
|
-
const header = headers[config.clientIpHeader]
|
|
347
|
-
if (!header) return
|
|
348
|
-
|
|
349
|
-
return findFirstIp(header)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const foundHeaders = []
|
|
353
|
-
|
|
354
|
-
for (let i = 0; i < ipHeaderList.length; i++) {
|
|
355
|
-
if (headers[ipHeaderList[i]]) {
|
|
356
|
-
foundHeaders.push(ipHeaderList[i])
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if (foundHeaders.length === 1) {
|
|
361
|
-
const header = headers[foundHeaders[0]]
|
|
362
|
-
const firstIp = findFirstIp(header)
|
|
363
|
-
|
|
364
|
-
if (firstIp) return firstIp
|
|
365
|
-
} else if (foundHeaders.length > 1) {
|
|
366
|
-
log.error(`Cannot find client IP: multiple IP headers detected ${foundHeaders}`)
|
|
367
|
-
return
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return req.socket && req.socket.remoteAddress
|
|
371
|
-
},
|
|
372
|
-
|
|
373
316
|
obfuscateQs (config, url) {
|
|
374
317
|
const { queryStringObfuscation } = config
|
|
375
318
|
|
|
@@ -486,8 +429,7 @@ function addRequestTags (context) {
|
|
|
486
429
|
[HTTP_METHOD]: req.method,
|
|
487
430
|
[SPAN_KIND]: SERVER,
|
|
488
431
|
[SPAN_TYPE]: WEB,
|
|
489
|
-
[HTTP_USERAGENT]: req.headers['user-agent']
|
|
490
|
-
[HTTP_CLIENT_IP]: web.extractIp(context)
|
|
432
|
+
[HTTP_USERAGENT]: req.headers['user-agent']
|
|
491
433
|
})
|
|
492
434
|
|
|
493
435
|
addHeaders(context)
|
|
@@ -555,51 +497,6 @@ function getProtocol (req) {
|
|
|
555
497
|
return 'http'
|
|
556
498
|
}
|
|
557
499
|
|
|
558
|
-
const privateCIDRs = [
|
|
559
|
-
'127.0.0.0/8',
|
|
560
|
-
'10.0.0.0/8',
|
|
561
|
-
'172.16.0.0/12',
|
|
562
|
-
'192.168.0.0/16',
|
|
563
|
-
'169.254.0.0/16',
|
|
564
|
-
'::1/128',
|
|
565
|
-
'fec0::/10',
|
|
566
|
-
'fe80::/10',
|
|
567
|
-
'fc00::/7',
|
|
568
|
-
'fd00::/8'
|
|
569
|
-
]
|
|
570
|
-
|
|
571
|
-
const privateIPMatcher = new BlockList()
|
|
572
|
-
|
|
573
|
-
for (const cidr of privateCIDRs) {
|
|
574
|
-
const [ address, prefix ] = cidr.split('/')
|
|
575
|
-
|
|
576
|
-
privateIPMatcher.addSubnet(address, parseInt(prefix), net.isIPv6(address) ? 'ipv6' : 'ipv4')
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
function findFirstIp (str) {
|
|
580
|
-
let firstPrivateIp
|
|
581
|
-
const splitted = str.split(',')
|
|
582
|
-
|
|
583
|
-
for (let i = 0; i < splitted.length; i++) {
|
|
584
|
-
const chunk = splitted[i].trim()
|
|
585
|
-
|
|
586
|
-
// TODO: strip port and interface data ?
|
|
587
|
-
|
|
588
|
-
const type = net.isIP(chunk)
|
|
589
|
-
if (!type) continue
|
|
590
|
-
|
|
591
|
-
if (!privateIPMatcher.check(chunk, type === 6 ? 'ipv6' : 'ipv4')) {
|
|
592
|
-
// it's public, return it immediately
|
|
593
|
-
return chunk
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// it's private, only save the first one found
|
|
597
|
-
if (!firstPrivateIp) firstPrivateIp = chunk
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
return firstPrivateIp
|
|
601
|
-
}
|
|
602
|
-
|
|
603
500
|
function getHeadersToRecord (config) {
|
|
604
501
|
if (Array.isArray(config.headers)) {
|
|
605
502
|
try {
|