@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.
61 lines (60 loc) • 2.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildRouteFromURL = buildRouteFromURL;
const looksLikeASecret_1 = require("./looksLikeASecret");
const tryParseURLPath_1 = require("./tryParseURLPath");
const net_1 = require("net");
const UUID = /(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
const OBJECT_ID = /^[0-9a-f]{24}$/i;
const ULID = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
const NUMBER = /^\d+$/;
const DATE = /^\d{4}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4}$/;
const EMAIL = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
const HASH = /^(?:[a-f0-9]{32}|[a-f0-9]{40}|[a-f0-9]{64}|[a-f0-9]{128})$/i;
const HASH_LENGTHS = [32, 40, 64, 128];
function buildRouteFromURL(url) {
const path = (0, tryParseURLPath_1.tryParseURLPath)(url);
if (!path) {
return undefined;
}
const route = path.split("/").map(replaceURLSegmentWithParam).join("/");
if (route === "/") {
return "/";
}
if (route.endsWith("/")) {
return route.slice(0, -1);
}
return route;
}
function replaceURLSegmentWithParam(segment) {
const charCode = segment.charCodeAt(0);
const startsWithNumber = charCode >= 48 && charCode <= 57; // ASCII codes for '0' to '9'
if (startsWithNumber && NUMBER.test(segment)) {
return ":number";
}
if (segment.length === 36 && UUID.test(segment)) {
return ":uuid";
}
if (segment.length === 26 && ULID.test(segment)) {
return ":ulid";
}
if (segment.length === 24 && OBJECT_ID.test(segment)) {
return ":objectId";
}
if (startsWithNumber && DATE.test(segment)) {
return ":date";
}
if (segment.includes("@") && EMAIL.test(segment)) {
return ":email";
}
if ((segment.includes(":") || segment.includes(".")) && (0, net_1.isIP)(segment)) {
return ":ip";
}
if (HASH_LENGTHS.includes(segment.length) && HASH.test(segment)) {
return ":hash";
}
if ((0, looksLikeASecret_1.looksLikeASecret)(segment)) {
return ":secret";
}
return segment;
}