原文(日本語に翻訳)
JSON を標準出力に出力して終了コード 2 で終了する PreToolUse フックが、ツール呼び出しを正しくブロックしない問題を修正
原文(英語)
Fixed PreToolUse hooks that emit JSON to stdout and exit with code 2 not correctly blocking the tool call
概要
PreToolUse フックで終了コード 2 を使用してツール呼び出しをブロックしようとした際に、フックが JSON を標準出力に書き込んでいると正しくブロックが機能しないバグが修正されました。フックによるツール呼び出しのブロックは、セキュリティポリシーの適用や危険な操作の防止に使用される重要な機能であり、この修正により信頼性が向上しました。
基本的な使い方
PreToolUse フックで終了コード 2 を使用したブロック:
bash
#!/bin/bash
# 危険なコマンドをブロックするフックの例
TOOL_INPUT=$(cat)
# JSONで入力を解析
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // empty')
if echo "$COMMAND" | grep -qE "^(rm -rf|dd if=|mkfs)"; then
# ブロック理由をJSONで出力
echo '{"reason": "危険なコマンドはブロックされました", "blocked": true}'
exit 2 # v2.1.90以降は正しくブロックされる
fi
exit 0実践例
セキュリティポリシーの適用
本番環境への直接デプロイをブロックするフック:
bash
#!/bin/bash
TOOL_INPUT=$(cat)
# デプロイコマンドの検出
if echo "$TOOL_INPUT" | jq -e '.command | test("deploy.*production")' > /dev/null 2>&1; then
echo '{
"reason": "本番環境へのデプロイは承認が必要です",
"action": "blocked",
"contact": "devops@company.com"
}'
exit 2
fi
exit 0設定への追加方法:
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/path/to/security-check.sh"
}
]
}
]
}
}ファイル変更の検証
特定のディレクトリへの変更をブロックするフック:
bash
#!/bin/bash
TOOL_INPUT=$(cat)
FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')
if [[ "$FILE_PATH" == /etc/* ]] || [[ "$FILE_PATH" == /usr/* ]]; then
echo '{"reason": "システムディレクトリへの変更は許可されていません"}'
exit 2 # 修正後、正しくブロックされる
fi
exit 0ツール呼び出しのロギングとブロック
監査ログ付きブロック:
bash
#!/bin/bash
TOOL_INPUT=$(cat)
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# 監査ログに記録
echo "{\"timestamp\": \"$TIMESTAMP\", \"input\": $TOOL_INPUT}" >> /var/log/claude-audit.log
# 特定のパターンをブロック
if echo "$TOOL_INPUT" | jq -e '.command | test("curl.*external-api")' > /dev/null 2>&1; then
echo '{"reason": "外部APIへの直接アクセスはブロックされました", "logged": true}'
exit 2
fi
exit 0注意点
exit 2はツール呼び出しをブロックするための終了コードです(exit 1は別の動作)- JSON を標準出力に出力する場合は、有効な JSON 形式であることを確認してください
- このバグは JSON を出力しながら
exit 2を使用する場合のみ影響していました - v2.1.90 以降では、JSON 出力の有無に関わらず
exit 2でのブロックが確実に機能します