Skip to content

Commit c8bac1f

Browse files
authored
fix: improve filename path sanitization (#1967)
1 parent f25fdf4 commit c8bac1f

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

src/main/files.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,14 @@ export async function saveFiles(
208208
filePath: string,
209209
files: Files,
210210
) {
211-
console.log(`saveFiddleWithTransforms: Asked to save to ${filePath}`);
211+
console.log(`saveFiles: Asked to save to ${filePath}`);
212212

213213
for (const [fileName, content] of files) {
214+
if (!isSafeDataName(fileName)) {
215+
console.warn(`saveFiles: rejected unsafe filename: ${fileName}`);
216+
continue;
217+
}
218+
214219
const savePath = path.join(filePath, fileName);
215220

216221
// If the file has content, save it to disk. If there's no

src/utils/editor-utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,10 @@ export function getSuffix(filename: string) {
4545
}
4646

4747
export function isSupportedFile(filename: string): filename is EditorId {
48+
// Reject any name containing a path separator
49+
if (/[/\\]/.test(filename)) {
50+
return false;
51+
}
52+
4853
return /\.(css|html|cjs|js|mjs|json)$/i.test(filename);
4954
}

tests/utils/editor-utils.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ describe('editor-utils', () => {
3030
expect(isSupportedFile(id)).toBe(true);
3131
}
3232
});
33+
34+
it('rejects path traversal and absolute paths', () => {
35+
expect(isSupportedFile('../../../../tmp/evil.js')).toBe(false);
36+
expect(isSupportedFile('/tmp/evil.js')).toBe(false);
37+
expect(isSupportedFile('foo/bar.js')).toBe(false);
38+
expect(isSupportedFile('..\\..\\evil.js')).toBe(false);
39+
});
3340
});
3441

3542
describe('getSuffix', () => {

0 commit comments

Comments
 (0)