@aikidosec/firewall
Version:
Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.
63 lines (62 loc) • 2.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.shouldRateLimitRequest = shouldRateLimitRequest;
const Context_1 = require("../agent/Context");
const isLocalhostIP_1 = require("../helpers/isLocalhostIP");
const getRateLimitedEndpoint_1 = require("./getRateLimitedEndpoint");
// eslint-disable-next-line max-lines-per-function
function shouldRateLimitRequest(context, agent) {
// Do not consume rate limit for the same request a second time
// (Might happen if the user adds the middleware multiple times)
if (context.consumedRateLimit) {
return { block: false };
}
// We want to count the request only once
(0, Context_1.updateContext)(context, "consumedRateLimit", true);
const endpoint = (0, getRateLimitedEndpoint_1.getRateLimitedEndpoint)(context, agent.getConfig());
if (!endpoint) {
return { block: false };
}
const isProduction = process.env.NODE_ENV === "production";
// Allow requests from localhost in development to be rate limited
// In production, we don't want to rate limit localhost
const isFromLocalhostInProduction = context.remoteAddress &&
(0, isLocalhostIP_1.isLocalhostIP)(context.remoteAddress) &&
isProduction;
// Allow requests from allowed IPs, e.g. never rate limit office IPs
const isBypassedIP = context.remoteAddress &&
agent.getConfig().isBypassedIP(context.remoteAddress);
if (isFromLocalhostInProduction || isBypassedIP) {
return { block: false };
}
const { maxRequests, windowSizeInMS } = endpoint.rateLimiting;
if (context.rateLimitGroup) {
const allowed = agent
.getRateLimiter()
.isAllowed(`${endpoint.method}:${endpoint.route}:group:${context.rateLimitGroup}`, windowSizeInMS, maxRequests);
if (!allowed) {
return { block: true, trigger: "group", endpoint };
}
// Do not check IP or User rate limit if rateLimitGroup is set
return { block: false };
}
if (context.user) {
const allowed = agent
.getRateLimiter()
.isAllowed(`${endpoint.method}:${endpoint.route}:user:${context.user.id}`, windowSizeInMS, maxRequests);
if (!allowed) {
return { block: true, trigger: "user", endpoint };
}
// Do not check IP rate limit if user is set
return { block: false };
}
if (context.remoteAddress) {
const allowed = agent
.getRateLimiter()
.isAllowed(`${endpoint.method}:${endpoint.route}:ip:${context.remoteAddress}`, windowSizeInMS, maxRequests);
if (!allowed) {
return { block: true, trigger: "ip", endpoint };
}
}
return { block: false };
}