Repository navigation
fix(agent-guard): see through env/command; refuse a quoted ~ and the eval wrapper's other spellings - #1691
Merged
Conversation
…eval wrapper's other spellings Closes the gaps tracked in apache#1679, plus one found while running evals. - Every guard now looks through the prefix wrappers that run their argument: `env` (with -i, -u NAME, -S "...", and NAME=value assignments, which still count as inline overrides) and `command` (-p). `env git commit ...` used to reach no guard at all. `command -v git` is a lookup and is left alone. - vetted-ops-spelling refuses a quoted or escaped `~` in the --project/--from value: the shell does not expand it, so uv gets a directory named `~` and the exclusion does not match. - A sandbox exclusion matches a command line by its start, so the right spelling behind `env` / `command` still runs sandboxed: refused, with the command to run instead. - `magpie-run-evals.sh` launched by any path but the literal `~/.claude/scripts/magpie-run-evals.sh` (an expanded home, $HOME, a quoted `~`, a repository copy, a wrapper) is refused: it would run inside the sandbox and every eval case would error ungraded. Override: MAGPIE_ALLOW_SCRIPT_PATH=1. AGENTS.md's golden rule and the agent-guard README cover both. Generated-by: Claude Opus 5
… spelling Closes the bypasses a security review found in the previous commit: - Unwrapping stopped after eight nested wrappers and left `env` as the head, so nine wrappers reached no guard. It now runs until no wrapper is left; a line deeper than a generous limit, an `env` option that is not documented, a `command` flag other than -p, or a -S string that does not tokenise marks the segment unparsed, and dispatch refuses it. - `env` options are parsed as GNU / BSD env documents them: clustered short flags (`-iu NAME`, `-uNAME`, `-iCdir`, `-iS'...'`), long forms with `=` or a separate value, and the signal options. - A `~` spelling is accepted only when the raw line carries it bare and space-separated: a quote after the `~` (`~"/..."`) or the `--project=~/...` form leaves the `~` unexpanded as surely as a leading quote does. Generated-by: Claude Opus 5
This was referenced Oct 17, 2026
potiuk
added a commit
that referenced
this pull request
Oct 19, 2026
Hand-sync of tools/spec-loop/specs/ with the functionality that landed between 43e4c6e and ccb53a3. Specs changed: - adapters: Gmail drafting through the gmail-plaintext MCP tools, not the CLI (93051d5, #1681); the Jira CLI's explicit --deployment and the tracker backends shipped as generated plugin copies (1cf5cee, #1683); local-tracker report files and folders created 0600 / 0700 (68ec4a3, #1700). - agent-isolation-sandbox: agent-guard unwrapping env / command and refusing env -S (b00d4b5, #1691; 4aea234, #1694); the macOS touch overlay shown whether or not activation is granted (0d9c168, #1697); the sandbox-lint workflow refusing a tracked .claude/settings.local.json (51a610b, #1692) and sandbox-lint refusing the Gmail token path in allowRead (93051d5, #1681). - vetted-command-surface: the spelling guard refusing a quoted ~, the right spelling behind env / command, and other spellings of the eval wrapper (b00d4b5, #1691). - adoption-and-setup: the tracker-backend question on every first setup and the Jira label mapping and doctor gate (1cf5cee, #1683). - .last-sync bumped to ccb53a3. No spec change needed (specs already updated in the commit itself): ccb53a3, 9a8ec5f, 9955d7d, c9f34cc, 76cc6e8, 1d773a8, 16014a2. No functional change for the specs: d4b7dc3 (review-body wording), 77e8145 (test timing), 8d606d6 (eval fixtures), a04891f (the previous sync). Generated-by: Claude Opus 5
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
Closes #1679, plus one gap found while running the evals for #1683.
env(GNU/BSD options, including clustered short flags such as-iu NAME,-uNAMEand-iS'…', the long forms, the signal options, andNAME=valueassignments, which still count as inline overrides) andcommand(-p). Before,env git commit …orcommand gh pr comment …reached no guard.command -v gitis a lookup and is left alone.dispatchrefuse the line (agent-guard[wrapper]). That covers an undocumented option, an option missing its value, a-Sstring that does not tokenise, and nesting deeper than a generous limit.~.vetted-ops-spellingaccepts a~base only when the raw line carries it bare and space-separated. A quoted or escaped~("~/…",~"/…",\~/…) and the--project=~/…form are not expanded by the shell, so they would run inside the sandbox and fail.env/commandstill runs sandboxed. This is now refused, with the command to run instead.magpie-run-evals.shlaunched by anything but a bare~/.claude/scripts/magpie-run-evals.shat the start of the line is refused: an expanded home,$HOME, a quoted~, a repository copy, or a wrapper. Each of those runs inside the sandbox, where every case errors without being graded, which happened while running the fix(security-tracker): harden the local and Jira backends after review #1683 evals. Override:MAGPIE_ALLOW_SCRIPT_PATH=1.Type of change
tools/agent-guardengine + plugin copy)Test plan
prek run --all-filespassestools/agent-guardtests. New cases cover:-S;env;=-form~;claude-codesecurity review of the branch: pass. The first commit's security review findings are fixed in the second.Notes for reviewers
nice,nohup,time,timeout,bash -c,exec, GNUenv -), and shell syntax the guards'shlextokeniser reads differently from the shell (a newline as a command separator,$'…'quoting, command substitution). These are engine-wide parser differentials; they bypass every guard today and are worth their own issue. The guards stay defence in depth, not the sandbox.Gen-AI disclosure: prepared with the assistance of Claude Code (Claude Opus 5); reviewed by the author.
🤖 Generated with Claude Code