diff --git a/packages/backend-common/src/paths.test.ts b/packages/backend-common/src/paths.test.ts index a9a557c8fe..94b96580e9 100644 --- a/packages/backend-common/src/paths.test.ts +++ b/packages/backend-common/src/paths.test.ts @@ -16,6 +16,7 @@ import { createMockDirectory } from '@backstage/backend-test-utils'; import { resolveSafeChildPath } from './paths'; +import fs from 'fs/promises'; describe('paths', () => { describe('resolveSafeChildPath', () => { @@ -41,9 +42,9 @@ describe('paths', () => { ); }); - it('should resolve to the full path if the target is inside the directory', () => { + it('should resolve to the full path if the target is inside the directory', async () => { expect(resolveSafeChildPath(workspacePath, './README.md')).toEqual( - `${workspacePath}/README.md`, + `${await fs.realpath(workspacePath)}/README.md`, ); }); diff --git a/packages/backend-common/src/paths.ts b/packages/backend-common/src/paths.ts index 0e784a60db..b5d4b331fd 100644 --- a/packages/backend-common/src/paths.ts +++ b/packages/backend-common/src/paths.ts @@ -63,9 +63,10 @@ export function resolvePackagePath(name: string, ...paths: string[]) { * @returns A path that is guaranteed to point to or within the base path. */ export function resolveSafeChildPath(base: string, path: string): string { - const targetPath = resolvePath(base, path); + const resolvedBasePath = resolveRealPath(base); + const targetPath = resolvePath(resolvedBasePath, path); - if (!isChildPath(resolveRealPath(base), resolveRealPath(targetPath))) { + if (!isChildPath(resolvedBasePath, resolveRealPath(targetPath))) { throw new NotAllowedError( 'Relative path is not allowed to refer to a directory outside its parent', );