Skip to content

fix(agent-guard): refuse env -S instead of re-splitting its string - #1694

Merged
potiuk merged 1 commit into
apache:mainfrom
potiuk:fix/agent-guard-refuse-env-split
Oct 18, 2026
Merged

potiuk merged 1 commit into
apache:mainfrom
potiuk:fix/agent-guard-refuse-env-split

Conversation

@potiuk

@potiuk potiuk commented Oct 17, 2026

Copy link
Copy Markdown
Member

GNU env -S / --split-string splits its string with its own escapes (\_, \c, ${VAR}). agent-guard re-split it with shlex, which does not reproduce those rules, so a crafted string could make the guards check one command while env runs another. -S is rare in legitimate agent commands, so the guard now treats it like any other unparsable wrapper and refuses the line (agent-guard[wrapper]).

  • -S, -S'…', clustered -iS, and --split-string[=…] are refused. -u/--unset, -C/--chdir, -i and NAME=value are still unwrapped as before.
  • The tests that expected the guards to see through -S now expect the refusal, with the escape case covered.
  • The README's wrapper paragraph says so; the plugin copy and the secure-setup fingerprint are regenerated.

Found by the automated push security review on #1693.

🤖 Generated with Claude Code

GNU env splits a -S string with its own escapes (\_, \c, ${VAR}), which
shlex does not reproduce, so the guards could check one command while env
runs another. The option is rare in legitimate commands, so refusing it is
the fail-closed choice.

Generated-by: Claude Opus 5
@github-actions github-actions Bot added family:setup setup-* skills family:tools tools/* family:docs Docs, MISSION.md, READMEs capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) substrate:action-guard Tool substrate: deterministic pre-tool-use command guards labels Oct 17, 2026
@potiuk
potiuk merged commit 4aea234 into apache:main Oct 18, 2026
11 checks passed
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) family:docs Docs, MISSION.md, READMEs family:setup setup-* skills family:tools tools/* substrate:action-guard Tool substrate: deterministic pre-tool-use command guards

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant