{"record":{"id":"1f4c1817d15e4bc7","repo":"n8n-io/n8n","slug":"cannot-access-name-via-expression-extension-d","errorCode":null,"errorMessage":"Cannot access \"${name}\" via expression extension due to security concerns","messagePattern":"Cannot access \"(.+?)\" via expression extension due to security concerns","errorType":"exception","errorClass":"ExpressionExtensionError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/expression-runtime/src/extensions/extend.ts","lineNumber":82,"sourceCode":"\t'_linkedBinding',\n\t'_load',\n\t'prepareStackTrace',\n\t'__lookupGetter__',\n\t'__lookupSetter__',\n\t'__defineGetter__',\n\t'__defineSetter__',\n\t'caller',\n\t'arguments',\n\t'getBuiltinModule',\n\t'dlopen',\n\t'execve',\n\t'loadEnvFile',\n]);\n\nfunction findExtendedFunction(input: unknown, functionName: string): FoundFunction | undefined {\n\tconst name = typeof functionName === 'string' ? functionName : String(functionName);\n\tif (UNSAFE_PROPERTY_NAMES.has(name)) {\n\t\tthrow new ExpressionExtensionError(\n\t\t\t`Cannot access \"${name}\" via expression extension due to security concerns`,\n\t\t);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-restricted-types\n\tlet foundFunction: Function | undefined;\n\tif (Array.isArray(input)) {\n\t\tfoundFunction = arrayExtensions.functions[name];\n\t} else if (isDate(input) && name !== 'toDate' && name !== 'toDateTime') {\n\t\t// If it's a string date (from $json), convert it to a Date object,\n\t\t// unless that function is `toDate`, since `toDate` does something\n\t\t// very different on date objects\n\t\tinput = new Date(input as string);\n\t\tfoundFunction = dateExtensions.functions[name];\n\t} else if (typeof input === 'string') {\n\t\tfoundFunction = stringExtensions.functions[name];\n\t} else if (typeof input === 'number') {\n\t\tfoundFunction = numberExtensions.functions[name];","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/expression-runtime/src/extensions/extend.ts#L64-L100","documentation":"n8n sandbox-blocks a hardcoded set of unsafe property names (`__proto__`, `constructor`, `caller`, `arguments`, `__defineGetter__`/`__defineSetter__`, `getBuiltinModule`, `dlopen`, `execve`, `loadEnvFile`, ...) from being dispatched as expression extensions. This is a deliberate hardening to prevent prototype pollution and access to dangerous Node primitives from inside an expression.","triggerScenarios":"Invoking any blocked name as an extension method: `{{ $json.foo.constructor() }}`, `{{ $json.bar.__proto__ }}`, `{{ $json.x.dlopen() }}`, `{{ $json.y.loadEnvFile() }}`.","commonSituations":"Attempts at prototype-chain traversal in an expression; libraries/probes that walk `__proto__`; adversarial or untrusted input routed through an expression.","solutions":["Do not access these property names through expressions.","Move the logic into a Code node where full (sandboxed) JS is available, and only return primitive values back into the workflow.","Sanitize untrusted input before it reaches an expression."],"exampleFix":"// before\n{{ $json.foo.constructor('return process')() }}\n// after\n// move the computation into a Code node; do not reach through constructors in expressions","handlingStrategy":"validation","validationCode":"const UNSAFE = new Set(['__proto__','constructor','prototype','caller','arguments','__defineGetter__','__defineSetter__','getBuiltinModule','dlopen','execve','loadEnvFile']);\nconst name = $json.methodName;\nif (typeof name === 'string' && UNSAFE.has(name)) {\n  throw new Error(`Refusing to dispatch blocked property: ${name}`);\n}\nreturn $json;","typeGuard":"const isSafePropertyName = (name: string): boolean =>\n  !['__proto__','constructor','prototype','caller','arguments','__defineGetter__','__defineSetter__','getBuiltinModule','dlopen','execve','loadEnvFile'].includes(name);","tryCatchPattern":null,"preventionTips":["Never reach through `constructor` or `__proto__` in expressions.","Do dynamic/reflective work in a Code node, returning only primitives.","Treat untrusted input as untrusted — sanitize before it reaches an expression."],"tags":["security","expression","sandbox","prototype-pollution"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}