Skip to content

feat(allowedpaths): permit writes through sandbox open#206

Draft
julesmcrt wants to merge 1 commit intomainfrom
jules.macret/host-remediation/allowed-paths-writes
Draft

feat(allowedpaths): permit writes through sandbox open#206
julesmcrt wants to merge 1 commit intomainfrom
jules.macret/host-remediation/allowed-paths-writes

Conversation

@julesmcrt
Copy link
Copy Markdown
Collaborator

Summary

  • Relax Sandbox.Open from read-only to read+write. The underlying os.Root.OpenFile already validates writes safely via openat, so this is a flag-check widening, not new machinery.
  • Tighten the accepted flag set to an explicit allowlist (O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREATE|O_EXCL|O_TRUNC); anything else (O_DIRECTORY, O_NOFOLLOW, O_SYNC, O_NONBLOCK, …) returns ErrPermission.
  • Keep the cross-root symlink fallback read-only. Following a symlink that escapes its os.Root and then performing O_CREATE/O_TRUNC/O_APPEND/write opens is the classic TOCTOU footgun — the link target can be swapped between resolution and open. Writes must therefore stay inside a single os.Root.
  • Update interp.AllowedPaths doc and README.md / SHELL_FEATURES.md to reflect the new read+write semantics.

Demo-only stack — not for main merge

This branch is the foundation of a demo-only stack and is not expected to merge to main. Follow-up branches (> redirection, a truncate builtin, logrotate via host exec) build on top.

As a result, this PR ships a sandbox capability with no in-tree consumer — file-target output redirects (>, >>) are still rejected by interp/validate.go, and no builtin gains write capability. Reviewers should not expect user-visible behavior changes here.

Test plan

  • make fmt clean
  • go test ./allowedpaths/... ./interp/... -timeout 120s
  • go test ./... -timeout 300s (full suite, including TestVerificationAllowedpathsCleanPass)
  • New tests in allowedpaths/sandbox_test.go:
    • TestSandboxWriteAllowedPathO_CREATE|O_WRONLY inside the allowlist creates the file
    • TestSandboxWriteOutsideAllowedPath — same flags outside returns ErrPermission, no file created
    • TestSandboxAppendO_APPEND appends correctly
    • TestSandboxTruncateO_TRUNC replaces content
    • TestSandboxWriteThroughSymlinkEscapeRejected — symlink-inside-allowlist pointing outside is denied for writes (TOCTOU defense), and the target is not created
    • TestSandboxWriteRejectsUnknownFlag — unknown flag bit rejected
    • TestSandboxOpenReadStillWorks — read-only path unaffected
  • TestAllowedPathsRedirectOutside (and other existing redirect/cat tests) still pass — file-target redirection remains blocked at the parser.

🤖 Generated with Claude Code

Relax Sandbox.Open from read-only to read+write. The underlying
os.Root.OpenFile already validates writes safely via openat, so the
sandbox needed only to widen its flag check rather than build new
machinery.

The cross-root symlink fallback stays read-only — following a symlink
that escapes its os.Root and then performing O_CREATE/O_TRUNC is the
classic TOCTOU footgun, where the link target can be swapped between
resolution and open. Writes therefore stay inside a single os.Root.

Open flags are also tightened to an explicit allowlist
(O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREATE|O_EXCL|O_TRUNC) so unknown
or platform-specific bits cannot slip through.

This is the foundation of a demo-only stack — file-target redirects
(>, >>) are still blocked at the parser, so no user-visible surface
gains write capability in this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@julesmcrt
Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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