@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
99 lines (98 loc) • 4.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapExport = wrapExport;
const AgentSingleton_1 = require("../AgentSingleton");
const Context_1 = require("../Context");
const wrapDefaultOrNamed_1 = require("./wrapDefaultOrNamed");
const onInspectionInterceptorResult_1 = require("./onInspectionInterceptorResult");
/**
* Wraps a function with the provided interceptors.
* If the function is not part of an object, like default exports, pass undefined as methodName and the function as subject.
*/
function wrapExport(subject, methodName, pkgInfo, interceptors) {
const agent = (0, AgentSingleton_1.getInstance)();
if (!agent) {
throw new Error("Can not wrap exports if agent is not initialized");
}
try {
return (0, wrapDefaultOrNamed_1.wrapDefaultOrNamed)(subject, methodName, function wrap(original) {
return function wrap() {
// eslint-disable-next-line prefer-rest-params
let args = Array.from(arguments);
const context = (0, Context_1.getContext)();
// Run inspectArgs interceptor if provided
if (typeof interceptors.inspectArgs === "function") {
// Bind context to functions in arguments
for (let i = 0; i < args.length; i++) {
if (typeof args[i] === "function") {
args[i] = (0, Context_1.bindContext)(args[i]);
}
}
inspectArgs.call(
// @ts-expect-error We don't now the type of this
this, args, interceptors.inspectArgs, context, agent, pkgInfo, methodName || "", interceptors.kind);
}
// Run modifyArgs interceptor if provided
if (typeof interceptors.modifyArgs === "function") {
try {
args = interceptors.modifyArgs(args, agent);
}
catch (error) {
agent.onErrorThrownByInterceptor({
error: error,
method: methodName || "default export",
module: pkgInfo.name,
});
}
}
const returnVal = original.apply(
// @ts-expect-error We don't now the type of this
this, args);
// Run modifyReturnValue interceptor if provided
if (typeof interceptors.modifyReturnValue === "function") {
try {
return interceptors.modifyReturnValue(args, returnVal, agent,
// @ts-expect-error We don't now the type of
this);
}
catch (error) {
agent.onErrorThrownByInterceptor({
error: error,
method: methodName || "default export",
module: pkgInfo.name,
});
}
}
return returnVal;
};
});
}
catch (error) {
if (error instanceof Error) {
agent.onFailedToWrapMethod(pkgInfo.name, methodName || "default export", error);
}
}
}
function inspectArgs(args, interceptor, context, agent, pkgInfo, methodName, kind) {
if (context) {
const matches = agent.getConfig().getEndpoints(context);
if (matches.find((match) => match.forceProtectionOff)) {
return;
}
}
const start = performance.now();
let result = undefined;
try {
result = interceptor(args, agent,
// @ts-expect-error We don't now the type of this
this);
}
catch (error) {
agent.onErrorThrownByInterceptor({
error: error,
method: methodName,
module: pkgInfo.name,
});
}
(0, onInspectionInterceptorResult_1.onInspectionInterceptorResult)(context, agent, result, pkgInfo, start, `${pkgInfo.name}.${methodName}`, kind);
}