From 49f3115429fd465f5292ef06785c00a210ad029e Mon Sep 17 00:00:00 2001 From: RomanDavydchuk Date: Wed, 6 Aug 2025 12:51:23 +0300 Subject: [PATCH] fix(core): Handle non-existing files when checking if it is a symlink (#18010) --- .../file-system-helper-functions.test.ts | 20 +++++++++++++++++++ .../utils/file-system-helper-functions.ts | 13 +++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/core/src/execution-engine/node-execution-context/utils/__tests__/file-system-helper-functions.test.ts b/packages/core/src/execution-engine/node-execution-context/utils/__tests__/file-system-helper-functions.test.ts index c952767160b..5b481ab7795 100644 --- a/packages/core/src/execution-engine/node-execution-context/utils/__tests__/file-system-helper-functions.test.ts +++ b/packages/core/src/execution-engine/node-execution-context/utils/__tests__/file-system-helper-functions.test.ts @@ -160,6 +160,26 @@ describe('isFilePathBlocked', () => { ); expect(await isFilePathBlocked(allowedPath)).toBe(true); }); + + it('should handle non-existent file when it is allowed', async () => { + const filePath = '/non/existent/file'; + const error = new Error('ENOENT'); + // @ts-expect-error undefined property + error.code = 'ENOENT'; + (fsRealpath as jest.Mock).mockRejectedValueOnce(error); + expect(await isFilePathBlocked(filePath)).toBe(false); + }); + + it('should handle non-existent file when it is not allowed', async () => { + const filePath = '/non/existent/file'; + const allowedPath = '/some/allowed/path'; + process.env[RESTRICT_FILE_ACCESS_TO] = allowedPath; + const error = new Error('ENOENT'); + // @ts-expect-error undefined property + error.code = 'ENOENT'; + (fsRealpath as jest.Mock).mockRejectedValueOnce(error); + expect(await isFilePathBlocked(filePath)).toBe(true); + }); }); describe('getFileSystemHelperFunctions', () => { diff --git a/packages/core/src/execution-engine/node-execution-context/utils/file-system-helper-functions.ts b/packages/core/src/execution-engine/node-execution-context/utils/file-system-helper-functions.ts index 60dc26460db..61943b1243e 100644 --- a/packages/core/src/execution-engine/node-execution-context/utils/file-system-helper-functions.ts +++ b/packages/core/src/execution-engine/node-execution-context/utils/file-system-helper-functions.ts @@ -8,6 +8,7 @@ import { writeFile as fsWriteFile, realpath as fsRealpath, } from 'node:fs/promises'; +import { resolve } from 'node:path'; import { BINARY_DATA_STORAGE_PATH, @@ -34,7 +35,17 @@ const getAllowedPaths = () => { export async function isFilePathBlocked(filePath: string): Promise { const allowedPaths = getAllowedPaths(); - const resolvedFilePath = await fsRealpath(filePath); + let resolvedFilePath = ''; + try { + resolvedFilePath = await fsRealpath(filePath); + } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (error.code === 'ENOENT') { + resolvedFilePath = resolve(filePath); + } else { + throw error; + } + } const blockFileAccessToN8nFiles = process.env[BLOCK_FILE_ACCESS_TO_N8N_FILES] !== 'false'; const restrictedPaths = blockFileAccessToN8nFiles ? getN8nRestrictedPaths() : [];