chmod the mcp config, because writeFileSync's mode never fires on it

host measured what df450318 assumed. writeFileSync passes `mode` to open(2),
which honours it only when it CREATES the file — on an existing one the call
truncates and writes and the mode is ignored. So the fix worked on a fresh
install and did nothing at all on every box already leaking, which is the whole
exposed population. Verified on production after the commit: still 0644, still
readable by a member.

That is worse than not fixing it, because it closes the ticket. The exposure
would have continued through every bootstrap with nobody watching for it.

chmodSync after the write, both kept — the creation mode closes the window
between open and chmod on a fresh write, and chmodSync is what reaches an
install that is already leaking. Commented so neither is deleted as redundant.

Still not closed on disk: the file is the owner's to chmod and the token is
theirs to rotate, and no commit reaches either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 22:45:34 +00:00
co-authored by Claude Opus 5
parent fe30164452
commit 3e0daee611
2 changed files with 48 additions and 2 deletions
+9 -2
View File
@@ -1,4 +1,4 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { homedir } from 'node:os';
import type { SidecarCommand, SidecarEvent } from '../protocol';
@@ -137,7 +137,14 @@ function generateMcpConfig(): string {
// The mode is only the half of this that is code. The directory chain above it still allows traversal and
// listing, and a token that has been world-readable stays compromised however the file is chmod'ed
// afterwards — it has to be rotated. Both are the owner's, and both are written up in COMMS.
writeFileSync(join(contextDir, 'mcp-host.json'), JSON.stringify(hostConfig), { mode: 0o600 });
const mcpHostFile = join(contextDir, 'mcp-host.json');
writeFileSync(mcpHostFile, JSON.stringify(hostConfig), { mode: 0o600 });
// BOTH, and neither is redundant. `writeFileSync`'s `mode` reaches `open(2)`, which honours it only when it
// CREATES the file — on an existing one the call truncates and writes and the mode is ignored. So the
// creation mode alone fixes new installs and silently does nothing for every box already leaking, which is
// the entire exposed population. `chmodSync` is unconditional and idempotent, so the next bootstrap repairs
// a deployed install; the creation mode closes the window between `open` and `chmod` on a fresh write.
chmodSync(mcpHostFile, 0o600);
return join(contextDir, 'mcp-host.json');
}