mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
fix(core): Prevent XSS via static cache dir (#10339)
Some checks failed
Test Master / install-and-build (push) Has been cancelled
Test Master / Unit tests (18.x) (push) Has been cancelled
Test Master / Unit tests (20.x) (push) Has been cancelled
Test Master / Unit tests (22.4) (push) Has been cancelled
Test Master / Lint (push) Has been cancelled
Test Master / Notify Slack on failure (push) Has been cancelled
Some checks failed
Test Master / install-and-build (push) Has been cancelled
Test Master / Unit tests (18.x) (push) Has been cancelled
Test Master / Unit tests (20.x) (push) Has been cancelled
Test Master / Unit tests (22.4) (push) Has been cancelled
Test Master / Lint (push) Has been cancelled
Test Master / Notify Slack on failure (push) Has been cancelled
This commit is contained in:
parent
1cf48cc301
commit
4f392b5e3e
|
@ -2,6 +2,16 @@
|
||||||
|
|
||||||
This list shows all the versions which include breaking changes and how to upgrade.
|
This list shows all the versions which include breaking changes and how to upgrade.
|
||||||
|
|
||||||
|
## 1.55.0
|
||||||
|
|
||||||
|
### What changed?
|
||||||
|
|
||||||
|
The `N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES` environment variable now also blocks access to n8n's static cache directory at `~/.cache/n8n/public`.
|
||||||
|
|
||||||
|
### When is action necessary?
|
||||||
|
|
||||||
|
If you are writing to or reading from a file at n8n's static cache directory via a node, e.g. `Read/Write Files from Disk`, please update your node to use a different path.
|
||||||
|
|
||||||
## 1.52.0
|
## 1.52.0
|
||||||
|
|
||||||
### What changed?
|
### What changed?
|
||||||
|
|
|
@ -341,7 +341,7 @@ export const schema = {
|
||||||
env: 'N8N_RESTRICT_FILE_ACCESS_TO',
|
env: 'N8N_RESTRICT_FILE_ACCESS_TO',
|
||||||
},
|
},
|
||||||
blockFileAccessToN8nFiles: {
|
blockFileAccessToN8nFiles: {
|
||||||
doc: 'If set to true it will block access to all files in the ".n8n" directory and user defined config files.',
|
doc: 'If set to true it will block access to all files in the ".n8n" directory, the static cache dir at ~/.cache/n8n/public, and user defined config files.',
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
env: 'N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES',
|
env: 'N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES',
|
||||||
|
|
|
@ -3326,7 +3326,7 @@ const getAllowedPaths = () => {
|
||||||
return allowedPaths;
|
return allowedPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isFilePathBlocked(filePath: string): boolean {
|
export function isFilePathBlocked(filePath: string): boolean {
|
||||||
const allowedPaths = getAllowedPaths();
|
const allowedPaths = getAllowedPaths();
|
||||||
const resolvedFilePath = path.resolve(filePath);
|
const resolvedFilePath = path.resolve(filePath);
|
||||||
const blockFileAccessToN8nFiles = process.env[BLOCK_FILE_ACCESS_TO_N8N_FILES] !== 'false';
|
const blockFileAccessToN8nFiles = process.env[BLOCK_FILE_ACCESS_TO_N8N_FILES] !== 'false';
|
||||||
|
@ -3342,10 +3342,10 @@ function isFilePathBlocked(filePath: string): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//restrict access to .n8n folder and other .env config related paths
|
//restrict access to .n8n folder, ~/.cache/n8n/public, and other .env config related paths
|
||||||
if (blockFileAccessToN8nFiles) {
|
if (blockFileAccessToN8nFiles) {
|
||||||
const { n8nFolder } = Container.get(InstanceSettings);
|
const { n8nFolder, staticCacheDir } = Container.get(InstanceSettings);
|
||||||
const restrictedPaths = [n8nFolder];
|
const restrictedPaths = [n8nFolder, staticCacheDir];
|
||||||
|
|
||||||
if (process.env[CONFIG_FILES]) {
|
if (process.env[CONFIG_FILES]) {
|
||||||
restrictedPaths.push(...process.env[CONFIG_FILES].split(','));
|
restrictedPaths.push(...process.env[CONFIG_FILES].split(','));
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
copyInputItems,
|
copyInputItems,
|
||||||
ensureType,
|
ensureType,
|
||||||
getBinaryDataBuffer,
|
getBinaryDataBuffer,
|
||||||
|
isFilePathBlocked,
|
||||||
parseIncomingMessage,
|
parseIncomingMessage,
|
||||||
parseRequestObject,
|
parseRequestObject,
|
||||||
proxyRequestToAxios,
|
proxyRequestToAxios,
|
||||||
|
@ -34,6 +35,7 @@ import { join } from 'path';
|
||||||
import Container from 'typedi';
|
import Container from 'typedi';
|
||||||
import type { Agent } from 'https';
|
import type { Agent } from 'https';
|
||||||
import toPlainObject from 'lodash/toPlainObject';
|
import toPlainObject from 'lodash/toPlainObject';
|
||||||
|
import { InstanceSettings } from '@/InstanceSettings';
|
||||||
|
|
||||||
const temporaryDir = mkdtempSync(join(tmpdir(), 'n8n'));
|
const temporaryDir = mkdtempSync(join(tmpdir(), 'n8n'));
|
||||||
|
|
||||||
|
@ -663,3 +665,11 @@ describe('NodeExecuteFunctions', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isFilePathBlocked', () => {
|
||||||
|
test('should return true for static cache dir', () => {
|
||||||
|
const filePath = Container.get(InstanceSettings).staticCacheDir;
|
||||||
|
|
||||||
|
expect(isFilePathBlocked(filePath)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue