diff --git a/end2end/getFreePort.js b/end2end/getFreePort.js
new file mode 100644
index 000000000..36fa5f1e8
--- /dev/null
+++ b/end2end/getFreePort.js
@@ -0,0 +1,14 @@
+const { randomInt } = require("crypto");
+const used = [];
+
+module.exports = function getFreePort(t) {
+ const port = randomInt(3000, 10000) + t.childId;
+
+ if (used.includes(port)) {
+ return getFreePort(t);
+ }
+
+ used.push(port);
+
+ return port;
+};
diff --git a/end2end/package-lock.json b/end2end/package-lock.json
index 540f68c8e..ea509ecc4 100644
--- a/end2end/package-lock.json
+++ b/end2end/package-lock.json
@@ -7,7 +7,8 @@
"name": "end2end",
"dependencies": {
"@supercharge/promise-pool": "^3.1.1",
- "tap": "^18.7.0"
+ "tap": "^18.7.0",
+ "wait-on": "^8.0.1"
}
},
"node_modules/@alcalzone/ansi-tokenize": {
@@ -43,6 +44,19 @@
"node": ">=12"
}
},
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -264,6 +278,24 @@
"node": ">=14"
}
},
+ "node_modules/@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
+ },
"node_modules/@sigstore/bundle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz",
@@ -941,6 +973,11 @@
"node": ">=16"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
"node_modules/auto-bind": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz",
@@ -952,6 +989,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/axios": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
+ "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1340,6 +1387,17 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1411,6 +1469,14 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/diff": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
@@ -1506,6 +1572,25 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/foreground-child": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
@@ -1521,6 +1606,19 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fromentries": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
@@ -1966,6 +2064,18 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/joi": {
+ "version": "17.13.3",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
+ "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
+ "dependencies": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2068,6 +2178,25 @@
"node": "^16.14.0 || >=18.0.0"
}
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -2090,6 +2219,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
@@ -2651,6 +2788,11 @@
"node": ">=10"
}
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
@@ -2815,6 +2957,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/rxjs": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -3491,6 +3641,24 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/wait-on": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.1.tgz",
+ "integrity": "sha512-1wWQOyR2LVVtaqrcIL2+OM+x7bkpmzVROa0Nf6FryXkS+er5Sa1kzFGjzZRqLnHa3n1rACFLeTwUqE1ETL9Mig==",
+ "dependencies": {
+ "axios": "^1.7.7",
+ "joi": "^17.13.3",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.8",
+ "rxjs": "^7.8.1"
+ },
+ "bin": {
+ "wait-on": "bin/wait-on"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/walk-up-path": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz",
diff --git a/end2end/package.json b/end2end/package.json
index 53387d8bc..bd2fa3614 100644
--- a/end2end/package.json
+++ b/end2end/package.json
@@ -3,9 +3,10 @@
"private": true,
"dependencies": {
"@supercharge/promise-pool": "^3.1.1",
- "tap": "^18.7.0"
+ "tap": "^18.7.0",
+ "wait-on": "^8.0.1"
},
"scripts": {
- "test": "AIKIDO_CI=true tap tests/*.js --allow-empty-coverage -j 1"
+ "test": "AIKIDO_CI=true tap tests/*.js --allow-empty-coverage"
}
}
diff --git a/end2end/server/app.js b/end2end/server/app.js
index fb1844f02..52796cd55 100644
--- a/end2end/server/app.js
+++ b/end2end/server/app.js
@@ -1,4 +1,4 @@
-// This is a insecure mock server for testing purposes
+// This is an insecure mock server for testing purposes
const express = require("express");
const config = require("./src/handlers/getConfig");
const captureEvent = require("./src/handlers/captureEvent");
diff --git a/end2end/tests/big-payloads.test.js b/end2end/tests/big-payloads.test.js
index 35fe63306..084523816 100644
--- a/end2end/tests/big-payloads.test.js
+++ b/end2end/tests/big-payloads.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const { PromisePool } = require("@supercharge/promise-pool");
const pathToApp = resolve(
@@ -11,7 +12,8 @@ const pathToApp = resolve(
);
t.test("it does not crash if many attacks with big payloads", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -20,7 +22,7 @@ t.test("it does not crash if many attacks with big payloads", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -36,7 +38,7 @@ t.test("it does not crash if many attacks with big payloads", (t) => {
const amount = 2000;
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return PromisePool.withConcurrency(3)
.for(Array.from({ length: amount }))
@@ -49,7 +51,7 @@ t.test("it does not crash if many attacks with big payloads", (t) => {
})),
};
- return await fetch(`http://localhost:4000/search`, {
+ return await fetch(`http://localhost:${port}/search`, {
method: "POST",
signal: AbortSignal.timeout(5000),
body: JSON.stringify(filter),
@@ -64,7 +66,7 @@ t.test("it does not crash if many attacks with big payloads", (t) => {
);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-graphql.test.js b/end2end/tests/express-graphql.test.js
index c3ae92f86..7ef10dea5 100644
--- a/end2end/tests/express-graphql.test.js
+++ b/end2end/tests/express-graphql.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,10 +35,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch(`http://localhost:4000/graphql`, {
+ fetch(`http://127.0.0.1:${port}/graphql`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -44,7 +46,7 @@ t.test("it blocks in blocking mode", (t) => {
}),
signal: AbortSignal.timeout(5000),
}),
- fetch(`http://localhost:4000/graphql`, {
+ fetch(`http://127.0.0.1:${port}/graphql`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -64,7 +66,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stdout, /Starting agent/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -72,7 +74,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -91,10 +94,10 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch(`http://localhost:4000/graphql`, {
+ fetch(`http://127.0.0.1:${port}/graphql`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -102,7 +105,7 @@ t.test("it does not block in dry mode", (t) => {
}),
signal: AbortSignal.timeout(5000),
}),
- fetch(`http://localhost:4000/graphql`, {
+ fetch(`http://127.0.0.1:${port}/graphql`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -123,7 +126,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mariadb.test.js b/end2end/tests/express-mariadb.test.js
index 02eec40c6..7e61abde9 100644
--- a/end2end/tests/express-mariadb.test.js
+++ b/end2end/tests/express-mariadb.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,16 +35,16 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://localhost:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4000/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -54,7 +56,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -62,7 +64,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -81,16 +84,16 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://localhost:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4001/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -102,7 +105,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mongodb.shell-injection.test.js b/end2end/tests/express-mongodb.shell-injection.test.js
index 7209b3d34..4a7f99698 100644
--- a/end2end/tests/express-mongodb.shell-injection.test.js
+++ b/end2end/tests/express-mongodb.shell-injection.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCK: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,10 +35,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://localhost:4000/ls", {
+ fetch(`http://localhost:${port}/ls`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -46,7 +48,7 @@ t.test("it blocks in blocking mode", (t) => {
directory: "'; ls ~",
}),
}),
- fetch("http://localhost:4000/ls", {
+ fetch(`http://localhost:${port}/ls`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -65,7 +67,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a shell injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -73,7 +75,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -92,10 +95,10 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://localhost:4001/ls", {
+ fetch(`http://localhost:${port}/ls`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -105,7 +108,7 @@ t.test("it does not block in dry mode", (t) => {
directory: "'; ls ~; echo '",
}),
}),
- fetch("http://localhost:4001/ls", {
+ fetch(`http://localhost:${port}/ls`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -124,7 +127,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a shell injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mongodb.ssrf.test.js b/end2end/tests/express-mongodb.ssrf.test.js
index 2255875b6..d7a690249 100644
--- a/end2end/tests/express-mongodb.ssrf.test.js
+++ b/end2end/tests/express-mongodb.ssrf.test.js
@@ -3,7 +3,8 @@ const { spawn } = require("child_process");
const { readFile } = require("fs/promises");
const { createServer } = require("http");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -13,7 +14,8 @@ const pathToApp = resolve(
const testServerUrl = "http://localhost:5874";
const safeImage = "https://nodejs.org/static/images/favicons/favicon.png";
-const unsafeImage = "http://local.aikido.io:5875/favicon.png";
+const port = getFreePort(t);
+const unsafeImage = `http://local.aikido.io:${port}/favicon.png`;
t.setTimeout(60000);
@@ -33,7 +35,7 @@ t.before(async () => {
}
});
- server.listen(5875, () => {
+ server.listen(port, () => {
resolve();
});
@@ -51,7 +53,8 @@ t.beforeEach(async () => {
});
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
@@ -66,7 +69,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -80,14 +83,17 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch(`http://127.0.0.1:4000/images/${encodeURIComponent(safeImage)}`, {
- signal: AbortSignal.timeout(5000),
- }),
fetch(
- `http://127.0.0.1:4000/images/${encodeURIComponent(unsafeImage)}`,
+ `http://127.0.0.1:${port}/images/${encodeURIComponent(safeImage)}`,
+ {
+ signal: AbortSignal.timeout(5000),
+ }
+ ),
+ fetch(
+ `http://127.0.0.1:${port}/images/${encodeURIComponent(unsafeImage)}`,
{
signal: AbortSignal.timeout(5000),
}
@@ -121,7 +127,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(attack.attack.stack, /express-async-handler/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -129,7 +135,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
@@ -153,14 +160,17 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch(`http://127.0.0.1:4001/images/${encodeURIComponent(safeImage)}`, {
- signal: AbortSignal.timeout(5000),
- }),
fetch(
- `http://127.0.0.1:4001/images/${encodeURIComponent(unsafeImage)}`,
+ `http://127.0.0.1:${port}/images/${encodeURIComponent(safeImage)}`,
+ {
+ signal: AbortSignal.timeout(5000),
+ }
+ ),
+ fetch(
+ `http://127.0.0.1:${port}/images/${encodeURIComponent(unsafeImage)}`,
{
signal: AbortSignal.timeout(5000),
}
@@ -174,7 +184,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a server-side request forgery/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mongodb.test.js b/end2end/tests/express-mongodb.test.js
index 9a508b769..0607e33e6 100644
--- a/end2end/tests/express-mongodb.test.js
+++ b/end2end/tests/express-mongodb.test.js
@@ -1,7 +1,9 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
+const { setTimeout } = require("timers/promises");
const pathToApp = resolve(
__dirname,
@@ -12,7 +14,8 @@ const pathToApp = resolve(
t.setTimeout(60000);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -21,7 +24,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -35,13 +38,13 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4000/?search[$ne]=null", {
+ fetch(`http://127.0.0.1:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4000/?search=title", {
+ fetch(`http://127.0.0.1:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -53,7 +56,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -61,7 +64,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -80,13 +84,13 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://127.0.0.1:4001/?search[$ne]=null", {
+ fetch(`http://127.0.0.1:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4001/?search=title", {
+ fetch(`http://127.0.0.1:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -98,7 +102,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -106,6 +110,7 @@ t.test("it does not block in dry mode", (t) => {
});
t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
+ const port = getFreePort(t);
const server = spawn(
`node`,
[
@@ -113,7 +118,7 @@ t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
"--require",
"@opentelemetry/auto-instrumentations-node/register",
pathToApp,
- "4002",
+ port,
],
{
cwd: resolve(__dirname, "../../sample-apps/express-mongodb"),
@@ -134,7 +139,7 @@ t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -148,15 +153,16 @@ t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
});
// Wait for the server to start
- timeout(6000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4002/?search[$ne]=null", {
+ fetch(`http://127.0.0.1:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/?search=title", {
+ fetch(`http://127.0.0.1:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
+ setTimeout(4000),
]);
})
.then(([noSQLInjection, normalSearch]) => {
@@ -167,7 +173,7 @@ t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
t.match(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill("SIGINT");
@@ -175,6 +181,7 @@ t.test("it blocks in blocking mode (with open telemetry enabled)", (t) => {
});
t.test("it does not block in dry mode (with open telemetry enabled)", (t) => {
+ const port = getFreePort(t);
const server = spawn(
`node`,
[
@@ -182,7 +189,7 @@ t.test("it does not block in dry mode (with open telemetry enabled)", (t) => {
"--require",
"@opentelemetry/auto-instrumentations-node/register",
pathToApp,
- "4003",
+ port,
],
{
cwd: resolve(__dirname, "../../sample-apps/express-mongodb"),
@@ -212,15 +219,16 @@ t.test("it does not block in dry mode (with open telemetry enabled)", (t) => {
});
// Wait for the server to start
- timeout(6000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://127.0.0.1:4003/?search[$ne]=null", {
+ fetch(`http://127.0.0.1:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/?search=title", {
+ fetch(`http://127.0.0.1:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
+ setTimeout(4000),
])
)
.then(([noSQLInjection, normalSearch]) => {
@@ -231,7 +239,7 @@ t.test("it does not block in dry mode (with open telemetry enabled)", (t) => {
t.notMatch(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill("SIGINT");
diff --git a/end2end/tests/express-mongoose.test.js b/end2end/tests/express-mongoose.test.js
index 3abe88025..bc974159a 100644
--- a/end2end/tests/express-mongoose.test.js
+++ b/end2end/tests/express-mongoose.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,13 +35,13 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://localhost:4000/?search[$ne]=null", {
+ fetch(`http://localhost:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://localhost:4000/?search=title", {
+ fetch(`http://localhost:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -51,7 +53,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -59,7 +61,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -78,13 +81,13 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://localhost:4001/?search[$ne]=null", {
+ fetch(`http://localhost:${port}/?search[$ne]=null`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://localhost:4001/?search=title", {
+ fetch(`http://localhost:${port}/?search=title`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -96,7 +99,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mysql.test.js b/end2end/tests/express-mysql.test.js
index 863c9a31d..a072fbca1 100644
--- a/end2end/tests/express-mysql.test.js
+++ b/end2end/tests/express-mysql.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,16 +35,16 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://localhost:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4000/cats", {
+ fetch(`http://localhost:${port}/cats`, {
signal: AbortSignal.timeout(5000),
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
@@ -50,10 +52,10 @@ t.test("it blocks in blocking mode", (t) => {
"Content-Type": "application/xml",
},
}),
- fetch("http://localhost:4000/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://localhost:4000/cats", {
+ fetch(`http://localhost:${port}/cats`, {
signal: AbortSignal.timeout(5000),
method: "POST",
body: "Njuska",
@@ -72,7 +74,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -80,7 +82,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -99,16 +102,16 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://localhost:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4001/cats", {
+ fetch(`http://localhost:${port}/cats`, {
signal: AbortSignal.timeout(5000),
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
@@ -116,10 +119,10 @@ t.test("it does not block in dry mode", (t) => {
"Content-Type": "application/xml",
},
}),
- fetch("http://localhost:4001/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://localhost:4001/cats", {
+ fetch(`http://localhost:${port}/cats`, {
signal: AbortSignal.timeout(5000),
method: "POST",
body: "Njuska",
@@ -138,7 +141,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-mysql2.test.js b/end2end/tests/express-mysql2.test.js
index c9b35588a..2a569dae4 100644
--- a/end2end/tests/express-mysql2.test.js
+++ b/end2end/tests/express-mysql2.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,22 +35,22 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://localhost:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
fetch(
- `http://localhost:4000/cats/${encodeURIComponent("Njuska'; DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/cats/${encodeURIComponent("Njuska'; DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4000/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -61,7 +63,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -69,7 +71,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -88,22 +91,22 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://localhost:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
fetch(
- `http://localhost:4001/cats/${encodeURIComponent("Njuska'; DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/cats/${encodeURIComponent("Njuska'; DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4001/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -116,7 +119,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-path-traversal.test.js b/end2end/tests/express-path-traversal.test.js
index 1654fecca..f7d389766 100644
--- a/end2end/tests/express-path-traversal.test.js
+++ b/end2end/tests/express-path-traversal.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,17 +35,17 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- "http://localhost:4000/?content=blablabla&filename=/../TestDoc.txt",
+ `http://localhost:${port}/?content=blablabla&filename=/../TestDoc.txt`,
{
signal: AbortSignal.timeout(5000),
}
),
fetch(
- "http://localhost:4000/?content=blablabla&filename=/TestDoc.txt",
+ `http://localhost:${port}/?content=blablabla&filename=/TestDoc.txt`,
{
signal: AbortSignal.timeout(5000),
}
@@ -57,7 +59,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a path traversal attack/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -65,7 +67,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -84,17 +87,17 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- "http://localhost:4001/?content=blablabla&filename=/../TestDoc.txt",
+ `http://localhost:${port}/?content=blablabla&filename=/../TestDoc.txt`,
{
signal: AbortSignal.timeout(5000),
}
),
fetch(
- "http://localhost:4001/?content=blablabla&filename=/TestDoc.txt",
+ `http://localhost:${port}/?content=blablabla&filename=/TestDoc.txt`,
{
signal: AbortSignal.timeout(5000),
}
@@ -108,7 +111,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a path traversal attack/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/express-postgres.test.js b/end2end/tests/express-postgres.test.js
index b445e05ca..b145990b2 100644
--- a/end2end/tests/express-postgres.test.js
+++ b/end2end/tests/express-postgres.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,28 +35,28 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://localhost:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats_2;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats_2;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch(`http://localhost:4000/string-concat`, {
+ fetch(`http://localhost:${port}/string-concat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ petname: ["'", "1)", "(0,1)", "(1", "'"] }),
signal: AbortSignal.timeout(5000),
}),
fetch(
- `http://localhost:4000/string-concat?petname='&petname=1)&petname=(0,1)&petname=(1&petname='`,
+ `http://localhost:${port}/string-concat?petname='&petname=1)&petname=(0,1)&petname=(1&petname='`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4000/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -70,7 +72,7 @@ t.test("it blocks in blocking mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -78,7 +80,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -97,28 +100,28 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://localhost:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats_2;-- H")}`,
+ `http://localhost:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats_2;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch(`http://localhost:4001/string-concat`, {
+ fetch(`http://localhost:${port}/string-concat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ petname: ["'", "1)", "(0,1)", "(1", "'"] }),
signal: AbortSignal.timeout(5000),
}),
fetch(
- `http://localhost:4001/string-concat?petname='&petname=1)&petname=(0,1)&petname=(1&petname='`,
+ `http://localhost:${port}/string-concat?petname='&petname=1)&petname=(0,1)&petname=(1&petname='`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://localhost:4001/?petname=Njuska", {
+ fetch(`http://localhost:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -134,7 +137,7 @@ t.test("it does not block in dry mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/fastify-mysql2.test.js b/end2end/tests/fastify-mysql2.test.js
index acbeaed9e..faa114013 100644
--- a/end2end/tests/fastify-mysql2.test.js
+++ b/end2end/tests/fastify-mysql2.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,19 +35,19 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(4000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://127.0.0.1:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://127.0.0.1:4000/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4000/context", {
+ fetch(`http://127.0.0.1:${port}/context`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -57,7 +59,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stdout, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -65,7 +67,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, [pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, [pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -84,16 +87,16 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(4000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://127.0.0.1:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://127.0.0.1:4001/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -105,7 +108,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stdout, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/hapi-postgres.test.js b/end2end/tests/hapi-postgres.test.js
index 2b30757e9..b01fe96d6 100644
--- a/end2end/tests/hapi-postgres.test.js
+++ b/end2end/tests/hapi-postgres.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,16 +35,16 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
fetch(
- `http://127.0.0.1:4000/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://127.0.0.1:4000/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
]);
@@ -54,7 +56,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(await noSQLInjection.text(), /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -62,7 +64,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -81,16 +84,16 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
fetch(
- `http://127.0.0.1:4001/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
+ `http://127.0.0.1:${port}/?petname=${encodeURIComponent("Njuska'); DELETE FROM cats;-- H")}`,
{
signal: AbortSignal.timeout(5000),
}
),
- fetch("http://127.0.0.1:4001/?petname=Njuska", {
+ fetch(`http://127.0.0.1:${port}/?petname=Njuska`, {
signal: AbortSignal.timeout(5000),
}),
])
@@ -105,7 +108,7 @@ t.test("it does not block in dry mode", (t) => {
);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/hono-mongodb.test.js b/end2end/tests/hono-mongodb.test.js
index 5b813ea6d..598a621a2 100644
--- a/end2end/tests/hono-mongodb.test.js
+++ b/end2end/tests/hono-mongodb.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -12,7 +13,8 @@ const pathToApp = resolve(
t.setTimeout(60000);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4000"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -21,7 +23,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -35,16 +37,16 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then((a) => {
return Promise.all([
- fetch("http://127.0.0.1:4000/search", {
+ fetch(`http://127.0.0.1:${port}/search`, {
method: "POST",
signal: AbortSignal.timeout(5000),
body: JSON.stringify({ title: { $ne: null } }),
headers: { "Content-Type": "application/json" },
}),
- fetch("http://127.0.0.1:4000/search", {
+ fetch(`http://127.0.0.1:${port}/search`, {
method: "POST",
signal: AbortSignal.timeout(5000),
body: JSON.stringify({ title: "title" }),
@@ -59,7 +61,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -67,7 +69,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4001"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -86,16 +89,16 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then((a) => {
return Promise.all([
- fetch("http://127.0.0.1:4001/search", {
+ fetch(`http://127.0.0.1:${port}/search`, {
method: "POST",
signal: AbortSignal.timeout(5000),
body: JSON.stringify({ title: { $ne: null } }),
headers: { "Content-Type": "application/json" },
}),
- fetch("http://127.0.0.1:4001/search", {
+ fetch(`http://127.0.0.1:${port}/search`, {
method: "POST",
signal: AbortSignal.timeout(5000),
body: JSON.stringify({ title: "title" }),
@@ -110,7 +113,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked a NoSQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/hono-sqlite3.test.js b/end2end/tests/hono-sqlite3.test.js
index a428124fd..c75324cec 100644
--- a/end2end/tests/hono-sqlite3.test.js
+++ b/end2end/tests/hono-sqlite3.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(
__dirname,
@@ -10,7 +11,8 @@ const pathToApp = resolve(
);
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4002"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -19,7 +21,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -33,10 +35,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Test'), ('Test2');--" }),
headers: {
@@ -44,7 +46,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Miau" }),
headers: {
@@ -61,7 +63,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -69,7 +71,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4003"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -88,10 +91,10 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Test'), ('Test2');--" }),
headers: {
@@ -99,7 +102,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Miau" }),
headers: {
@@ -116,7 +119,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/hono-xml-rate-limiting.test.js b/end2end/tests/hono-xml-rate-limiting.test.js
index f9f75a1a1..5ea330455 100644
--- a/end2end/tests/hono-xml-rate-limiting.test.js
+++ b/end2end/tests/hono-xml-rate-limiting.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/hono-xml", "app.js");
const testServerUrl = "http://localhost:5874";
@@ -43,7 +44,8 @@ t.beforeEach(async () => {
});
t.test("it rate limits requests", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4002"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
@@ -58,7 +60,7 @@ t.test("it rate limits requests", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -72,9 +74,9 @@ t.test("it rate limits requests", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(async () => {
- const resp1 = await fetch("http://127.0.0.1:4002/add", {
+ const resp1 = await fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Njuska",
headers: {
@@ -84,7 +86,7 @@ t.test("it rate limits requests", (t) => {
});
t.same(resp1.status, 200);
- const resp2 = await fetch("http://127.0.0.1:4002/add", {
+ const resp2 = await fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Harry",
headers: {
@@ -95,7 +97,7 @@ t.test("it rate limits requests", (t) => {
t.same(resp2.status, 429);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -103,7 +105,8 @@ t.test("it rate limits requests", (t) => {
});
t.test("user rate limiting works", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4003"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
@@ -118,7 +121,7 @@ t.test("user rate limiting works", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -132,9 +135,9 @@ t.test("user rate limiting works", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(async () => {
- const resp1 = await fetch("http://127.0.0.1:4003/add", {
+ const resp1 = await fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Njuska",
headers: {
@@ -145,7 +148,7 @@ t.test("user rate limiting works", (t) => {
});
t.same(resp1.status, 200);
- const resp2 = await fetch("http://127.0.0.1:4003/add", {
+ const resp2 = await fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Harry",
headers: {
@@ -156,7 +159,7 @@ t.test("user rate limiting works", (t) => {
});
t.same(resp2.status, 200);
- const resp3 = await fetch("http://127.0.0.1:4003/add", {
+ const resp3 = await fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Njuska",
headers: {
@@ -168,7 +171,7 @@ t.test("user rate limiting works", (t) => {
t.same(resp3.status, 429);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/hono-xml.test.js b/end2end/tests/hono-xml.test.js
index 20334bf20..a9020016a 100644
--- a/end2end/tests/hono-xml.test.js
+++ b/end2end/tests/hono-xml.test.js
@@ -1,12 +1,14 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/hono-xml", "app.js");
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4002"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -15,7 +17,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -29,10 +31,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
headers: {
@@ -40,7 +42,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add-attribute", {
+ fetch(`http://127.0.0.1:${port}/add-attribute`, {
method: "POST",
body: ``,
headers: {
@@ -48,7 +50,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add-fast", {
+ fetch(`http://127.0.0.1:${port}/add-fast`, {
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
headers: {
@@ -56,7 +58,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add-fast-attribute", {
+ fetch(`http://127.0.0.1:${port}/add-fast-attribute`, {
method: "POST",
body: ``,
headers: {
@@ -64,7 +66,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Miau",
headers: {
@@ -92,7 +94,7 @@ t.test("it blocks in blocking mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -100,7 +102,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4003"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -119,10 +122,10 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
headers: {
@@ -130,7 +133,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add-attribute", {
+ fetch(`http://127.0.0.1:${port}/add-attribute`, {
method: "POST",
body: ``,
headers: {
@@ -138,7 +141,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add-fast", {
+ fetch(`http://127.0.0.1:${port}/add-fast`, {
method: "POST",
body: "Njuska'); DELETE FROM cats;-- H",
headers: {
@@ -146,7 +149,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add-fast-attribute", {
+ fetch(`http://127.0.0.1:${port}/add-fast-attribute`, {
method: "POST",
body: ``,
headers: {
@@ -154,7 +157,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: "Miau",
headers: {
@@ -182,7 +185,7 @@ t.test("it does not block in dry mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/http2.test.js b/end2end/tests/http2.test.js
index bec6291f3..784856143 100644
--- a/end2end/tests/http2.test.js
+++ b/end2end/tests/http2.test.js
@@ -1,15 +1,17 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const getFreePort = require("../getFreePort");
const { connect } = require("http2");
+const { setTimeout } = require("timers/promises");
const pathToApp = resolve(__dirname, "../../sample-apps/http2", "index.js");
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4002"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -18,7 +20,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -32,13 +34,13 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ setTimeout(2000)
.then(() => {
return Promise.all([
fetch(
- "https://127.0.0.1:4002?url=https://www.cloudflare.com/favicon.ico"
+ `https://127.0.0.1:${port}?url=https://www.cloudflare.com/favicon.ico`
),
- fetch("https://127.0.0.1:4002?url=http://localhost"),
+ fetch(`https://127.0.0.1:${port}?url=http://localhost`),
]);
})
.then(([nonSSRF, ssrf]) => {
@@ -48,7 +50,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked a server-side request forgery/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -56,7 +58,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4003"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -75,13 +78,13 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ setTimeout(2000)
.then(() =>
Promise.all([
fetch(
- "https://127.0.0.1:4003?url=https://www.cloudflare.com/favicon.ico"
+ `https://127.0.0.1:${port}?url=https://www.cloudflare.com/favicon.ico`
),
- fetch("https://127.0.0.1:4003?url=http://localhost"),
+ fetch(`https://127.0.0.1:${port}?url=http://localhost`),
])
)
.then(([nonSSRF, ssrf]) => {
@@ -92,7 +95,7 @@ t.test("it does not block in dry mode", (t) => {
t.match(stderr, /fetch failed/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/koa-sqlite3.test.js b/end2end/tests/koa-sqlite3.test.js
index df9ba5b53..0aee5fe65 100644
--- a/end2end/tests/koa-sqlite3.test.js
+++ b/end2end/tests/koa-sqlite3.test.js
@@ -1,12 +1,14 @@
const t = require("tap");
const { spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/koa-sqlite3", "app.js");
t.test("it blocks in blocking mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4002"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" },
});
@@ -15,7 +17,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -29,10 +31,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Test'), ('Test2');--" }),
headers: {
@@ -40,7 +42,7 @@ t.test("it blocks in blocking mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4002/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Miau" }),
headers: {
@@ -57,7 +59,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -65,7 +67,8 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
- const server = spawn(`node`, ["--preserve-symlinks", pathToApp, "4003"], {
+ const port = getFreePort(t);
+ const server = spawn(`node`, ["--preserve-symlinks", pathToApp, port], {
env: { ...process.env, AIKIDO_DEBUG: "true" },
});
@@ -84,10 +87,10 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(() =>
Promise.all([
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Test'), ('Test2');--" }),
headers: {
@@ -95,7 +98,7 @@ t.test("it does not block in dry mode", (t) => {
},
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4003/add", {
+ fetch(`http://127.0.0.1:${port}/add`, {
method: "POST",
body: JSON.stringify({ name: "Miau" }),
headers: {
@@ -112,7 +115,7 @@ t.test("it does not block in dry mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/nestjs-fastify-reate-limiting.test.js b/end2end/tests/nestjs-fastify-rate-limiting.test.js
similarity index 86%
rename from end2end/tests/nestjs-fastify-reate-limiting.test.js
rename to end2end/tests/nestjs-fastify-rate-limiting.test.js
index 6f8c649b0..f1c1e86f4 100644
--- a/end2end/tests/nestjs-fastify-reate-limiting.test.js
+++ b/end2end/tests/nestjs-fastify-rate-limiting.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawn, spawnSync } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/nestjs-fastify");
const testServerUrl = "http://localhost:5874";
@@ -53,6 +54,7 @@ t.beforeEach(async () => {
});
t.test("it rate limits requests", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
cwd: pathToApp,
env: {
@@ -61,7 +63,7 @@ t.test("it rate limits requests", (t) => {
AIKIDO_BLOCKING: "true",
AIKIDO_TOKEN: token,
AIKIDO_URL: testServerUrl,
- PORT: "4002",
+ PORT: port,
},
});
@@ -70,7 +72,7 @@ t.test("it rate limits requests", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -84,9 +86,9 @@ t.test("it rate limits requests", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(async () => {
- const resp1 = await fetch("http://127.0.0.1:4002/cats", {
+ const resp1 = await fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Njuska" }),
headers: {
@@ -96,7 +98,7 @@ t.test("it rate limits requests", (t) => {
});
t.same(resp1.status, 201);
- const resp2 = await fetch("http://127.0.0.1:4002/cats", {
+ const resp2 = await fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Harry" }),
headers: {
@@ -107,7 +109,7 @@ t.test("it rate limits requests", (t) => {
t.same(resp2.status, 429);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -115,6 +117,7 @@ t.test("it rate limits requests", (t) => {
});
t.test("user rate limiting works", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
cwd: pathToApp,
env: {
@@ -123,7 +126,7 @@ t.test("user rate limiting works", (t) => {
AIKIDO_BLOCKING: "true",
AIKIDO_TOKEN: token,
AIKIDO_URL: testServerUrl,
- PORT: "4003",
+ PORT: port,
},
});
@@ -132,7 +135,7 @@ t.test("user rate limiting works", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -146,9 +149,9 @@ t.test("user rate limiting works", (t) => {
});
// Wait for the server to start
- timeout(2000)
+ waitOn(port)
.then(async () => {
- const resp1 = await fetch("http://127.0.0.1:4003/cats", {
+ const resp1 = await fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Njuska" }),
headers: {
@@ -159,7 +162,7 @@ t.test("user rate limiting works", (t) => {
});
t.same(resp1.status, 201);
- const resp2 = await fetch("http://127.0.0.1:4003/cats", {
+ const resp2 = await fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Harry" }),
headers: {
@@ -170,7 +173,7 @@ t.test("user rate limiting works", (t) => {
});
t.same(resp2.status, 201);
- const resp3 = await fetch("http://127.0.0.1:4003/cats", {
+ const resp3 = await fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Harry" }),
headers: {
@@ -182,7 +185,7 @@ t.test("user rate limiting works", (t) => {
t.same(resp3.status, 429);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/nestjs-fastify.test.js b/end2end/tests/nestjs-fastify.test.js
index 1fba4eb0b..33a96a56d 100644
--- a/end2end/tests/nestjs-fastify.test.js
+++ b/end2end/tests/nestjs-fastify.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawnSync, spawn } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/nestjs-fastify");
@@ -16,12 +17,13 @@ t.before(() => {
});
t.test("it blocks in blocking mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "true",
- PORT: "4000",
+ PORT: port,
},
cwd: pathToApp,
});
@@ -31,7 +33,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -45,10 +47,10 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4000/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -68,7 +70,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -76,12 +78,13 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in non-blocking mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "false",
- PORT: "4001",
+ PORT: port,
},
cwd: pathToApp,
});
@@ -91,7 +94,7 @@ t.test("it does not block in non-blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -105,10 +108,10 @@ t.test("it does not block in non-blocking mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4001/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -125,7 +128,7 @@ t.test("it does not block in non-blocking mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/nestjs-sentry.test.js b/end2end/tests/nestjs-sentry.test.js
index 1db24e1b2..705a21ece 100644
--- a/end2end/tests/nestjs-sentry.test.js
+++ b/end2end/tests/nestjs-sentry.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawnSync, spawn, execSync } = require("child_process");
const { resolve } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/nestjs-sentry");
@@ -16,12 +17,13 @@ t.before(() => {
});
t.test("it blocks in blocking mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "true",
- PORT: "4000",
+ PORT: port,
},
cwd: pathToApp,
});
@@ -31,7 +33,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -45,14 +47,14 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4000/releases", {
+ fetch(`http://127.0.0.1:${port}/releases`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4000/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -72,7 +74,7 @@ t.test("it blocks in blocking mode", (t) => {
t.match(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -80,12 +82,13 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in non-blocking mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node`, ["--preserve-symlinks", "dist/main"], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "false",
- PORT: "4001",
+ PORT: port,
},
cwd: pathToApp,
});
@@ -95,7 +98,7 @@ t.test("it does not block in non-blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -109,14 +112,14 @@ t.test("it does not block in non-blocking mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4001/releases", {
+ fetch(`http://127.0.0.1:${port}/releases`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4001/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -136,7 +139,7 @@ t.test("it does not block in non-blocking mode", (t) => {
t.notMatch(stderr, /Zen has blocked an SQL injection/);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/nextjs-standalone.test.js b/end2end/tests/nextjs-standalone.test.js
index edbcfdfba..4d102cd1f 100644
--- a/end2end/tests/nextjs-standalone.test.js
+++ b/end2end/tests/nextjs-standalone.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawnSync, spawn, execSync } = require("child_process");
const { resolve, join } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const { cpSync, writeFileSync } = require("fs");
const pathToApp = resolve(__dirname, "../../sample-apps/nextjs-standalone");
@@ -37,6 +38,7 @@ t.before(() => {
});
t.test("it blocks in blocking mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(
`node`,
["--preserve-symlinks", "-r", "@aikidosec/firewall", "server.js"],
@@ -45,7 +47,7 @@ t.test("it blocks in blocking mode", (t) => {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "true",
- PORT: 4000,
+ PORT: port,
},
cwd: join(pathToApp, ".next/standalone"),
}
@@ -56,7 +58,7 @@ t.test("it blocks in blocking mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -70,14 +72,14 @@ t.test("it blocks in blocking mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
- .then((a) => {
+ waitOn(port)
+ .then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4000/files?path=.%27;env%27", {
+ fetch(`http://127.0.0.1:${port}/files?path=.%27;env%27`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4000/files", {
+ fetch(`http://127.0.0.1:${port}/files`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -85,11 +87,11 @@ t.test("it blocks in blocking mode", (t) => {
},
body: JSON.stringify({ path: `.';env'` }),
}),
- fetch("http://127.0.0.1:4000/files", {
+ fetch(`http://127.0.0.1:${port}/files`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4000/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Kitty'); DELETE FROM cats;-- H" }),
headers: {
@@ -111,7 +113,7 @@ t.test("it blocks in blocking mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
@@ -119,6 +121,7 @@ t.test("it blocks in blocking mode", (t) => {
});
t.test("it does not block in dry mode", (t) => {
+ const port = getFreePort(t);
const server = spawn(
`node`,
["--preserve-symlinks", "-r", "@aikidosec/firewall", "server.js"],
@@ -126,7 +129,7 @@ t.test("it does not block in dry mode", (t) => {
env: {
...process.env,
AIKIDO_DEBUG: "true",
- PORT: 4001,
+ PORT: port,
},
cwd: join(pathToApp, ".next/standalone"),
}
@@ -137,7 +140,7 @@ t.test("it does not block in dry mode", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -151,14 +154,14 @@ t.test("it does not block in dry mode", (t) => {
});
// Wait for the server to start
- timeout(5000)
- .then((a) => {
+ waitOn(port)
+ .then(() => {
return Promise.all([
- fetch("http://127.0.0.1:4001/files?path=.%27;env%27", {
+ fetch(`http://127.0.0.1:${port}/files?path=.%27;env%27`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4001/files", {
+ fetch(`http://127.0.0.1:${port}/files`, {
method: "POST",
signal: AbortSignal.timeout(5000),
headers: {
@@ -166,11 +169,11 @@ t.test("it does not block in dry mode", (t) => {
},
body: JSON.stringify({ path: `.';env'` }),
}),
- fetch("http://127.0.0.1:4001/files", {
+ fetch(`http://127.0.0.1:${port}/files`, {
method: "GET",
signal: AbortSignal.timeout(5000),
}),
- fetch("http://127.0.0.1:4001/cats", {
+ fetch(`http://127.0.0.1:${port}/cats`, {
method: "POST",
body: JSON.stringify({ name: "Kitty'); DELETE FROM cats;-- H" }),
headers: {
@@ -192,7 +195,7 @@ t.test("it does not block in dry mode", (t) => {
}
)
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/tests/strapi.test.js b/end2end/tests/strapi.test.js
index fcac2c896..108f9c854 100644
--- a/end2end/tests/strapi.test.js
+++ b/end2end/tests/strapi.test.js
@@ -1,7 +1,8 @@
const t = require("tap");
const { spawnSync, spawn, execSync } = require("child_process");
const { resolve, join } = require("path");
-const timeout = require("../timeout");
+const waitOn = require("../waitOn");
+const getFreePort = require("../getFreePort");
const pathToApp = resolve(__dirname, "../../sample-apps/strapi");
@@ -21,12 +22,14 @@ t.before(() => {
// We initially wrapped the Router class by hooking into the constructor
// This results in weird behaviour where the router returns 405 for all requests
t.test("it does not return 405 for register admin", (t) => {
+ const port = getFreePort(t);
const server = spawn(`node_modules/.bin/strapi`, ["start"], {
env: {
...process.env,
AIKIDO_DEBUG: "true",
AIKIDO_BLOCK: "true",
NODE_OPTIONS: "-r @aikidosec/firewall",
+ PORT: port,
},
cwd: pathToApp,
});
@@ -36,7 +39,7 @@ t.test("it does not return 405 for register admin", (t) => {
});
server.on("error", (err) => {
- t.fail(err.message);
+ t.fail(err);
});
let stdout = "";
@@ -50,10 +53,10 @@ t.test("it does not return 405 for register admin", (t) => {
});
// Wait for the server to start
- timeout(5000)
+ waitOn(port)
.then(() => {
return Promise.all([
- fetch("http://127.0.0.1:1337/admin/register-admin", {
+ fetch(`http://127.0.0.1:${port}/admin/register-admin`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -67,7 +70,7 @@ t.test("it does not return 405 for register admin", (t) => {
t.equal(registerAdmin.status, 400);
})
.catch((error) => {
- t.fail(error.message);
+ t.fail(error);
})
.finally(() => {
server.kill();
diff --git a/end2end/timeout.js b/end2end/timeout.js
deleted file mode 100644
index 14719f34a..000000000
--- a/end2end/timeout.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = async function timeout(ms) {
- return new Promise((resolve) => setTimeout(resolve, ms));
-};
diff --git a/end2end/waitOn.js b/end2end/waitOn.js
new file mode 100644
index 000000000..b551cb27a
--- /dev/null
+++ b/end2end/waitOn.js
@@ -0,0 +1,8 @@
+const waitOn = require("wait-on");
+
+module.exports = function (port) {
+ return waitOn({
+ resources: ["tcp:localhost:" + port],
+ log: true,
+ });
+};
diff --git a/sample-apps/express-graphql/app.js b/sample-apps/express-graphql/app.js
index c128155c0..1b4ce1062 100644
--- a/sample-apps/express-graphql/app.js
+++ b/sample-apps/express-graphql/app.js
@@ -106,7 +106,7 @@ function getRootPage() {