Skip to content

Commit 991f03d

Browse files
EthanGuo-coderxxiaoxiong
authored andcommitted
fix(daemon): reject path-traversal ids in readPromptTemplate (nexu-io#5027)
1 parent 406cb7a commit 991f03d

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

apps/daemon/src/prompt-templates.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ export async function listPromptTemplates(root: string): Promise<PromptTemplate[
7272

7373
export async function readPromptTemplate(root: string, surface: string, id: string): Promise<PromptTemplate | null> {
7474
if (!isPromptTemplateSurface(surface)) return null;
75-
const filePath = path.join(root, surface, `${id}.json`);
75+
const dir = path.join(root, surface);
76+
const filePath = path.join(dir, `${id}.json`);
77+
// `id` comes straight from the request path; a value like `../secret` would
78+
// resolve outside the surface directory. Only read a direct child of it.
79+
if (path.dirname(filePath) !== dir) return null;
7680
try {
7781
const raw = await readFile(filePath, 'utf8');
7882
const parsed = JSON.parse(raw);

apps/daemon/tests/prompt-templates.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,15 @@ describe('readPromptTemplate', () => {
175175
);
176176
expect(await readPromptTemplate(root, 'image', 'bad')).toBeNull();
177177
});
178+
179+
it('returns null for a path-traversal id instead of reading outside the surface dir', async () => {
180+
// `id` arrives straight from the request path (`/api/prompt-templates/:surface/:id`,
181+
// where a percent-encoded `..%2f` decodes back to `../`). Plant a valid template one
182+
// level above the surface dir and confirm a traversal id can't resolve to it.
183+
await writeFile(
184+
path.join(root, 'secret.json'),
185+
JSON.stringify(makeTemplate({ id: '../secret' })),
186+
);
187+
expect(await readPromptTemplate(root, 'image', '../secret')).toBeNull();
188+
});
178189
});

0 commit comments

Comments
 (0)