mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 12:09:03 +00:00
fix(persist): accurate symlink guard message on backup read
The guard fires on the backup READ step; use a typed ConfigError whose message matches the actual step (refusing to read), not a misleading 'refusing to write'.
This commit is contained in:
1 parent
9d5b33382b
commit
e4c91d2853
1 file changed
+9
@@ -11,6 +11,7 @@ import * as path from 'path';
|
||||
import { initUI, header, color, dim, ok, fail, warn, info } from '../../utils/ui';
|
||||
import { InteractivePrompt } from '../../utils/prompt';
|
||||
import { getClaudeSettingsPath } from '../../utils/claude-config-path';
|
||||
import { ConfigError } from '../../errors';
|
||||
import {
|
||||
formatDisplayPath,
|
||||
getClaudeSettingsDisplayPath,
|
||||
@@ -86,6 +87,14 @@ export async function createBackup(): Promise<string> {
|
||||
throw new Error('No settings.json to backup');
|
||||
}
|
||||
|
||||
// Guard: refuse to read a symlinked settings.json (TOCTOU mitigation on backup read).
|
||||
if (await isSymlinkAsync(settingsPath)) {
|
||||
throw new ConfigError(
|
||||
'settings.json is a symlink - refusing to read for backup for security',
|
||||
settingsPath
|
||||
);
|
||||
}
|
||||
|
||||
const settingsContent = await readFileUtf8NoFollow(settingsPath);
|
||||
|
||||
const now = new Date();
|
||||
|
||||
Reference in new issue
Block a user