Skip to content

Security review #15

Description

@lionello

Critical issues:

  1. Default full autonomy
    skipPermissions = true means --dangerously-skip-permissions by default. That is the biggest red flag. Any agent compromise becomes arbitrary command execution as that Unix user.
  2. Remote control enabled by default
    remoteControl = true exposes the session to Claude apps by default. That expands the control plane. Should be opt-in, not default.
  3. Normal users, persistent homes
    It creates real isNormalUser accounts with writable /home/<name>. Good for isolation from root, bad for persistence and lateral movement if secrets, SSH keys, git creds, or dotfiles accumulate.
  4. Passwordless sudo with SETENV
    The sudo allowlist supports NOPASSWD and SETENV. SETENV is risky because env vars can alter behavior of many binaries/scripts. I’d remove it unless absolutely needed.
  5. Secrets via EnvironmentFile
    Better than Nix store, but services get tokens as env vars. Child processes can inherit them; tools may leak them to logs, crash dumps, process inspection by same user, shell history, etc.
  6. Token dir is 0755
    /etc/claude-box is world-readable/traversable by default. Files may be 600, but the module does not enforce file ownership/mode for ${name}.env. Easy footgun.
  7. No systemd hardening
    Missing NoNewPrivileges, PrivateTmp, ProtectSystem, ProtectHome, RestrictSUIDSGID, SystemCallFilter, CapabilityBoundingSet, etc. For an AI agent runner, that’s weak.
  8. Command construction smells
    claudeCmd is built via string concatenation, then wrapped into shell/tmux. Some args are escaped later as a whole command string, but extraArgs and remoteControlName are not individually shell-escaped before joining. The docs say “keep it shell-safe,” which is not enforcement.

Verdict: usable only as a trusted-dev-box toy, not production-safe. I’d change defaults to:

skipPermissions = false;
remoteControl = false;

Also remove SETENV, make token dir 0710 or 0700, enforce token file modes, shell-escape every arg individually, add systemd sandboxing, and consider ephemeral users/homes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions