mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-07-07 06:02:43 +08:00
fix: address code scanning findings
- enforce a second image trust boundary in the provider builders: buildClaudeUserContent/buildCodexInputItems only accept files inside the upload store or the run's working directory (CodeQL path injection) - drop an always-true selectedProject check in handleSubmit - remove the unused resume option from spawnCursor
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
appendImagesInputTag,
|
||||
buildClaudeUserContent,
|
||||
buildCodexInputItems,
|
||||
isAllowedImageSourcePath,
|
||||
normalizeImageDescriptors,
|
||||
parseImagesInputTag,
|
||||
resolveImageMediaType,
|
||||
@@ -186,3 +187,31 @@ test('buildCodexInputItems emits text plus absolute local_image paths', () => {
|
||||
assert.ok(path.isAbsolute(imageItem.path));
|
||||
assert.equal(imageItem.path, path.resolve(cwd, '.cloudcli/assets/pic.jpg'));
|
||||
});
|
||||
|
||||
test('isAllowedImageSourcePath only accepts the upload store and the run cwd', () => {
|
||||
const cwd = path.join(os.tmpdir(), 'some-project');
|
||||
const uploadStore = path.join(os.homedir(), '.cloudcli', 'assets');
|
||||
|
||||
assert.equal(isAllowedImageSourcePath(path.join(uploadStore, 'shot.png'), cwd), true);
|
||||
assert.equal(isAllowedImageSourcePath(path.join(cwd, 'docs', 'diagram.png'), cwd), true);
|
||||
|
||||
assert.equal(isAllowedImageSourcePath(path.join(os.homedir(), '.ssh', 'id_rsa'), cwd), false);
|
||||
assert.equal(isAllowedImageSourcePath(path.join(cwd, '..', 'other-project', 'x.png'), cwd), false);
|
||||
// The roots themselves are directories, not readable image files.
|
||||
assert.equal(isAllowedImageSourcePath(cwd, cwd), false);
|
||||
});
|
||||
|
||||
test('provider builders refuse descriptors outside the allowed roots', async () => {
|
||||
const cwd = path.join(os.tmpdir(), 'codex-project');
|
||||
const outsidePath = path.join(os.homedir(), '.ssh', 'id_rsa.png');
|
||||
|
||||
const codexItems = buildCodexInputItems('prompt', [{ path: outsidePath }], cwd);
|
||||
assert.deepEqual(codexItems, [{ type: 'text', text: 'prompt' }]);
|
||||
|
||||
const claudeContent = await buildClaudeUserContent(
|
||||
'prompt',
|
||||
[{ path: outsidePath, mimeType: 'image/png' }],
|
||||
cwd,
|
||||
);
|
||||
assert.deepEqual(claudeContent, [{ type: 'text', text: 'prompt' }]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user