mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(core): Don't reveal whether files exists if they're not within allowed paths (#18480)
This commit is contained in:
@@ -223,6 +223,19 @@ describe('getFileSystemHelperFunctions', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should not reveal if file exists if it is within restricted path', async () => {
|
||||
process.env[RESTRICT_FILE_ACCESS_TO] = '/allowed/path';
|
||||
|
||||
const error = new Error('ENOENT');
|
||||
// @ts-expect-error undefined property
|
||||
error.code = 'ENOENT';
|
||||
(fsAccess as jest.Mock).mockRejectedValueOnce(error);
|
||||
|
||||
await expect(helperFunctions.createReadStream('/blocked/path')).rejects.toThrow(
|
||||
'Access to the file is not allowed',
|
||||
);
|
||||
});
|
||||
|
||||
it('should create a read stream if file access is permitted', async () => {
|
||||
const filePath = '/allowed/path';
|
||||
(fsAccess as jest.Mock).mockResolvedValueOnce({});
|
||||
|
||||
@@ -38,9 +38,8 @@ export async function isFilePathBlocked(filePath: string): Promise<boolean> {
|
||||
let resolvedFilePath = '';
|
||||
try {
|
||||
resolvedFilePath = await fsRealpath(filePath);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (error.code === 'ENOENT') {
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
||||
resolvedFilePath = resolve(filePath);
|
||||
} else {
|
||||
throw error;
|
||||
@@ -64,6 +63,14 @@ export async function isFilePathBlocked(filePath: string): Promise<boolean> {
|
||||
|
||||
export const getFileSystemHelperFunctions = (node: INode): FileSystemHelperFunctions => ({
|
||||
async createReadStream(filePath) {
|
||||
if (await isFilePathBlocked(filePath.toString())) {
|
||||
const allowedPaths = getAllowedPaths();
|
||||
const message = allowedPaths.length ? ` Allowed paths: ${allowedPaths.join(', ')}` : '';
|
||||
throw new NodeOperationError(node, `Access to the file is not allowed.${message}`, {
|
||||
level: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await fsAccess(filePath);
|
||||
} catch (error) {
|
||||
@@ -76,13 +83,7 @@ export const getFileSystemHelperFunctions = (node: INode): FileSystemHelperFunct
|
||||
})
|
||||
: error;
|
||||
}
|
||||
if (await isFilePathBlocked(filePath as string)) {
|
||||
const allowedPaths = getAllowedPaths();
|
||||
const message = allowedPaths.length ? ` Allowed paths: ${allowedPaths.join(', ')}` : '';
|
||||
throw new NodeOperationError(node, `Access to the file is not allowed.${message}`, {
|
||||
level: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
return createReadStream(filePath);
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user