UNPKG

@nodesecure/js-x-ray

Version:
68 lines 2.07 kB
// Import Third-party Dependencies import { getCallExpressionIdentifier, getMemberExpressionIdentifier } from "@nodesecure/estree-ast-utils"; // Import Internal Dependencies import { generateWarning } from "../warnings.js"; /** * @description Detect serialization of process.env which could indicate environment variable exfiltration * @example * JSON.stringify(process.env) * JSON.stringify(process["env"]) * JSON.stringify(process["env"]) * JSON.stringify(process[`env`]) */ function validateNode(node, ctx) { const { tracer } = ctx.sourceFile; const id = getCallExpressionIdentifier(node); if (id === null) { return [false]; } const data = tracer.getDataFromIdentifier(id); if (data === null || data.identifierOrMemberExpr !== "JSON.stringify") { return [false]; } const castedNode = node; if (castedNode.arguments.length === 0) { return [false]; } const firstArg = castedNode.arguments[0]; if (firstArg.type === "MemberExpression") { const memberExprId = [...getMemberExpressionIdentifier(firstArg)].join("."); if (memberExprId === "process.env") { return [true]; } } if (firstArg.type === "Identifier") { const data = tracer.getDataFromIdentifier(firstArg.name); if (data !== null) { return [true]; } } return [false]; } function main(node, ctx) { const { sourceFile, signals } = ctx; const warning = generateWarning("serialize-environment", { value: "JSON.stringify(process.env)", location: node.loc }); sourceFile.warnings.push(warning); return signals.Skip; } function initialize(ctx) { const { tracer } = ctx.sourceFile; tracer .trace("process.env", { followConsecutiveAssignment: true }) .trace("JSON.stringify", { followConsecutiveAssignment: true }); } export default { name: "isSerializeEnv", validateNode, initialize, main, breakOnMatch: false }; //# sourceMappingURL=isSerializeEnv.js.map