fix: restrict ~/.claude-mem/.env permissions to owner-only (0600) (#1770)
* fix: restrict .env file permissions to owner-only (0600) API keys stored in ~/.claude-mem/.env were created without explicit permissions, defaulting to umask-dependent mode. On systems with a permissive umask (e.g. 0022), the file would be world-readable. - Set directory permissions to 0700 on creation - Set file permissions to 0600 via writeFileSync mode option - Call chmodSync after write to fix permissions on pre-existing files Signed-off-by: Jochen Meyer * fix: also restrict pre-existing directory permissions to 0700 The initial fix only set directory mode on creation. Pre-existing ~/.claude-mem/ directories from earlier installs remained world-readable. Add chmodSync for the directory alongside the existing file chmod, and document the Windows limitation (ACLs, not POSIX permissions). --------- Signed-off-by: Jochen Meyer
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* causing memory operations to bill personal API accounts instead of CLI subscription.
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
||||
import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { logger } from '../utils/logger.js';
|
||||
@@ -132,10 +132,13 @@ export function loadClaudeMemEnv(): ClaudeMemEnv {
|
||||
*/
|
||||
export function saveClaudeMemEnv(env: ClaudeMemEnv): void {
|
||||
try {
|
||||
// Ensure directory exists
|
||||
// Ensure directory exists with restricted permissions (owner only)
|
||||
if (!existsSync(DATA_DIR)) {
|
||||
mkdirSync(DATA_DIR, { recursive: true });
|
||||
mkdirSync(DATA_DIR, { recursive: true, mode: 0o700 });
|
||||
}
|
||||
// Fix permissions on pre-existing directories (mode: is only applied on creation)
|
||||
// Note: On Windows, chmod has no effect — permissions are controlled via ACLs.
|
||||
chmodSync(DATA_DIR, 0o700);
|
||||
|
||||
// Load existing to preserve any extra keys
|
||||
const existing = existsSync(ENV_FILE_PATH)
|
||||
@@ -175,7 +178,11 @@ export function saveClaudeMemEnv(env: ClaudeMemEnv): void {
|
||||
}
|
||||
}
|
||||
|
||||
writeFileSync(ENV_FILE_PATH, serializeEnvFile(updated), 'utf-8');
|
||||
writeFileSync(ENV_FILE_PATH, serializeEnvFile(updated), { encoding: 'utf-8', mode: 0o600 });
|
||||
// Explicitly set permissions in case the file already existed before this fix.
|
||||
// writeFileSync's mode option only applies on file creation (O_CREAT), not on overwrites.
|
||||
// Note: On Windows, chmod has no effect — permissions are controlled via ACLs.
|
||||
chmodSync(ENV_FILE_PATH, 0o600);
|
||||
} catch (error) {
|
||||
logger.error('ENV', 'Failed to save .env file', { path: ENV_FILE_PATH }, error as Error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user