@nodesecure/js-x-ray
Version:
JavaScript AST XRay analysis
59 lines • 1.7 kB
JavaScript
import { getCallExpressionIdentifier, isCallExpression } from "../estree/index.js";
import { CALL_EXPRESSION_IDENTIFIER } from "../contants.js";
import { generateWarning } from "../warnings.js";
/**
* @description Detect unsafe statement
* @example
* eval("this");
* Function("return this")();
*/
function validateNode(node, ctx) {
return isUnsafeCallee(node, ctx);
}
function main(node, ctx) {
const { sourceFile, data: calleeName, signals } = ctx;
if (!calleeName) {
return signals.Skip;
}
if (calleeName === "Function" &&
node.callee.arguments.length > 0 &&
node.callee.arguments[0].value === "return this") {
return signals.Skip;
}
const warning = generateWarning("unsafe-stmt", {
value: calleeName,
location: node.loc
});
sourceFile.warnings.push(warning);
return signals.Skip;
}
function isFunctionCallee(node, identifier) {
return identifier === "Function" && isCallExpression(node.callee);
}
function isEvalCallee(node) {
const identifier = getCallExpressionIdentifier(node, {
resolveCallExpression: true
});
return identifier === "eval";
}
export function isUnsafeCallee(node, ctx) {
if (node.type !== "CallExpression") {
return [false, null];
}
if (isEvalCallee(node)) {
return [true, "eval"];
}
if (isFunctionCallee(node, ctx.context?.[CALL_EXPRESSION_IDENTIFIER])) {
return [true, "Function"];
}
return [false, null];
}
export default {
name: "isUnsafeCallee",
nodeTypes: ["CallExpression"],
validateNode,
main,
breakOnMatch: false,
context: {}
};
//# sourceMappingURL=isUnsafeCallee.js.map