{"record":{"id":"0c22b4e6e805b80b","repo":"n8n-io/n8n","slug":"security-violation-eval-is-not-allowed","errorCode":null,"errorMessage":"Security violation: 'eval()' is not allowed","messagePattern":"Security violation: 'eval\\(\\)' is not allowed","errorType":"exception","errorClass":"SecurityError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/workflow-sdk/src/ast-interpreter/validators.ts","lineNumber":299,"sourceCode":"\t_allowedVariables: Set<string>,\n\tnode: Node,\n\tsourceCode: string,\n): void {\n\tif (DANGEROUS_GLOBALS.has(name)) {\n\t\tthrow new SecurityError(name, node.loc ?? undefined, sourceCode);\n\t}\n}\n\n/**\n * Validate a function call expression.\n * @throws SecurityError if the call is dangerous\n */\nexport function validateCallExpression(node: CallExpression, sourceCode: string): void {\n\t// Check for dangerous patterns like eval(\"...\")\n\tif (node.callee.type === 'Identifier') {\n\t\tconst name = node.callee.name;\n\t\tif (name === 'eval') {\n\t\t\tthrow new SecurityError('eval()', node.loc ?? undefined, sourceCode);\n\t\t}\n\t\tif (name === 'Function') {\n\t\t\tthrow new SecurityError('Function()', node.loc ?? undefined, sourceCode);\n\t\t}\n\t\tif (name === 'require') {\n\t\t\tthrow new SecurityError('require()', node.loc ?? undefined, sourceCode);\n\t\t}\n\t}\n\n\t// Check for dangerous patterns like global.constructor.constructor\n\tif (node.callee.type === 'MemberExpression') {\n\t\tconst memberExpr = node.callee;\n\t\tif (memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'constructor') {\n\t\t\tthrow new SecurityError('constructor access', node.loc ?? undefined, sourceCode);\n\t\t}\n\t}\n}\n","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/workflow-sdk/src/ast-interpreter/validators.ts#L281-L317","documentation":"Thrown by validateCallExpression when a CallExpression's callee is an Identifier named 'eval'. eval() would execute arbitrary strings, defeating the entire secure-interpreter design. This is one of three hard-blocked call identifiers (eval, Function, require).","triggerScenarios":"SDK code containing `eval(...)`, even indirectly where an identifier named `eval` is called. Aliased eval (`const e = eval; e(...)`) is caught separately by the dangerous-global identifier check (1146).","commonSituations":"Pasting code that dynamically evaluates strings; metaprogramming patterns; code that builds and executes strings at runtime.","solutions":["Remove all eval() calls — there is no safe replacement inside SDK builder code.","If you need dynamic computation, pre-compute the result and pass it as a literal/parameter.","Move truly dynamic code execution into a Code node where it runs in the n8n sandbox, not in the SDK builder interpreter."],"exampleFix":"// before\nconst cfg = eval('(' + jsonStr + ')');\n\n// after\nconst cfg = { a: 1, b: 2 };  // build the object statically\n// or parse the string at runtime in a Code node","handlingStrategy":"validation","validationCode":"function containsEval(code: string): boolean {\n  return /\\beval\\s*\\(/.test(code);\n}","typeGuard":"function callsEval(code: string): boolean {\n  return /\\beval\\s*\\(/.test(code);\n}","tryCatchPattern":"import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';\nimport { SecurityError } from '@n8n/workflow-sdk/ast-interpreter/errors';\n\ntry {\n  interpretSDKCode(code, sdkFunctions);\n} catch (e) {\n  if (e instanceof SecurityError && e.pattern === 'eval()') {\n    // hard block — instruct removal of eval\n  }\n  throw e;\n}","preventionTips":["Ban eval via lint (no-eval rule).","Pre-compute dynamic values; never build+execute strings.","Use a Code node for any runtime string-evaluation need."],"tags":["sdk","validators","security","eval","code-injection"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}