Skip to content

fix(sandbox): drop ~/.config and ~/.local from auto write-set - #305

Merged
zjshen14 merged 2 commits into
mainfrom
fix/299-narrow-auto-sandbox-writes
Aug 10, 2026
Merged

fix(sandbox): drop ~/.config and ~/.local from auto write-set#305
zjshen14 merged 2 commits into
mainfrom
fix/299-narrow-auto-sandbox-writes

Conversation

@zjshen14

@zjshen14 zjshen14 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

auto mode bound ~/.config and ~/.local writable inside the sandbox. Both sit on the user's shell $PATH / rc-load path (~/.local/bin, ~/.config/fish, ~/.config/npm, …), so a sandboxed command could plant an executable or rc backdoor that runs unsandboxed later — a persistence/escape vector that widens the per-command blast radius.

This drops both from:

  • the bwrap AUTO_HOME_DIRS array, and
  • the sandbox-exec auto profile.

Package caches (~/.npm, ~/.cargo, ~/.cache, …) — which are not on $PATH — are kept.

auto is documented as "not a security boundary"; this narrows the obvious persistence surface. Real isolation remains --sandbox strict.

Test plan

  • npm run typecheck && npm run lint && npm run format:check && npm test — all pass (844 tests)
  • New macOS-gated tests: writes to ~/.config and ~/.local are now blocked in auto mode (permission denied); existing ~/.npm / ~/.cache / ~/Library/Caches allow tests still pass.

Tradeoff (for reviewers)

Some tools write first-run config to ~/.config (e.g. gh auth). Under auto those may now fail until run once outside the sandbox. Acceptable for the security gain; users can opt out with --sandbox off. Alternative considered: narrow ~/.local to ~/.local/share — happy to switch if reviewers prefer the less aggressive option.

Closes #299

auto mode bound ~/.config and ~/.local writable inside the sandbox. Both sit on
the user's shell $PATH / rc-load path (~/.local/bin, ~/.config/fish,
~/.config/npm, ...), so a sandboxed command could plant an executable or rc
backdoor that runs UNSANDBOXED later — a persistence/escape vector widening the
per-command blast radius.

Drops both from the bwrap AUTO_HOME_DIRS array and the sandbox-exec auto profile.
Package caches (~/.npm, ~/.cargo, ~/.cache, ...) which are not on $PATH are kept.

Closes #299
@zjshen14

zjshen14 commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

Review — LGTM, good catch

This is a genuinely subtle one and the reasoning in the comment is exactly right: the distinction that matters is not "dot-dir in home" but "on a path that gets executed or sourced later". ~/.local/bin on $PATH and ~/.config/fish|npm as rc-load locations turn a sandboxed write into unsandboxed execution on the user's next shell — which defeats the point of the sandbox entirely. Keeping the package caches (.npm, .cargo, .yarn) writable while dropping these two is the correct line.

The macOS tests assert the actual denial rather than just the config change, which is the right level.

Two follow-on thoughts, not blocking:

  • The same "is it on an execution path?" question applies to a few entries that remain reachable in auto: ~/.cargo/bin is on $PATH for most Rust users, and ~/.yarn/bin similarly. .cargo is bound writable here. If the threat model is "sandboxed command plants an executable that runs later unsandboxed", ~/.cargo/bin is the same vector as ~/.local/bin. Worth either excluding those bin subdirectories specifically or documenting why the risk is accepted.
  • Users who legitimately need ~/.config writes in auto now have no path short of --sandbox off, which is a big hammer. If that turns up in practice, a targeted allowlist knob would be better than pushing people to disable isolation wholesale.

Please also mirror the rationale into docs/design/a7-sandbox-loosen-auto.md, since that doc is what a future contributor will read when they wonder why the auto write-set looks arbitrary — the code comment is good but the design doc is where the "why" belongs.

#299)

Review asked for the 'why' to live in the design doc a future contributor reads,
not just the code comment. Adds an amendment to a7-sandbox-loosen-auto.md
explaining the on-$PATH / rc-load distinction that drove dropping ~/.config and
~/.local, the residual ~/.cargo/bin acceptance, and the lack of a $HOME/.config
auto-mode escape hatch.

References #299
@zjshen14

zjshen14 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Addressed in 5ca581c — added an amendment to docs/design/a7-sandbox-loosen-auto.md capturing the on-$PATH / rc-load rationale and the residual ~/.cargo/bin acceptance, so the 'why' lives in the design doc a future contributor reads. The ~/.config escape-hatch knob is noted there as the better future answer than --sandbox off.

@zjshen14
zjshen14 merged commit f321053 into main Aug 10, 2026
3 checks passed
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.

[security] auto sandbox binds ~/.config and ~/.local writable (persistence / escape vector)

1 participant