Skip to content

Commit

Permalink
Merge branch 'main' of github.com:AikidoSec/firewall-node into patch-…
Browse files Browse the repository at this point in the history
…ghost

* 'main' of github.com:AikidoSec/firewall-node: (53 commits)
  Fix path unit tests
  Fix not protecting path functions of different os
  Cleanup
  Extract type
  Update library/helpers/shouldEnableFirewall.ts
  Improve envToBool
  Add AIKIDO_DISABLE and envToBool helper
  Fix ShellJS tests
  Unhook fs functions that are not dangerous
  Increase code coverage
  Add distinct test with safe context
  Add happy path test
  Use separate method for distinct
  Undici/Fetch: Add metadata for SSRF
  Check filter for NoSQL of mongodb distinct
  Add test (no injection)
  Fix NoSQL injection bypass
  Add comment
  Remove lock file, not used (Docker container)
  Move server
  ...
  • Loading branch information
hansott committed Oct 7, 2024
2 parents f61da42 + 042099c commit 4b33956
Show file tree
Hide file tree
Showing 67 changed files with 1,382 additions and 279 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/end-to-end-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Add local.aikido.io to /etc/hosts
run: |
sudo echo "127.0.0.1 local.aikido.io" | sudo tee -a /etc/hosts
- name: Build and run server
run: |
cd end2end/server && docker build -t server . && docker run -d -p 5874:3000 server
- run: make install
- run: make build
- run: make end2end
2 changes: 1 addition & 1 deletion benchmarks/hono-pg/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const spawn = require("child_process").spawn;
async function startServer(firewallEnabled) {
console.log("Spawning server. Firewall enabled:", firewallEnabled);

let env = { ...process.env };
let env = { ...process.env, AIKIDO_CI: "true" };
if (firewallEnabled) {
env = {
...env,
Expand Down
11 changes: 11 additions & 0 deletions end2end/server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:22

WORKDIR /app

COPY package.json /app

RUN npm install

COPY . /app

CMD ["node" , "/app/app.js"]
22 changes: 22 additions & 0 deletions end2end/server/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const express = require("express");
const config = require("./src/handlers/getConfig");
const captureEvent = require("./src/handlers/captureEvent");
const listEvents = require("./src/handlers/listEvents");
const createApp = require("./src/handlers/createApp");
const checkToken = require("./src/middleware/checkToken");

const app = express();

const port = process.env.PORT || 3000;

app.use(express.json());

app.get("/api/runtime/config", checkToken, config);
app.post("/api/runtime/events", checkToken, captureEvent);

app.get("/api/runtime/events", checkToken, listEvents);
app.post("/api/runtime/apps", createApp);

app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
9 changes: 9 additions & 0 deletions end2end/server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "server",
"version": "1.0.0",
"main": "index.js",
"private": true,
"dependencies": {
"express": "^4.21.0"
}
}
18 changes: 18 additions & 0 deletions end2end/server/src/handlers/captureEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { generateConfig } = require("../zen/config");
const { captureEvent: capture } = require("../zen/events");

module.exports = function captureEvent(req, res) {
if (!req.app) {
throw new Error("App is missing");
}

capture(req.body, req.app);

if (req.body.type === "detected_attack") {
return res.json({
success: true,
});
}

return res.json(generateConfig(req.app));
};
9 changes: 9 additions & 0 deletions end2end/server/src/handlers/createApp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { createApp: create } = require("../zen/apps");

module.exports = function createApp(req, res) {
const token = create();

res.json({
token: token,
});
};
8 changes: 8 additions & 0 deletions end2end/server/src/handlers/getConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { generateConfig } = require("../zen/config");
module.exports = function getConfig(req, res) {
if (!req.app) {
throw new Error("App is missing");
}

res.json(generateConfig(req.app));
};
11 changes: 11 additions & 0 deletions end2end/server/src/handlers/listEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { listEvents: list } = require("../zen/events");

function listEvents(req, res) {
if (!req.app) {
throw new Error("App is missing");
}

res.json(list(req.app));
}

module.exports = listEvents;
23 changes: 23 additions & 0 deletions end2end/server/src/middleware/checkToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { getByToken } = require("../zen/apps");

module.exports = function checkToken(req, res, next) {
const token = req.headers["authorization"];

if (!token) {
return res.status(401).json({
message: "Token is required",
});
}

const app = getByToken(token);

if (!app) {
return res.status(401).json({
message: "Invalid token",
});
}

req.app = app;

next();
};
47 changes: 47 additions & 0 deletions end2end/server/src/zen/apps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { randomInt, timingSafeEqual } = require("crypto");

const apps = [];

let id = 1;
function createApp() {
const appId = id++;
const token = `AIK_RUNTIME_1_${appId}_${generateRandomString(48)}`;
const app = {
id: appId,
token: token,
configUpdatedAt: Date.now(),
};

apps.push(app);

return token;
}

function getByToken(token) {
return apps.find((app) => {
if (app.token.length !== token.length) {
return false;
}

return timingSafeEqual(Buffer.from(app.token), Buffer.from(token));
});
}

function generateRandomString(length) {
const chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const size = chars.length;
let str = "";

for (let i = 0; i < length; i++) {
const randomIndex = randomInt(0, size);
str += chars[randomIndex];
}

return str;
}

module.exports = {
createApp,
getByToken,
};
16 changes: 16 additions & 0 deletions end2end/server/src/zen/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function generateConfig(app) {
return {
success: true,
serviceId: app.id,
configUpdatedAt: app.configUpdatedAt,
heartbeatIntervalInMS: 10 * 60 * 1000,
endpoints: [],
blockedUserIds: [],
allowedIPAddresses: [],
receivedAnyStats: true,
};
}

module.exports = {
generateConfig,
};
23 changes: 23 additions & 0 deletions end2end/server/src/zen/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const events = new Map();

function captureEvent(event, app) {
if (event.type === "heartbeat") {
// Ignore heartbeats
return;
}

if (!events.has(app.id)) {
events.set(app.id, []);
}

events.get(app.id).push(event);
}

function listEvents(app) {
return events.get(app.id) || [];
}

module.exports = {
captureEvent,
listEvents,
};
Loading

0 comments on commit 4b33956

Please sign in to comment.