n8n-io/n8n · error · SecurityError

Security violation: 'Function()' is not allowed

Error message

Security violation: 'Function()' is not allowed

What it means

Thrown by validateCallExpression when a CallExpression's callee is an Identifier named 'Function'. `Function(...)` is the Function constructor, which compiles and executes arbitrary strings — equivalent to eval. Blocked as a hard security boundary.

Source

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

): 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);
		}
	}
}

/**
 * Validate a member expression.
 * @throws SecurityError if the access is dangerous

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Remove all Function() constructor calls.
  2. Use static function definitions where allowed, or express the logic via the SDK DSL (factory functions, builder methods).
  3. If dynamic behavior is required, run it in a Code node at execution time, not in the SDK builder.

Example fix

// before
const fn = new Function('x', 'return x * 2');

// after
// SDK builder code is declarative — express the operation as a parameter
export default workflow()
  .add(node('Set').parameters({ doubled: '={{ $json.x * 2 }}' }));
Defensive patterns

Strategy: validation

Validate before calling

function containsFunctionCtor(code: string): boolean {
  return /\bFunction\s*\(/.test(code) || /\bnew\s+Function\s*\(/.test(code);
}

Type guard

function usesFunctionConstructor(code: string): boolean {
  return /\b(new\s+)?Function\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 === 'Function()') {
    // hard block — instruct removal of Function constructor
  }
  throw e;
}

Prevention

When it happens

Trigger: SDK code containing `new Function(...)` or `Function(...)` calls. Both `new Function('return ...')()` and `Function('...')()` are caught because the callee Identifier is 'Function'.

Common situations: Metaprogramming; building dynamic callbacks; polyfills; code that constructs functions from strings.

Related errors


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