Skip to content

fix: prevent sudo-caused file ownership corruption#59

Merged
nmhjklnm merged 4 commits intomasterfrom
fix/sudo-permission-corruption
Apr 1, 2026
Merged

fix: prevent sudo-caused file ownership corruption#59
nmhjklnm merged 4 commits intomasterfrom
fix/sudo-permission-corruption

Conversation

@nmhjklnm
Copy link
Copy Markdown
Owner

@nmhjklnm nmhjklnm commented Apr 1, 2026

Problem

Running sudo cac <env> could corrupt ~/.cac/ file ownership:

  • _ensure_initialized() runs as root, cp commands overwrite fingerprint-hook.js / relay.js as root-owned files
  • If root's umask is 077, files become mode 600 (unreadable by normal user)
  • Subsequent claude invocations silently exit: the wrapper has set -e and fails when bun/node tries to --preload / --require an unreadable file

Symptoms: cp: ~/.cac/fingerprint-hook.js: Permission denied on cac <env>, claude silently exits.

Fix

cmd_setup.sh

  • Print warning when running as root
  • Add 2>/dev/null || true to both cp lines (was missing, unlike _write_dns_guard_js which already had || true)

templates.sh (wrapper)

  • Change [[ -f ... ]][[ -r ... ]] for fingerprint-hook.js, cac-dns-guard.js, blocked_hosts
  • -r checks readability, not just existence — root-owned 600 files exist but can't be read, skipping injection is safe graceful degradation vs. silent crash

Test

# Simulate the corruption
sudo touch ~/.cac/fingerprint-hook.js  # or sudo cac <env> on a version bump
claude  # before fix: silent exit; after fix: starts normally (skips hook injection)
cac <env>  # before fix: cp error; after fix: warning printed, activation succeeds

…er claude

Running `sudo cac` could rewrite ~/.cac/ files as root, causing the claude
wrapper to silently exit (set -e + unreadable root-owned JS files).

- cmd_setup.sh: add warning when running as root; protect cp commands with
  `|| true` so init doesn't abort on existing root-owned files
- templates.sh: use `-r` (readable) instead of `-f` (exists) when injecting
  fingerprint-hook.js and cac-dns-guard.js into NODE_OPTIONS/BUN_OPTIONS,
  so unreadable root-owned files are skipped gracefully instead of crashing
After 'sudo cac' runs, hook files (fingerprint-hook.js, relay.js,
cac-dns-guard.js, blocked_hosts) become root-owned. On next normal-user
run, cp/write fails silently (beta.2 fix), leaving old root-owned
versions in place. Those files ARE readable (mode 644), so they get
loaded via NODE_OPTIONS/BUN_OPTIONS but may be stale or corrupted.

Fix: rm -f the target before writing. User owns ~/.cac/ directory so
can always unlink files in it even if root-owned (rm needs write on
parent dir, not on the file itself). This self-heals on next cac run.

Version: 1.5.2-beta.3
Faking userID in .claude.json provided minimal protection (account_uuid
still exposed via OAuth) but caused user_id mismatch errors after /login.

Changes:
- env create: no longer generates fake user_id or writes to .claude.json
- env activate: remove _update_claude_json_user_id call
- env check: auto-sync env/user_id from .claude.json (real value wins),
  never report mismatch error
- Bump version from 1.5.2-beta.3 to 1.5.2
- Update changelog (EN + ZH) with both fixes
- Correct v1.5.0 user_id entry to reflect new behavior
@nmhjklnm nmhjklnm merged commit 99c9782 into master Apr 1, 2026
@nmhjklnm nmhjklnm deleted the fix/sudo-permission-corruption branch April 1, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant