n8n-io/n8n · error · SecurityError

Security violation: 'eval()' is not allowed

Error message

Security violation: 'eval()' is not allowed

What it means

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).

Source

Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/validators.ts:299

	_allowedVariables: Set<string>,
	node: Node,
	sourceCode: string,
): void {
	if (DANGEROUS_GLOBALS.has(name)) {
		throw new SecurityError(name, node.loc ?? undefined, sourceCode);
	}
}

/**
 * Validate a function call expression.
 * @throws SecurityError if the call is dangerous
 */
export function validateCallExpression(node: CallExpression, sourceCode: string): void {
	// Check for dangerous patterns like eval("...")
	if (node.callee.type === 'Identifier') {
		const name = node.callee.name;
		if (name === 'eval') {
			throw new SecurityError('eval()', node.loc ?? undefined, sourceCode);
		}
		if (name === 'Function') {
			throw new SecurityError('Function()', node.loc ?? undefined, sourceCode);
		}
		if (name === 'require') {
			throw new SecurityError('require()', node.loc ?? undefined, sourceCode);
		}
	}

	// Check for dangerous patterns like global.constructor.constructor
	if (node.callee.type === 'MemberExpression') {
		const memberExpr = node.callee;
		if (memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'constructor') {
			throw new SecurityError('constructor access', node.loc ?? undefined, sourceCode);
		}
	}
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Remove all eval() calls — there is no safe replacement inside SDK builder code.
  2. If you need dynamic computation, pre-compute the result and pass it as a literal/parameter.
  3. Move truly dynamic code execution into a Code node where it runs in the n8n sandbox, not in the SDK builder interpreter.

Example fix

// before
const cfg = eval('(' + jsonStr + ')');

// after
const cfg = { a: 1, b: 2 };  // build the object statically
// or parse the string at runtime in a Code node
Defensive patterns

Strategy: validation

Validate before calling

function containsEval(code: string): boolean {
  return /\beval\s*\(/.test(code);
}

Type guard

function callsEval(code: string): boolean {
  return /\beval\s*\(/.test(code);
}

Try / catch

import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';
import { SecurityError } from '@n8n/workflow-sdk/ast-interpreter/errors';

try {
  interpretSDKCode(code, sdkFunctions);
} catch (e) {
  if (e instanceof SecurityError && e.pattern === 'eval()') {
    // hard block — instruct removal of eval
  }
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: Pasting code that dynamically evaluates strings; metaprogramming patterns; code that builds and executes strings at runtime.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/0c22b4e6e805b80b. Report an issue: GitHub.