fix(coding-agent): avoid splitting parameter expansions
This commit is contained in:
@@ -43,7 +43,7 @@ Interception behavior:
|
||||
- on block, `BashTool` throws `ToolError` with message:
|
||||
- `Blocked: ...`
|
||||
- original command included.
|
||||
- heredocs, command substitutions, backticks, grouping, and malformed quoting do not produce extra fragments; they retain only the complete-input check. Interception is best-effort routing to dedicated tools, not a shell-security policy.
|
||||
- heredocs, parameter expansion, command substitutions, backticks, grouping, and malformed quoting do not produce extra fragments; they retain only the complete-input check. Interception is best-effort routing to dedicated tools, not a shell-security policy.
|
||||
|
||||
Default rule patterns (defined in code) target common misuses:
|
||||
|
||||
|
||||
+2
-2
@@ -110,7 +110,7 @@ git add file && git commit -m "message"
|
||||
GIT_AUTHOR_NAME=Dev git commit -m "message"
|
||||
```
|
||||
|
||||
An anchored rule such as `^\s*git\s+commit\b` can therefore match the `git commit` command in both examples. Quoted, escaped, and commented text is not treated as a command. Heredocs, command substitution, backticks, grouping, and malformed quoting retain only the complete-command check; the interceptor deliberately does not attempt to become a full shell parser.
|
||||
An anchored rule such as `^\s*git\s+commit\b` can therefore match the `git commit` command in both examples. Quoted, escaped, and commented text is not treated as a command. Heredocs, parameter expansion, command substitution, backticks, grouping, and malformed quoting retain only the complete-command check; the interceptor deliberately does not attempt to become a full shell parser.
|
||||
|
||||
### Interaction and selection guide
|
||||
|
||||
@@ -221,7 +221,7 @@ Choose the setting by the desired outcome:
|
||||
- `strict = true` is set on `BashTool`; `concurrency` is resolved per call: `pty: true` is `"exclusive"` (it takes over the terminal UI), everything else is `"shared"`, so multiple non-pty bash calls in one assistant message run in parallel. When parallel calls overlap on the same shell session key, the first owns the persistent `Shell`; the rest run in isolated one-shot shells (see `shellSessionsInUse` in `bash-executor.ts`).
|
||||
- `command` URL expansions shell-escape replacements; `env` and `cwd` expansion use `noEscape: true` because they become environment values / filesystem paths, not shell text.
|
||||
- `checkBashInterception()` blocks only when the matching rule's `tool` name is present in `ctx.toolNames`; missing tools disable their corresponding rule.
|
||||
- Interceptor configuration syntax is unchanged. It handles common flat command lists, not full shell parsing: heredocs, command substitution, backticks, grouping, and malformed quoting only receive the existing whole-input check. This is best-effort routing toward dedicated tools, not a security boundary.
|
||||
- Interceptor configuration syntax is unchanged. It handles common flat command lists, not full shell parsing: heredocs, parameter expansion, command substitution, backticks, grouping, and malformed quoting only receive the existing whole-input check. This is best-effort routing toward dedicated tools, not a security boundary.
|
||||
- Default interceptor rules come from `DEFAULT_BASH_INTERCEPTOR_RULES` in `packages/coding-agent/src/config/settings-schema.ts`:
|
||||
- `cat|head|tail|less|more` -> `read`
|
||||
- `grep|rg|ripgrep|ag|ack` -> `grep`
|
||||
|
||||
@@ -145,6 +145,7 @@ export function extractFlatShellCommandSegments(command: string): string[] {
|
||||
ch === "(" ||
|
||||
ch === ")" ||
|
||||
(ch === "$" && command[i + 1] === "(") ||
|
||||
(ch === "$" && command[i + 1] === "{") ||
|
||||
(ch === "<" && command[i + 1] === "<") ||
|
||||
((ch === "{" || ch === "}") &&
|
||||
atWordStart &&
|
||||
|
||||
@@ -127,6 +127,7 @@ describe("compound command interception", () => {
|
||||
for (const command of [
|
||||
'echo "$(git commit -m message)"',
|
||||
"echo `git commit -m message`",
|
||||
"echo ${x:-foo;git commit -m message}",
|
||||
"( git commit -m message )",
|
||||
"echo start; { true; git commit -m message; }",
|
||||
"cat <<'EOF'\ngit commit -m message\nEOF",
|
||||
|
||||
Reference in New Issue
Block a user