allowedpaths: relax sandbox to permit write opens (remediation series PR B)#525
Merged
Merged
Conversation
This comment has been minimized.
This comment has been minimized.
julesmcrt
marked this pull request as ready for review
June 11, 2026 16:18
julesmcrt
requested review from
AlexandreYang,
astuyve,
matt-dz,
thieman and
val06
as code owners
June 11, 2026 16:18
4 tasks
val06
approved these changes
Jun 12, 2026
AlexandreYang
approved these changes
Jun 12, 2026
AlexandreYang
self-requested a review
June 12, 2026 12:24
julesmcrt
force-pushed
the
jules.macret/sandbox-write-capability
branch
from
June 15, 2026 11:54
a7ddd58 to
a8279f1
Compare
julesmcrt
added a commit
that referenced
this pull request
Jun 15, 2026
Address two reviewer comments on PR #525: 1. "pass remediation mode state to the Sandbox" — adds a readOnly bool field to Sandbox (default true). Open rejects write flags in read-only mode as defense-in-depth, so even a mistaken interpreter call in read-only mode is caught at the sandbox boundary. SetWritable() switches the sandbox into write-permitted mode; the interpreter will call this when RemediationMode is active (PR C). 2. "check to only keep minimal needed" — trims allowedOpenFlags to the exact set needed for shell redirections (O_RDONLY, O_WRONLY, O_APPEND, O_CREATE, O_TRUNC). O_RDWR and O_EXCL are not needed and are now rejected. A separate writeOpenFlags const names the write-implying subset for the readOnly check. Tests: all write tests now call sb.SetWritable() first; new TestSandboxDefaultReadOnly verifies the default sandbox blocks all write flag combinations. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…n series) The sandbox previously rejected every non-O_RDONLY open as a blanket defense. This change replaces that with a precise flag-mask check: only bits in allowedOpenFlags (O_RDONLY|O_WRONLY|O_RDWR|O_APPEND| O_CREATE|O_EXCL|O_TRUNC) are accepted; unknown bits still return ErrPermission. Write opens through os.Root are now allowed for paths inside the allowlist. TOCTOU defense: the cross-root symlink fallback continues to be read-only. A symlink that escapes its os.Root is followed for reads but rejected for writes, preventing a malicious link target from being swapped between resolution and open. Nothing in the interpreter uses write opens yet — output redirections are still blocked at parse time. This is a pure capability layer change; wiring is PR C. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
RemediationMode, ModeRemediation, remediationMode, and the --mode CLI flag help text all still said "inert in this release; behavior is wired in follow-up PRs." PR C wires file-target output redirections (>, >>) within AllowedPaths — update all three sites to describe what is now actually enabled. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Address two reviewer comments on PR #525: 1. "pass remediation mode state to the Sandbox" — adds a readOnly bool field to Sandbox (default true). Open rejects write flags in read-only mode as defense-in-depth, so even a mistaken interpreter call in read-only mode is caught at the sandbox boundary. SetWritable() switches the sandbox into write-permitted mode; the interpreter will call this when RemediationMode is active (PR C). 2. "check to only keep minimal needed" — trims allowedOpenFlags to the exact set needed for shell redirections (O_RDONLY, O_WRONLY, O_APPEND, O_CREATE, O_TRUNC). O_RDWR and O_EXCL are not needed and are now rejected. A separate writeOpenFlags const names the write-implying subset for the readOnly check. Tests: all write tests now call sb.SetWritable() first; new TestSandboxDefaultReadOnly verifies the default sandbox blocks all write flag combinations. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The new s.readOnly field access in Open was a nil pointer dereference when the interpreter is constructed without AllowedPaths (nil sandbox). The open handler always calls sandbox.Open via a closure, so a nil receiver reaches Open on any file open attempt in that configuration. The old code only reached s.resolve() which already had a nil guard; the new readOnly check before it had none. Add an explicit nil guard at the top of Open, matching the pattern established by resolve(). Nil sandbox returns ErrPermission, same as before (resolve returned false → ErrPermission). Fixes TestFeatureProbesMatchHelp/pipes-redirections/supported/Input_redirection. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
julesmcrt
force-pushed
the
jules.macret/sandbox-write-capability
branch
from
June 15, 2026 14:02
3f9f2cb to
db47ea4
Compare
PR #527 moved the command count from the top-level header line into the Commands section header ("Commands (N of M enabled):"). Update the four help scenario files that still checked for the old "commands available" and "commands enabled" header strings. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
allowedOpenFlagsconst (O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREATE|O_EXCL|O_TRUNC) toallowedpaths/sandbox.goSandbox.Opento reject unknown flag bits (instead of blanket non-O_RDONLYrejection), allowing write opens inside the allowlistanalysis/symbols_allowedpaths.gowith the new OS flag constantsREADME.md,SHELL_FEATURES.md, andinterp/api.godoc comment to reflect that both reads and writes are now sandboxedContext
This is PR B of the remediation mode series. PR A (#524) added the
RemediationMode()option tointerp/api.go.The sandbox is now write-capable, but nothing in the interpreter uses it yet — output redirections (
>,>>) remain blocked at parse time. Wiring write opens into shell features (redirections, builtins) is PR C.Test plan
go test ./allowedpaths/... ./interp/... -timeout 120spasses🤖 Generated with Claude Code