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.
|
* 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 { join, dirname } from 'path';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { logger } from '../utils/logger.js';
|
import { logger } from '../utils/logger.js';
|
||||||
@@ -132,10 +132,13 @@ export function loadClaudeMemEnv(): ClaudeMemEnv {
|
|||||||
*/
|
*/
|
||||||
export function saveClaudeMemEnv(env: ClaudeMemEnv): void {
|
export function saveClaudeMemEnv(env: ClaudeMemEnv): void {
|
||||||
try {
|
try {
|
||||||
// Ensure directory exists
|
// Ensure directory exists with restricted permissions (owner only)
|
||||||
if (!existsSync(DATA_DIR)) {
|
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
|
// Load existing to preserve any extra keys
|
||||||
const existing = existsSync(ENV_FILE_PATH)
|
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) {
|
} catch (error) {
|
||||||
logger.error('ENV', 'Failed to save .env file', { path: ENV_FILE_PATH }, error as Error);
|
logger.error('ENV', 'Failed to save .env file', { path: ENV_FILE_PATH }, error as Error);
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
Reference in New Issue
Block a user