@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.
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);
}
;