feat(core): Block access to env in code and expressions by default (#22643)

This commit is contained in:
Tomi Turtiainen
2025-12-03 12:33:18 +02:00
committed by GitHub
parent 41ef19bc06
commit 0ffd76093c
7 changed files with 21 additions and 38 deletions
@@ -20,7 +20,6 @@ describe('DeprecationService', () => {
// Ignore environment variables coming in from the environment when running
// this test suite.
process.env = {
N8N_BLOCK_ENV_ACCESS_IN_NODE: 'false',
N8N_GIT_NODE_DISABLE_BARE_REPOS: 'false',
};
@@ -117,7 +116,6 @@ describe('DeprecationService', () => {
beforeEach(() => {
process.env = {
N8N_RUNNERS_ENABLED: 'true',
N8N_BLOCK_ENV_ACCESS_IN_NODE: 'false',
N8N_GIT_NODE_DISABLE_BARE_REPOS: 'false',
};
});
@@ -210,37 +208,10 @@ describe('DeprecationService', () => {
});
});
describe('N8N_BLOCK_ENV_ACCESS_IN_NODE', () => {
beforeEach(() => {
process.env = {
N8N_RUNNERS_ENABLED: 'true',
N8N_GIT_NODE_DISABLE_BARE_REPOS: 'false',
};
jest.resetAllMocks();
});
test('should warn when N8N_BLOCK_ENV_ACCESS_IN_NODE is not set', () => {
delete process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE;
deprecationService.warn();
expect(logger.warn).toHaveBeenCalled();
});
test.each(['false', 'true'])(
'should not warn when N8N_BLOCK_ENV_ACCESS_IN_NODE is %s',
(value) => {
process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE = value;
deprecationService.warn();
expect(logger.warn).not.toHaveBeenCalled();
},
);
});
describe('N8N_GIT_NODE_DISABLE_BARE_REPOS', () => {
beforeEach(() => {
process.env = {
N8N_RUNNERS_ENABLED: 'true',
N8N_BLOCK_ENV_ACCESS_IN_NODE: 'false',
};
jest.resetAllMocks();
});
@@ -91,12 +91,6 @@ export class DeprecationService {
'n8n does not support `own` mode since May 2023. Please remove this environment variable to allow n8n to start. If you need the isolation and performance gains, please consider queue mode: https://docs.n8n.io/hosting/scaling/queue-mode/',
checkValue: (value: string) => value === 'own',
},
{
envVar: 'N8N_BLOCK_ENV_ACCESS_IN_NODE',
message:
'The default value of N8N_BLOCK_ENV_ACCESS_IN_NODE will be changed from false to true in a future version. If you need to access environment variables from the Code Node or from expressions, please set N8N_BLOCK_ENV_ACCESS_IN_NODE=false. Learn more: https://docs.n8n.io/hosting/configuration/environment-variables/security/',
checkValue: (value: string | undefined) => value === undefined || value === '',
},
{
envVar: 'N8N_GIT_NODE_DISABLE_BARE_REPOS',
message:
@@ -11,7 +11,7 @@ type PythonSandboxContext = {
type PyodideError = Error & { type: string };
const envAccessBlocked = process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE === 'true';
const envAccessBlocked = process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE !== 'false';
export class PythonSandbox extends Sandbox {
private readonly context: PythonSandboxContext;
+1 -1
View File
@@ -282,7 +282,7 @@ export class Expression {
typeof process !== 'undefined'
? {
arch: process.arch,
env: process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE === 'true' ? {} : process.env,
env: process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE !== 'false' ? {} : process.env,
platform: process.platform,
pid: process.pid,
ppid: process.ppid,
@@ -13,7 +13,7 @@ export type EnvProviderState = {
export function createEnvProviderState(): EnvProviderState {
const isProcessAvailable = typeof process !== 'undefined';
const isEnvAccessBlocked = isProcessAvailable
? process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE === 'true'
? process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE !== 'false'
: false;
const env: Record<string, string> =
!isProcessAvailable || isEnvAccessBlocked ? {} : (process.env as Record<string, string>);
@@ -7,6 +7,8 @@ describe('createEnvProviderState', () => {
});
it('should return the state with process available and env access allowed', () => {
process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE = 'false';
expect(createEnvProviderState()).toEqual({
isProcessAvailable: true,
isEnvAccessBlocked: false,
@@ -24,6 +26,14 @@ describe('createEnvProviderState', () => {
});
});
it('should block env access when N8N_BLOCK_ENV_ACCESS_IN_NODE is not set', () => {
expect(createEnvProviderState()).toEqual({
isProcessAvailable: true,
isEnvAccessBlocked: true,
env: {},
});
});
it('should handle process not being available', () => {
const originalProcess = global.process;
try {
@@ -42,12 +52,18 @@ describe('createEnvProviderState', () => {
});
describe('createEnvProvider', () => {
afterEach(() => {
delete process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE;
});
it('should return true when checking for a property using "has"', () => {
const proxy = createEnvProvider(0, 0, createEnvProviderState());
expect('someProperty' in proxy).toBe(true);
});
it('should return the value from process.env if access is allowed', () => {
process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE = 'false';
process.env.TEST_ENV_VAR = 'test_value';
const proxy = createEnvProvider(0, 0, createEnvProviderState());
expect(proxy.TEST_ENV_VAR).toBe('test_value');
+2
View File
@@ -1743,6 +1743,8 @@ describe('Workflow', () => {
for (const testData of tests) {
test(testData.description, () => {
process.env.N8N_BLOCK_ENV_ACCESS_IN_NODE = 'false';
const nodes: INode[] = [
{
name: 'Node1',