Skip to content

Commit 0fff2ae

Browse files
committed
Proof of concept for serverless async check
1 parent a69e463 commit 0fff2ae

File tree

5 files changed

+77
-3
lines changed

5 files changed

+77
-3
lines changed

library/agent/Agent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,8 @@ export class Agent {
546546
onMiddlewareExecuted() {
547547
this.middlewareInstalled = true;
548548
}
549+
550+
getToken() {
551+
return this.token;
552+
}
549553
}

library/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import isFirewallSupported from "./helpers/isFirewallSupported";
33
import shouldEnableFirewall from "./helpers/shouldEnableFirewall";
44
import { setUser } from "./agent/context/user";
55
import { shouldBlockRequest } from "./middleware/shouldBlockRequest";
6-
import { addExpressMiddleware } from "./middleware/express";
6+
import {
7+
addExpressMiddleware,
8+
addExpressMiddlewareAsync,
9+
} from "./middleware/express";
710
import { addHonoMiddleware } from "./middleware/hono";
811
import { addHapiMiddleware } from "./middleware/hapi";
912
import { addFastifyHook } from "./middleware/fastify";
@@ -20,6 +23,7 @@ export {
2023
setUser,
2124
shouldBlockRequest,
2225
addExpressMiddleware,
26+
addExpressMiddlewareAsync,
2327
addHonoMiddleware,
2428
addHapiMiddleware,
2529
addFastifyHook,
@@ -32,6 +36,7 @@ export default {
3236
setUser,
3337
shouldBlockRequest,
3438
addExpressMiddleware,
39+
addExpressMiddlewareAsync,
3540
addHonoMiddleware,
3641
addHapiMiddleware,
3742
addFastifyHook,

library/middleware/express.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/** TS_EXPECT_TYPES_ERROR_OPTIONAL_DEPENDENCY **/
22
import type { Express } from "express";
3-
import { shouldBlockRequest } from "./shouldBlockRequest";
3+
import {
4+
shouldBlockRequest,
5+
shouldBlockRequestAsync,
6+
} from "./shouldBlockRequest";
47
import { escapeHTML } from "../helpers/escapeHTML";
58

69
/**
@@ -30,3 +33,31 @@ export function addExpressMiddleware(app: Express) {
3033
next();
3134
});
3235
}
36+
37+
export function addExpressMiddlewareAsync(app: Express) {
38+
app.use((req, res, next) => {
39+
shouldBlockRequestAsync()
40+
.then((result) => {
41+
if (result.block) {
42+
if (result.type === "ratelimited") {
43+
let message = "You are rate limited by Zen.";
44+
if (result.trigger === "ip" && result.ip) {
45+
message += ` (Your IP: ${escapeHTML(result.ip)})`;
46+
}
47+
48+
return res.status(429).type("text").send(message);
49+
}
50+
51+
if (result.type === "blocked") {
52+
return res.status(403).type("text").send("You are blocked by Zen.");
53+
}
54+
}
55+
56+
next();
57+
})
58+
.catch((error) => {
59+
console.error(error);
60+
next();
61+
});
62+
});
63+
}

library/middleware/shouldBlockRequest.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,38 @@ type Result = {
99
ip?: string;
1010
};
1111

12+
const SERVERLESS_URL = "http://localhost:5132";
13+
14+
export async function shouldBlockRequestAsync(): Promise<Result> {
15+
const context = getContext();
16+
if (!context) {
17+
return { block: false };
18+
}
19+
20+
const agent = getInstance();
21+
if (!agent) {
22+
return { block: false };
23+
}
24+
25+
const response = await fetch(`${SERVERLESS_URL}/check-request`, {
26+
method: "POST",
27+
headers: {
28+
// TODO: Remove "!", token is not guaranteed to be present
29+
Authorization: agent.getToken()!.asString(),
30+
"Content-Type": "application/json",
31+
},
32+
body: JSON.stringify({
33+
method: context.method,
34+
headers: context.headers,
35+
url: context.url,
36+
route: context.route,
37+
clientIp: context.remoteAddress,
38+
}),
39+
});
40+
41+
return await response.json();
42+
}
43+
1244
export function shouldBlockRequest(): Result {
1345
const context = getContext();
1446
if (!context) {

sample-apps/express-mysql/app.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
require("dotenv").config();
2-
require("@aikidosec/firewall");
2+
const Zen = require("@aikidosec/firewall");
33
const Sentry = require("@sentry/node");
44

55
Sentry.init({
@@ -59,6 +59,8 @@ async function main(port) {
5959

6060
const app = express();
6161

62+
Zen.addExpressMiddlewareAsync(app);
63+
6264
app.use(Sentry.Handlers.requestHandler());
6365
app.use(morgan("tiny"));
6466

0 commit comments

Comments
 (0)