fix(shell): validate cwd parameter against workspace boundary (#524)

The shell tool's `cwd` / `working_dir` parameter was accepted raw
without any workspace boundary check, unlike file tools which all go
through `ToolContext::resolve_path()`.  This allowed the AI model to
execute shell commands from arbitrary directories outside the workspace.

Reuse the existing `resolve_path()` validation so that:
- Paths outside the workspace root are rejected with `PathEscape`
- `trust_mode = true` still bypasses the check (consistent behavior)
- `trusted_external_paths` entries are respected automatically
- Default behavior (no cwd argument) remains unchanged

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Zhang Zihan
2026-05-04 15:18:16 +08:00
committed by GitHub
parent 41843e63b0
commit 3e56f3526e
+9 -2
View File
@@ -1560,11 +1560,18 @@ impl ToolSpec for ExecShellTool {
}
let policy_override = context.elevated_sandbox_policy.clone();
let working_dir = input
let working_dir = match input
.get("cwd")
.or_else(|| input.get("working_dir"))
.and_then(serde_json::Value::as_str)
.map(str::to_string);
{
Some(dir) => {
// Validate cwd against workspace boundary (same as file tools)
let resolved = context.resolve_path(dir)?;
Some(resolved.to_string_lossy().to_string())
}
None => None,
};
let result = if interactive {
let mut manager = context