src/lib/auth.ts:59:
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
No mode argument, so ~/.config/partiful/auth.json is created 0644 under a typical umask — group- and world-readable.
The file holds apiKey, refreshToken, accessToken, tokenExpiry and userId. The refresh token is long-lived and sufficient to mint new access tokens, so this is a durable credential sitting at default permissions.
Fix
- Create the file at
0o600 (pass { mode: 0o600 } — note mode is subject to umask, so verify with an explicit fs.chmodSync where it matters).
- Ensure the containing directory is
0o700.
- Write atomically (temp file + rename) so a crash mid-write can't leave a truncated or world-readable credential file.
- Repair pre-existing files on load — anyone who has already authenticated has a 0644 file today, and a fix that only applies to new writes leaves them exposed.
A post-hoc chmod after writeFileSync is not sufficient on its own: it leaves a window where the file exists with permissive bits.
Follow-up
Consider a partiful doctor check that warns when the config file or directory is group/world readable.
src/lib/auth.ts:59:No
modeargument, so~/.config/partiful/auth.jsonis created 0644 under a typical umask — group- and world-readable.The file holds
apiKey,refreshToken,accessToken,tokenExpiryanduserId. The refresh token is long-lived and sufficient to mint new access tokens, so this is a durable credential sitting at default permissions.Fix
0o600(pass{ mode: 0o600 }— notemodeis subject to umask, so verify with an explicitfs.chmodSyncwhere it matters).0o700.A post-hoc
chmodafterwriteFileSyncis not sufficient on its own: it leaves a window where the file exists with permissive bits.Follow-up
Consider a
partiful doctorcheck that warns when the config file or directory is group/world readable.