UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks

66 lines (65 loc) 2.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.detectPathTraversal = detectPathTraversal; const containsUnsafePathParts_1 = require("./containsUnsafePathParts"); const unsafePathStart_1 = require("./unsafePathStart"); const url_1 = require("url"); function detectPathTraversal(filePath, userInput, checkPathStart = true, isUrl = false) { if (userInput.length <= 1) { // We ignore single characters since they don't pose a big threat. return false; } // Check for URL path traversal // Reason: new URL("file:///../../test.txt") => /test.txt // The normal check for relative path traversal will fail in this case, because transformed path does not contain ../. // For absolute path traversal, we dont need to check the transformed path, because it will always start with /. // Also /./ is checked by normal absolute path traversal check (if #219 is merged) // Use containsUnsafePathPartsUrl, because urls can contain a TAB, carriage return or line feed that is silently removed by the URL constructor. if (isUrl && (0, containsUnsafePathParts_1.containsUnsafePathPartsUrl)(userInput)) { const filePathFromUrl = parseAsFileUrl(userInput); if (filePathFromUrl && filePath.includes(filePathFromUrl)) { return true; } } if (userInput.length > filePath.length) { // We ignore cases where the user input is longer than the file path. // Because the user input can't be part of the file path. return false; } if (!filePath.includes(userInput)) { // We ignore cases where the user input is not part of the file path. return false; } if ((0, containsUnsafePathParts_1.containsUnsafePathParts)(filePath) && (0, containsUnsafePathParts_1.containsUnsafePathParts)(userInput)) { return true; } if (checkPathStart) { // Check for absolute path traversal return (0, unsafePathStart_1.startsWithUnsafePath)(filePath, userInput); } return false; } /** * This function is used to convert a file path as a URL to a file path. * It is used to handle cases where a URL object is passed to a fs function. * For example new URL("file:///../../test.txt") => file:///test.txt * This function will convert ../../test.txt to /test.txt * If the URL is not a file URL, it will return undefined. * Another sample: new URL("file:///./test.txt") => /test.txt */ function parseAsFileUrl(path) { let url = path; if (!url.toLowerCase().startsWith("file:")) { if (!url.startsWith("/")) { url = `/${url}`; } url = `file://${url}`; } try { return (0, url_1.fileURLToPath)(url); } catch { // } return undefined; }