security: tighten config-dir perms and validate plugin scope argv

Merged
JE
4mo ago
+4628-182

Tighten config-dir perms and validate plugin --scope argv

(Threats: T3 other local users on a shared machine; T6 untrusted data into exec args.)

  • 0700 global config dir — the skill-refresh and update-notice bootstrap created ~/.config/basecamp/ at 0755, and it runs before the auth store, leaving a dir that can hold credentials.json world-listable. Changed both bootstrap MkdirAlls to 0o700 and added a one-time os.Chmod(GlobalConfigDir(), 0o700) in root.go to tighten dirs created by older versions. (Intentionally-world-readable ~/.agents/~/.claude/skills dirs left at 0755.)
  • Plugin scope whitelist — the scope read from installed_plugins.json was appended after --scope in claude plugin uninstall unvalidated; a --leading value injects a flag. Now whitelisted to {user, project, local}.

Tests

TestValidPluginScope.


Part 5/6 of the stacked security series. Base: security/04-config-trust-gating.

šŸ“š Stack (merge bottom-up)

  1. #478 — reject foreign-host URLs in api (base main)
  2. #479 — strip ANSI/OSC escapes from output
  3. #480 — harden OAuth discovery / token endpoints
  4. #481 — close config trust-boundary gaps + completion gate
  5. #482 — tighten config-dir perms + plugin scope argv
  6. #483 — bump toolchain/x-net + CI gates

Each is independent except #482 depends on #481 (shared root.go). #478 can land first/alone.