fix(design): create the OpenAI key file owner-only, closing the write-then-chmod race

saveApiKey wrote ~/.gstack/openai.json at the default umask and tightened to
0600 afterwards, leaving the API key briefly world-readable between write and
chmod (CWE-377/367). Pass mode 0o600 at create; the trailing chmodSync stays
as a backstop to tighten a pre-existing loose file.

Contributed by @bunlongheng (PR #2468).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-14 20:20:58 -07:00
co-authored by Claude Fable 5
parent a03f571147
commit a2ae26d44c
2 changed files with 25 additions and 1 deletions
+4 -1
View File
@@ -111,7 +111,10 @@ export function describeApiKeySource(resolution: ApiKeyResolution): string {
export function saveApiKey(key: string): void {
const dir = path.dirname(configPath());
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(configPath(), JSON.stringify({ api_key: key }, null, 2));
// Create the file owner-only up front so the API key is never briefly
// world/group-readable in the window between write and chmod. The trailing
// chmodSync is kept as a backstop to tighten a pre-existing loose file.
fs.writeFileSync(configPath(), JSON.stringify({ api_key: key }, null, 2), { mode: 0o600 });
fs.chmodSync(configPath(), 0o600);
}