@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 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.startsWithUnsafePath = startsWithUnsafePath;
const path_1 = require("path");
const wrap_1 = require("../../helpers/wrap");
const rootFolders = [
"/bin/",
"/boot/",
"/dev/",
"/etc/",
"/home/",
"/init/",
"/lib/",
"/media/",
"/mnt/",
"/opt/",
"/proc/",
"/root/",
"/run/",
"/sbin/",
"/srv/",
"/sys/",
"/tmp/",
"/usr/",
"/var/",
// macOS specific
"/applications/",
"/cores/",
"/library/",
"/private/",
"/users/",
"/system/",
"/volumes/",
].map((path) => path.toLowerCase());
const dangerousPathStarts = [...rootFolders, "c:/", "c:\\"];
function startsWithUnsafePath(filePath, userInput) {
// Check if path is relative (not absolute or drive letter path)
// Required because resolve will build absolute paths from relative paths
if (!(0, path_1.isAbsolute)(filePath) || !(0, path_1.isAbsolute)(userInput)) {
return false;
}
let origResolve = path_1.resolve;
if ((0, wrap_1.isWrapped)(path_1.resolve)) {
origResolve = path_1.resolve.__original;
}
const normalizedPath = origResolve(filePath).toLowerCase();
const normalizedUserInput = origResolve(userInput).toLowerCase();
for (const dangerousStart of dangerousPathStarts) {
if (normalizedPath.startsWith(dangerousStart) &&
normalizedPath.startsWith(normalizedUserInput)) {
// If the user input is the same as the dangerous start, we don't want to flag it to prevent false positives
// e.g. if user input is /etc/ and the path is /etc/passwd, we don't want to flag it, as long as the
// user input does not contain a subdirectory or filename
if (userInput === dangerousStart ||
userInput === dangerousStart.slice(0, -1)) {
return false;
}
return true;
}
}
return false;
}
;