diff --git a/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.test.ts b/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.test.ts index ca71dfc668..d6e1370bf7 100644 --- a/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.test.ts +++ b/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.test.ts @@ -243,6 +243,28 @@ describe('loadPortableTemplateConfig', () => { ); }); + it('should throw an error if template point is absolute', async () => { + mockDir.setContent({ + 'package.json': JSON.stringify({ + backstage: { + cli: { + new: { + templates: ['/invalid'], + }, + }, + }, + }), + }); + + await expect( + loadPortableTemplateConfig({ + packagePath: mockDir.resolve('package.json'), + }), + ).rejects.toThrow( + "Failed to load template definition '/invalid'; caused by Error: Template target may not be an absolute path", + ); + }); + it('should handle missing backstage.new configuration', async () => { mockDir.setContent({ 'package.json': JSON.stringify({}), diff --git a/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.ts b/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.ts index 7cca6ba836..292f57ca0b 100644 --- a/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.ts +++ b/packages/cli/src/lib/new/preparation/loadPortableTemplateConfig.ts @@ -15,7 +15,7 @@ */ import fs from 'fs-extra'; -import { resolve as resolvePath, dirname } from 'node:path'; +import { resolve as resolvePath, dirname, isAbsolute } from 'node:path'; import { paths } from '../../paths'; import { defaultTemplates } from '../defaultTemplates'; import { @@ -126,6 +126,10 @@ export async function loadPortableTemplateConfig( } function resolveLocalTemplatePath(pointer: string, basePath: string): string { + if (isAbsolute(pointer)) { + throw new Error(`Template target may not be an absolute path`); + } + if (pointer.startsWith('.')) { return resolvePath(basePath, pointer, TEMPLATE_FILE_NAME); }