From 335142a628462a6f62a8a6b2974d839b43727af3 Mon Sep 17 00:00:00 2001 From: Ugaitz Urien Date: Mon, 19 Jun 2023 18:01:55 +0200 Subject: [PATCH] Add IAST benchmark tests (#3193) * appsec-iast benchmark tests * writing fixes Co-authored-by: simon-id * small fixes --------- Co-authored-by: simon-id --- benchmark/sirun/appsec-iast/README.md | 9 +++ benchmark/sirun/appsec-iast/client.js | 30 +++++++++ benchmark/sirun/appsec-iast/common.js | 6 ++ benchmark/sirun/appsec-iast/meta.json | 66 +++++++++++++++++++ .../appsec-iast/server-with-vulnerability.js | 25 +++++++ .../server-without-vulnerability.js | 21 ++++++ benchmark/sirun/runall.sh | 2 +- packages/dd-trace/test/plugins/externals.json | 4 ++ 8 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 benchmark/sirun/appsec-iast/README.md create mode 100644 benchmark/sirun/appsec-iast/client.js create mode 100644 benchmark/sirun/appsec-iast/common.js create mode 100644 benchmark/sirun/appsec-iast/meta.json create mode 100644 benchmark/sirun/appsec-iast/server-with-vulnerability.js create mode 100644 benchmark/sirun/appsec-iast/server-without-vulnerability.js diff --git a/benchmark/sirun/appsec-iast/README.md b/benchmark/sirun/appsec-iast/README.md new file mode 100644 index 00000000000..79c5e0d21ab --- /dev/null +++ b/benchmark/sirun/appsec-iast/README.md @@ -0,0 +1,9 @@ +This creates 150 HTTP requests from client to server. + +The variants are: +- control tracer with non vulnerable endpoint without iast +- tracer with non vulnerable endpoint with iast active and default configuration +- tracer with non vulnerable endpoint with iast active and sampling 100 +- control tracer with vulnerable endpoint without iast +- tracer with vulnerable endpoint with iast active and default configuration +- tracer with vulnerable endpoint with iast active and sampling 100 diff --git a/benchmark/sirun/appsec-iast/client.js b/benchmark/sirun/appsec-iast/client.js new file mode 100644 index 00000000000..91686dfa2c4 --- /dev/null +++ b/benchmark/sirun/appsec-iast/client.js @@ -0,0 +1,30 @@ +'use strict' + +const { port, reqs } = require('./common') +const http = require('http') + +let connectionsMade = 0 +function request (opts) { + http.get(opts, (res) => { + res.on('data', () => {}) + res.on('end', () => { + if (++connectionsMade !== reqs) { + request(opts) + } + }) + }).on('error', (e) => { + setTimeout(() => { + request(opts) + }, 10) + }) +} + +const path = '/?param=value' +const opts = { + headers: { + accept: 'text/html' + }, + port, + path +} +request(opts) diff --git a/benchmark/sirun/appsec-iast/common.js b/benchmark/sirun/appsec-iast/common.js new file mode 100644 index 00000000000..1631e10bff7 --- /dev/null +++ b/benchmark/sirun/appsec-iast/common.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = { + port: 3331 + parseInt(process.env.CPU_AFFINITY || '0'), + reqs: 350 +} diff --git a/benchmark/sirun/appsec-iast/meta.json b/benchmark/sirun/appsec-iast/meta.json new file mode 100644 index 00000000000..ed0717a5e00 --- /dev/null +++ b/benchmark/sirun/appsec-iast/meta.json @@ -0,0 +1,66 @@ +{ + "name": "appsec-iast", + "cachegrind": false, + "instructions": true, + "iterations": 40, + "variants": { + "no-vulnerability-control": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-without-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-without-vulnerability.js\"", + "env": { + "DD_IAST_ENABLED": "0" + } + }, + "no-vulnerability-iast-enabled-default-config": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-without-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-without-vulnerability.js\"", + "baseline": "no-vulnerability-control", + "env": { + "DD_IAST_ENABLED": "1" + } + }, + "no-vulnerability-iast-enabled-always-active": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-without-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-without-vulnerability.js\"", + "baseline": "no-vulnerability-control", + "env": { + "DD_IAST_ENABLED": "1", + "DD_IAST_REQUEST_SAMPLING": "100", + "DD_IAST_MAX_CONCURRENT_REQUESTS": "1000", + "DD_IAST_MAX_CONTEXT_OPERATIONS": "100" + } + }, + "with-vulnerability-control": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-with-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-with-vulnerability.js\"", + "env": { + "DD_IAST_ENABLED": "0" + } + }, + "with-vulnerability-iast-enabled-default-config": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-with-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-with-vulnerability.js\"", + "baseline": "with-vulnerability-control", + "env": { + "DD_IAST_ENABLED": "1" + } + }, + "with-vulnerability-iast-enabled-always-active": { + "setup": "bash -c \"nohup node client.js >/dev/null 2>&1 &\"", + "run": "node --require ../../../init.js server-with-vulnerability.js", + "run_with_affinity": "bash -c \"taskset -c $CPU_AFFINITY node --require ../../../init.js server-with-vulnerability.js\"", + "baseline": "with-vulnerability-control", + "env": { + "DD_IAST_ENABLED": "1", + "DD_IAST_REQUEST_SAMPLING": "100", + "DD_IAST_MAX_CONCURRENT_REQUESTS": "1000", + "DD_IAST_MAX_CONTEXT_OPERATIONS": "100" + } + } + } +} diff --git a/benchmark/sirun/appsec-iast/server-with-vulnerability.js b/benchmark/sirun/appsec-iast/server-with-vulnerability.js new file mode 100644 index 00000000000..cdacb7d5d0c --- /dev/null +++ b/benchmark/sirun/appsec-iast/server-with-vulnerability.js @@ -0,0 +1,25 @@ +'use strict' + +const { port, reqs } = require('./common') +const express = require('../../../versions/express').get() +const cookieParser = require('../../../versions/cookie-parser').get() +const childProcess = require('child_process') + +const app = express() +app.use(cookieParser()) + +let connectionsMade = 0 + +function noop () {} + +app.get('/', (req, res) => { + childProcess.exec('echo #' + req.query.param, noop) + res.writeHead(200) + res.end('Hello, World!') + + if (++connectionsMade === reqs) { + server.close() + } +}) + +const server = app.listen(port) diff --git a/benchmark/sirun/appsec-iast/server-without-vulnerability.js b/benchmark/sirun/appsec-iast/server-without-vulnerability.js new file mode 100644 index 00000000000..18bd943d2ef --- /dev/null +++ b/benchmark/sirun/appsec-iast/server-without-vulnerability.js @@ -0,0 +1,21 @@ +'use strict' + +const { port, reqs } = require('./common') +const express = require('../../../versions/express').get() +const cookieParser = require('../../../versions/cookie-parser').get() + +const app = express() +app.use(cookieParser()) + +let connectionsMade = 0 + +app.get('/', (req, res) => { + res.writeHead(200) + res.end('Hello, World!') + + if (++connectionsMade === reqs) { + server.close() + } +}) + +const server = app.listen(port) diff --git a/benchmark/sirun/runall.sh b/benchmark/sirun/runall.sh index 10d1f35557a..9c2556461b7 100755 --- a/benchmark/sirun/runall.sh +++ b/benchmark/sirun/runall.sh @@ -19,7 +19,7 @@ nvm use 18 cd ../../ && npm install --global yarn \ && yarn install --ignore-engines \ - && PLUGINS="bluebird|q|graphql" yarn services + && PLUGINS="bluebird|q|graphql|express" yarn services ) # run each test in parallel for a given version of Node.js diff --git a/packages/dd-trace/test/plugins/externals.json b/packages/dd-trace/test/plugins/externals.json index 76df8b8c879..391fb5733f5 100644 --- a/packages/dd-trace/test/plugins/externals.json +++ b/packages/dd-trace/test/plugins/externals.json @@ -35,6 +35,10 @@ { "name": "loopback", "versions": [">=2.38.1"] + }, + { + "name": "cookie-parser", + "versions": [">=1.4.6"] } ], "fastify": [