Skip to content

Commit f865bb6

Browse files
committed
fix(core): Set default for allowed file access dirs
1 parent 83ea8e1 commit f865bb6

File tree

3 files changed

+17
-14
lines changed

3 files changed

+17
-14
lines changed

packages/@n8n/config/src/configs/security.config.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ import { Config, Env } from '../decorators';
33
@Config
44
export class SecurityConfig {
55
/**
6-
* Which directories to limit n8n's access to. Separate multiple dirs with semicolon `;`.
6+
* Dirs that the `ReadWriteFile` and `ReadBinaryFiles` nodes are allowed to access. Separate multiple dirs with semicolon `;`.
7+
* Set to an empty string to disable restrictions (insecure, not recommended for production).
78
*
8-
* @example N8N_RESTRICT_FILE_ACCESS_TO=/home/user/.n8n;/home/user/n8n-data
9+
* @example N8N_RESTRICT_FILE_ACCESS_TO=/home/john/my-n8n-files
910
*/
1011
@Env('N8N_RESTRICT_FILE_ACCESS_TO')
11-
restrictFileAccessTo: string = '';
12+
restrictFileAccessTo: string = '~/.n8n-files';
1213

1314
/**
14-
* Whether to block access to all files at:
15-
* - the ".n8n" directory,
16-
* - the static cache dir at ~/.cache/n8n/public, and
17-
* - user-defined config files.
15+
* Whether to block users from accessing files at dirs internally used by n8n:
16+
* - `~/.n8n`
17+
* - `~/.cache/n8n/public`
18+
* - any dirs specified by `N8N_CONFIG_FILES`, `N8N_CUSTOM_EXTENSIONS`, `N8N_BINARY_DATA_STORAGE_PATH`, `N8N_UM_EMAIL_TEMPLATES_INVITE`, and `UM_EMAIL_TEMPLATES_PWRESET`.
1819
*/
1920
@Env('N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES')
2021
blockFileAccessToN8nFiles: boolean = true;

packages/@n8n/config/test/config.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ describe('GlobalConfig', () => {
317317
cert: '',
318318
},
319319
security: {
320-
restrictFileAccessTo: '',
320+
restrictFileAccessTo: '~/.n8n-files',
321321
blockFileAccessToN8nFiles: true,
322322
daysAbandonedWorkflow: 90,
323323
contentSecurityPolicy: '{}',

packages/core/src/execution-engine/node-execution-context/utils/file-system-helper-functions.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isContainedWithin, safeJoinPath } from '@n8n/backend-common';
2+
import { SecurityConfig } from '@n8n/config';
23
import { Container } from '@n8n/di';
34
import type { FileSystemHelperFunctions, INode } from 'n8n-workflow';
45
import { NodeOperationError } from 'n8n-workflow';
@@ -8,28 +9,29 @@ import {
89
writeFile as fsWriteFile,
910
realpath as fsRealpath,
1011
} from 'node:fs/promises';
12+
import { homedir } from 'node:os';
1113
import { resolve } from 'node:path';
1214

1315
import {
1416
BINARY_DATA_STORAGE_PATH,
1517
BLOCK_FILE_ACCESS_TO_N8N_FILES,
1618
CONFIG_FILES,
1719
CUSTOM_EXTENSION_ENV,
18-
RESTRICT_FILE_ACCESS_TO,
1920
UM_EMAIL_TEMPLATES_INVITE,
2021
UM_EMAIL_TEMPLATES_PWRESET,
2122
} from '@/constants';
2223
import { InstanceSettings } from '@/instance-settings';
2324

2425
const getAllowedPaths = () => {
25-
const restrictFileAccessTo = process.env[RESTRICT_FILE_ACCESS_TO];
26-
if (!restrictFileAccessTo) {
27-
return [];
28-
}
26+
const { restrictFileAccessTo } = Container.get(SecurityConfig);
27+
if (restrictFileAccessTo === '') return [];
28+
2929
const allowedPaths = restrictFileAccessTo
3030
.split(';')
3131
.map((path) => path.trim())
32-
.filter((path) => path);
32+
.filter((path) => path)
33+
.map((path) => (path.startsWith('~') ? path.replace('~', homedir()) : path));
34+
3335
return allowedPaths;
3436
};
3537

0 commit comments

Comments
 (0)