A logic flaw exists in bashToolHasPermission() inside src/tools/BashTool/bashPermissions.ts. When the sandbox auto-allow feature is active and no explicit deny rule is configured, the function returns an allow result immediately — before the path constraint filter (checkPathConstraints) is ever evaluated. This allows commands containing path traversal sequences (e.g., ../../../../../etc/passwd) to bypass directory restrictions entirely.
src/tools/BashTool/bashPermissions.tsbashToolHasPermissionbashToolHasPermission()
│
├─ [~1445] Sandbox auto-allow block
│ └─ No deny rule found → return ALLOW ⚠️ Early exit
│
└─ [~1644] checkPathConstraints() ❌ Never reached
The sandbox block was designed to skip interactive permission prompts in sandboxed environments. However, it unintentionally also skips the path traversal filter, which is a separate and critical security control.
Any process or user operating in a sandboxed session with no explicit deny rules can:
/etc/passwd, /etc/shadow, .env files, SSH private keys)SandboxManager.isSandboxingEnabled() = trueSandboxManager.isAutoAllowBashIfSandboxedEnabled() = truecat ../../../../../etc/passwd
behavior: allow without triggering checkPathConstraintsThe sandbox auto-allow block should never short-circuit the full permission pipeline. It may suppress interactive prompts, but path constraint validation must always execute.
allowOnly return early for deny or ask behaviors. Let allow fall through to checkPathConstraints:
if (
SandboxManager.isSandboxingEnabled() &&
SandboxManager.isAutoAllowBashIfSandboxedEnabled() &&
shouldUseSandbox(input)
) {
const sandboxAutoAllowResult = checkSandboxAutoAllow(
input,
appState.toolPermissionContext,
);
if (sandboxAutoAllowResult.behavior !== 'allow') {
// Only block or prompt — never skip path checks on allow
return sandboxAutoAllowResult;
}
// If 'allow', continue to checkPathConstraints below
}
Run checkPathConstraints explicitly inside the sandbox block before returning:
if (sandboxAutoAllowResult.behavior !== 'passthrough') {
const pathCheck = checkPathConstraints(input, appState.toolPermissionContext);
if (pathCheck.behavior !== 'allow') {
return pathCheck; // Block traversal attempts even in sandbox
}
return sandboxAutoAllowResult;
}
Reorder the function so checkPathConstraints always runs first, and the sandbox block only handles the prompt-suppression logic afterward.
Credit: Elvin Latifli (@Rickidevs )
{
"github_reviewed": true,
"github_reviewed_at": "2026-04-21T15:16:16Z",
"cwe_ids": [
"CWE-22",
"CWE-284"
],
"severity": "HIGH",
"nvd_published_at": "2026-04-21T00:16:28Z"
}