Repository navigation
fix: nested globs aren't refused as /proc reads, and other sessions' transcripts are readable in the sandbox - #455
Merged
Merged
Conversation
…ronment
`cat src/*/*.ts` and `grep x ~/.claude/projects/*/*.jsonl` were refused in
every mode ("/proc/<pid>/environ holds credentials"): a bare `*` component
could spell "proc", and the rule took it for /proc at any depth. /proc is
top-level: a pattern counts as it only at the root or after what can lead
anywhere (`$d`, `..`); a component that is "proc" still counts anywhere (a
link to /). `$HOME/...` is the home on a line that doesn't set HOME.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anscripts ~/.claude/projects joins the sandbox's read-only home allowlist by default, so an agent can look up what another session did (as before the sandbox); never writable. Removable from sandbox.homeReadable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rsharath
approved these changes
Nov 5, 2026
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
Ordinary commands that use a nested glob were refused in every mode as reading a process's environment. Examples:
cat src/*/*.ts, and searching session transcripts withgrep x ~/.claude/projects/*/*.jsonl. They now run. Real reads of a process's environment are still refused.What was wrong
The shell reader refuses any command that could read
/proc/<pid>/environ. A process's environment holds its credentials. The check treated any path component that could spell "proc" as/proc, wherever it appeared in the path. A bare*can spell anything, so the second*insrc/*/*.tscounted as a possible/proc, and the command was refused with "/proc//environ holds credentials".Why it matters
/procthat doesn't exist there.src/*/*.ts)./pr?c). Every test then covered/proc-shaped paths, and none covered an ordinary nested glob.What changed
/procis a top-level directory. A component that only matches "proc" as a pattern (*,pr?c) counts as/proconly:$d,..).procstill counts at any depth, since it could be reached through a link to/.$HOME/…is read as the home directory, as~/…is, on a line that doesn't nameHOMEas a bare word (HOME=,export HOME,unset HOME).Also: other sessions' transcripts are readable inside the sandbox
#454 hid the whole home from sandboxed commands,
~/.claude/projectsincluded, so an agent couldn't look up another session's transcript even with the glob fixed. The owner decided they should be readable by default, so~/.claude/projectsjoins the read-only home allowlist (sandbox.homeReadable). Agents can read every session's transcript and memory but never write them, and the current project's own memory stays writable, as before. To hide them, remove the entry: a secret once pasted into a session is in its transcript.Verification
/procreads that still must be. Among them:/proc/*/environ,/*/1/environ,/pr?c/1/environ,/proc/$PPID/environ,"$d"/proc/1/*,../../../../proc/1/*, a literalprocunder the home, andHOME=/; cat $HOME/proc/1/*.cat src/*/*.tsrates low, and/procreads are still refused.🤖 Implementation context (for agents / maintainers)
src/daemon/risk/shell-risk.tsprocSecretWord: theatsearch requiresc === "proc", orreachesRoot(i), meaningi === 0or an earlier component containingSHAPE_ANYor...shapeComponents: a leadingSHAPE_ANYfrom$HOME/${HOME}is replaced byctx.homewhenctx.homeFixed.assessShellCommandSynccomputeshomeFixed = !/(^|[^$\w{])HOME\b/.test(command), andCtxgains an optionalhomeFixed.src/daemon/risk/shell-risk.test.ts: "a nested glob isn't taken for /proc …".🤖 Generated with Claude Code