# Fix shell injection vulnerability in terminal tool permissions \(\#47807\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/dbeb0af9adeb0839fc0d7b3949392bb183ce183a)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: dbeb0af9adeb0839fc0d7b3949392bb183ce183a

Requested commit: dbeb0af9adeb0839fc0d7b3949392bb183ce183a

Commit: dbeb0af9adeb0839fc0d7b3949392bb183ce183a

Tree: 8dbe77f1afe3749e82de5a5c2eb44b54a04a881f

Author: Richard Feldman

Committer: GitHub

## Message

```
Fix shell injection vulnerability in terminal tool permissions (#47807)

<img width="1110" height="280" alt="Screenshot 2026-01-28 at 3 35 52 PM"
src="https://github.com/user-attachments/assets/4d467e2c-2e7b-4ec7-bc87-6f0df8e667f0"
/>

<img width="1094" height="411" alt="Screenshot 2026-01-28 at 3 40 54 PM"
src="https://github.com/user-attachments/assets/f559df93-e72e-4457-ba1b-f7d6239f3285"
/>


Previously, if a user configured `^ls` as an always-allow pattern, an
attacker could craft a command like `ls && rm -rf /` which would be
auto-approved because the regex only matched the beginning of the
command string.

Now the command is parsed into individual sub-commands (`ls`, `rm -rf
/`) and EACH sub-command must match an allow pattern for auto-approval.
This prevents shell injection attacks using operators like:
- `&&` and `||` (boolean operators)
- `;` and `&` (sequential/background execution)
- `|` (pipes)
- Newlines
- Command substitution (`$()` and backticks)
- Process substitution (`<()` and `>()`)

## Matching Logic

- **always_deny**: if ANY sub-command matches, deny the entire command
- **always_confirm**: if ANY sub-command matches, require confirmation
(unless always_deny matched, in which case deny)
- **always_allow**: ALL sub-commands must match for auto-approval
(unless always_confirm or always_deny matched, in which case defer to
those)
- If parsing fails, or if the shell is unsupported, then always_allow is
disabled for this command

As usual, `always_allow_tool_actions` supercedes all of these. If it is
`true`, then we always allow all tool calls, no questions asked.

## Shell Compatibility

The shell parser only supports POSIX-like command chaining syntax (`&&`,
`||`, `;`, `|`).

**Supported shells:** Posix (sh, bash, dash, zsh), Fish 3.0+, PowerShell
7+/Pwsh, Cmd, Xonsh, Csh, Tcsh

**Unsupported shells:** Nushell (uses `and`/`or` keywords), Elvish (uses
`and`/`or` keywords), Rc (Plan 9 shell - no `&&`/`||` operators)

For unsupported shells:
- The "Always allow" UI options are hidden for the terminal tool
- If the user has `always_allow` patterns configured in settings, they
will see a `Deny` with an explanatory error message

(No release notes because granular tool permissions are behind a feature
flag.)

Release Notes:

- N/A

---------

Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
```

## Parents

- [e18162216eed511648f06f8deeac1309b2617e2b](https://git.cafe/gitcafe/zed/commit/e18162216eed511648f06f8deeac1309b2617e2b?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/dbeb0af9adeb0839fc0d7b3949392bb183ce183a?format=markdown)
