n8n-io/n8n · error · SecurityError
Security violation: 'constructor access' is not allowed
Error message
Security violation: 'constructor access' is not allowed
What it means
Thrown by validateCallExpression when the callee is a MemberExpression whose property is an Identifier named 'constructor'. Calling `.constructor(...)` is a known prototype-pollution / sandbox-escape vector (e.g., `{}.constructor.constructor('return process')()`). This guard blocks the invocation specifically.
Source
Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/validators.ts:313
// 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
*/
export function validateMemberExpression(node: MemberExpression, sourceCode: string): void {
// Reject dynamic property access obj[expr] (computed access)
// Allow obj.property (non-computed)
if (node.computed) {
// Allow simple literal keys like obj["key"] or obj[0]
if (node.property.type !== 'Literal') {
throw new SecurityError(
'computed-member-access',
node.loc ?? undefined,
sourceCode,View on GitHub (pinned to 5ac6606e81)
Solutions
- Remove all `.constructor(...)` calls from SDK code.
- If you genuinely need to construct values, use literals (object/array/string/number literals) or the SDK factory functions.
- Never use prototype-chain traversal in builder code — it is explicitly forbidden by design.
Example fix
// before
const proc = {}.constructor.constructor('return process')();
// after
// There is no safe equivalent. Remove the call entirely.
// Access process info at runtime in a Code node if absolutely needed. Defensive patterns
Strategy: validation
Validate before calling
function containsConstructorCall(code: string): boolean {
return /\.constructor\s*\(/.test(code);
} Type guard
function callsConstructor(code: string): boolean {
return /\.constructor\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 === 'constructor access') {
// hard block — prototype-chain escape attempt
}
throw e;
} Prevention
- Never traverse prototype chains or call .constructor().
- Build values with literals, not reflective construction.
- Lint for `.constructor(` and reject it.
When it happens
Trigger: SDK code like `x.constructor(...)`, `obj.constructor.constructor(...)`, or any call where the callee is `something.constructor`. Property access of `.constructor` without calling it is caught separately by validateMemberExpression (1152).
Common situations: Intentional sandbox-escape attempts; copy-pasted exploit code; reflection-heavy utility code that walks prototypes.
Related errors
- Security violation: '${name}' is not allowed
- Security violation: 'eval()' is not allowed
- Security violation: 'Function()' is not allowed
- Security violation: 'require()' is not allowed
- Dynamic property access is not allowed. Use static property
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/30b166de17ac74d6.
Report an issue: GitHub.