@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
88 lines (87 loc) • 3.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Path = void 0;
const Context_1 = require("../agent/Context");
const wrapExport_1 = require("../agent/hooks/wrapExport");
const isWindows_1 = require("../helpers/isWindows");
const checkContextForPathTraversal_1 = require("../vulnerabilities/path-traversal/checkContextForPathTraversal");
class Path {
constructor() {
this.patchedPosix = false;
this.patchedWin32 = false;
}
inspectPath(args, operation) {
const context = (0, Context_1.getContext)();
if (!context) {
return undefined;
}
for (const path of args) {
if (typeof path === "string") {
const result = (0, checkContextForPathTraversal_1.checkContextForPathTraversal)({
filename: path,
operation: `path.${operation}`,
context: context,
/* Only check the first arg for absolute path traversal.
If an insecure absolute path is passed as the second argument,
it can not be an absolute path because it is not the start of the resulting path. */
checkPathStart: path === args[0],
});
if (result) {
return result;
}
}
}
return undefined;
}
wrapFunctions(exports, pkgInfo) {
const functions = ["join", "resolve", "normalize"];
for (const func of functions) {
(0, wrapExport_1.wrapExport)(exports, func, pkgInfo, {
kind: "fs_op",
inspectArgs: (args) => this.inspectPath(args, func),
});
}
}
wrapMainModule(exports, pkgInfo) {
// If `path/win32` or `path/posix` was not required before `path`, we should wrap the functions in `path`
if (!this.patchedWin32 && !this.patchedPosix) {
this.wrapFunctions(exports, pkgInfo);
}
if ((0, isWindows_1.isWindows)()) {
// `require("path").join` is the same as `require("path/win32").join`
this.patchedWin32 = true;
}
else {
// `require("path").join` is the same as `require("path/posix").join`
this.patchedPosix = true;
}
this.wrapPosix(exports.posix, pkgInfo);
this.wrapWin32(exports.win32, pkgInfo);
}
wrapPosix(exports, pkgInfo) {
if (this.patchedPosix) {
return;
}
this.wrapFunctions(exports, pkgInfo);
this.patchedPosix = true;
}
wrapWin32(exports, pkgInfo) {
if (this.patchedWin32) {
return;
}
this.wrapFunctions(exports, pkgInfo);
this.patchedWin32 = true;
}
wrap(hooks) {
hooks
.addBuiltinModule("path")
.onRequire((exports, pkgInfo) => this.wrapMainModule(exports, pkgInfo));
hooks
.addBuiltinModule("path/posix")
.onRequire((exports, pkgInfo) => this.wrapPosix(exports, pkgInfo));
hooks
.addBuiltinModule("path/win32")
.onRequire((exports, pkgInfo) => this.wrapWin32(exports, pkgInfo));
}
}
exports.Path = Path;