Claude Media
security-reviewのHaiku廃止で誤検知フィルタが無効化する理由

security-reviewのHaiku廃止で誤検知フィルタが無効化する理由

GitHub Action版のsecurity-reviewは誤検知フィルタの検証にHaiku 3.5を固定使用しており、モデル廃止後はフィルタが気づかれないまま無効化されます。原因と現状の対処法です。

GitHub Actionのanthropics/claude-code-security-review(Claude Code Security Reviewer)には、誤検知を除外する第二段フィルタが組み込まれています。このフィルタは内部でClaude APIへの疎通確認を行いますが、その確認処理が廃止済みのHaiku 3.5モデル(claude-3-5-haiku-20241022)を固定で呼び出しているため、モデル廃止後は確認が失敗し、フィルタそのものが気づかれないまま無効化されます。修正は提案されているものの、mainブランチへはまだ取り込まれていません。

何が壊れているか — validate_api_accessが廃止モデルを呼び続ける

GitHub Action版のsecurity-reviewは、PRの差分をClaudeで分析したあと、検出した指摘に対して「本当に危険な指摘か」を判定する第二段のフィルタ処理を通します。このフィルタを初期化する際、claude_api_client.pyvalidate_api_access()メソッドがAPIへの疎通確認を行います。

def validate_api_access(self) -> Tuple[bool, str]:
    try:
        self.client.messages.create(
            model="claude-3-5-haiku-20241022",  # 廃止済みモデルを固定指定
            max_tokens=10,
            messages=[{"role": "user", "content": "Hello"}],
            timeout=10
        )
        return True, ""
    except Exception as e:
        return False, f"API validation failed: {error_msg}"

呼び出しているモデルIDclaude-3-5-haiku-20241022(Claude Haiku 3.5)は、Anthropicの公式廃止ページによると2025年12月19日に廃止予告が出され、2026年2月19日付けで完全に廃止(Retired)されています。推奨移行先はclaude-haiku-4-5-20251001です。廃止後にこのメソッドを呼ぶと疎通確認が失敗し、呼び出し元のfindings_filter.pyが次の分岐に入ります。

valid, error = self.claude_client.validate_api_access()
if not valid:
    logger.warning(f"Claude API validation failed: {error}")
    self.claude_client = None
    self.use_claude_filtering = False  # フィルタを無効化

以降のスキャンはすべてuse_claude_filtering = Falseのまま実行され、検出された指摘はjustification: "Claude filtering disabled"confidence_score: 10.0というメタデータ付きでそのまま出力に混ざります。脆弱性検知そのもの(第一段のスキャン)は止まりません。止まるのは、検知結果から誤検知を間引く第二段の処理だけです。

このフィルタが正常に動いていれば、本来はどんな指摘を弾いているのでしょうか。READMEが挙げる「除外対象」は、サービス拒否(DoS)の可能性・レート制限まわりの懸念・メモリやCPU枯渇の懸念・実害が確認できない汎用的な入力検証の指摘・オープンリダイレクトの5種類です。いずれも「理屈の上では脆弱性だが、実際に悪用可能かは文脈次第」という、パターンマッチ型のスキャナが苦手とする判断です。フィルタが無効化された状態では、この5種類がそのままPRコメントとして流れ込みます。

疎通確認のような軽い呼び出しに、本体スキャンより安価なHaikuを割り当てる設計自体は理にかなっています。Claude Codeサブエージェントのモデル配分設計で扱っているような、役割ごとに軽量モデルを割り当てる考え方と同じ方向です。問題は、割り当てたモデルIDを特定のスナップショット名で固定し、モデルの世代交代を追随させる仕組みを持たなかった点にあります。

なぜCI上で気づきにくいか

validate_api_access()が失敗しても、スキャン全体は成功として終了します。findings_filter.pyは失敗をlogger.warningでstderrへ出力しますが、この警告はスキャンそのものの失敗とは扱われないため、PRへのコメントやジョブサマリーには表れません。GitHub Actionsのジョブログを開いてstderr出力を遡らない限り、見た目上は正常に完了したセキュリティレビューに見えます。

唯一の手がかりは、結果ファイル(upload-resultsが既定で有効なら、アーティファクトとしてアップロードされるresults-file)に残るjustificationフィールドです。次のように検索すると、フィルタが無効化された状態で通った指摘の件数が分かります。

# ダウンロードした結果JSON内で「フィルタ無効化」のまま出力された指摘を数える
grep -o '"justification": "Claude filtering disabled"' results.json | wc -l

件数が0より大きければ、そのスキャンではClaude側の誤検知フィルタが機能せず、パターンマッチに近い水準の指摘がそのままPRコメントとして流れていることになります。

報告者はこの状態を「GitHub Actionsの実行で、ENABLE_CLAUDE_FILTERINGはtrue、ANTHROPIC_API_KEYも設定済みなのに、フィルタは無効化されたままだった」と説明しています。設定はすべて正しいのに機能しない、という点が本バグの厄介さです。設定漏れのチェックリストをいくら見直しても、validate_api_access()が呼んでいるモデルIDまでは目が届きません。

影響範囲 — ENABLE_CLAUDE_FILTERINGは全実行で常にtrue

このバグの影響範囲を狭く見積もりたくなりますが、実際にはanthropics/claude-code-security-reviewを素のクイックスタート構成で使っているワークフローすべてが対象です。action.ymlは、ユーザーが入力を指定しなくても環境変数ENABLE_CLAUDE_FILTERINGを常に'true'にセットします。

env:
  ANTHROPIC_API_KEY: ${{ inputs.claude-api-key }}
  ENABLE_CLAUDE_FILTERING: 'true'

つまり「フィルタ機能をオンにする設定をした覚えがない」プロジェクトでも、既定でフィルタは有効化されようとし、そのたびに廃止済みモデルへの疎通確認が走って失敗します。claude-model入力(既定はclaude-opus-4-1-20250805)でスキャン本体のモデルを変更していても無関係です。この入力は本体スキャンのモデルにのみ反映され、validate_api_access()はどのモデルが設定されていてもclaude-3-5-haiku-20241022を固定で呼びます。廃止済みモデルへの参照を避ける設定の考え方は、CLIのenforceAvailableModelsでDefaultモデルの抜け穴を塞ぐでも扱っていますが、このGitHub Actionには同種の防御設定はありません。

修正は提案済み・未マージ — 現状の選択肢

Issueの報告と同時に、self.model(スキャン本体に設定済みのモデル)を疎通確認にも使う修正が提案されています。この提案は2026年3月に一度提出(PR #76)されたのち、2026年4月に別プルリクエスト(PR #92)として再提出されましたが、いずれもマージされていません。anthropics/claude-code-security-review本体にはタグ付きリリースが無く、ワークフローはuses: anthropics/claude-code-security-review@mainのようにmainブランチを直接参照する構成が基本のため、修正済みの過去バージョンにピン留めするという逃げ道も使えません。

提案されている修正はごく小さく、疎通確認に使うモデルをハードコードされた文字列ではなく、インスタンスが保持している設定済みモデルに差し替えるだけです。

def validate_api_access(self) -> Tuple[bool, str]:
    try:
        self.client.messages.create(
            model=self.model,  # 設定済みのモデルを使う
            max_tokens=10,
            messages=[{"role": "user", "content": "Hello"}],
            timeout=10
        )
        return True, ""
    except Exception as e:
        return False, f"API validation failed: {str(e)}"

差分は1行の変更にとどまりますが、この形で提出されたプルリクエストは2本とも外部コントリビューターによるもので、いずれもマージされていません。1本目(PR #76)は2026年3月2日に提出され、19日後の2026年3月21日にクローズされました。2本目(PR #92)は2026年4月中旬に提出されたまま開いています。Issue #69自体にはメンテナーからのコメントが付いておらず、対応の方針や時期についての公式な言及は見当たりません。

現状でこのプロジェクトを使い続ける場合、選択肢は次の3つです。

選択肢手間効果
何もしない手間なし効果脆弱性検知自体は継続。誤検知が増えた状態でPRコメントを運用する
フォークしてvalidate_api_access()のモデルIDを書き換え、uses:を自分のフォークに向ける手間効果フィルタが復旧するが、フォークをmainの更新に追従させる保守が要る
PR #92のマージを待つ手間なし効果対応が完了すれば自動で解消するが、時期は未定

いずれの対処も一長一短で、チームのCI運用にどこまで手を入れられるかで選び方が変わります。誤検知が増えること自体は脆弱性の見落としには直結しませんが、PRコメントのノイズが増えるとレビュー負荷が上がる点は運用上の実害です。廃止予告(2025年12月19日)から実際の廃止(2026年2月19日)まで約2か月の猶予があったにもかかわらず、この期間中にAction側のコードは更新されなかったことになります。

Claude Code CLIの/security-reviewとの違い

同じ「security-review」という名前でも、GitHub Action版とCLIスラッシュコマンド版は実装が別物です。README内の統合ガイドも、CLIコマンドは「GitHub Actionと同じ分析能力を、Claude Codeの開発環境に直接統合したもの」と位置付けており、コードベースが共有されているとは説明していません。

観点GitHub Action版(anthropics/claude-code-security-review)CLIスラッシュコマンド版(/security-review)
実行トリガーGitHub Action版(anthropics/claude-code-security-review)PRオープン時にCI上で自動実行CLIスラッシュコマンド版(/security-review)開発者が手元で明示的に実行
誤検知フィルタGitHub Action版(anthropics/claude-code-security-review)Python製の第二段フィルタ(Claude API疎通確認あり)CLIスラッシュコマンド版(/security-review)プロンプト内の指示のみ(別APIコールなし)
今回のバグの対象かGitHub Action版(anthropics/claude-code-security-review)対象(validate_api_accessが廃止モデルを呼ぶ)CLIスラッシュコマンド版(/security-review)対象外
比較対象GitHub Action版(anthropics/claude-code-security-review)変更されたファイル(diff-aware scan)CLIスラッシュコマンド版(/security-review)origin/HEADとの差分

CLIコマンド側の検知対象やorigin/HEAD関連のエラー対処は冒頭で触れた記事にまとめています。GitHub Action版とCLI版を同じセキュリティレビューの仕組みだと考えていると、このバグの範囲を誤解しやすいので注意が必要です。

よくある質問

フィルタが無効化されても脆弱性の検知漏れは起きますか

いいえ。無効化されるのは検出後の誤検知除外処理だけで、第一段のスキャン自体はclaude-model入力で設定したモデルのまま継続します。影響は「本来除外されるはずの低リスク指摘までPRコメントに混ざる」ことです。

自分のプロジェクトが影響を受けているか確認する方法はありますか

ワークフローのジョブログでstderr出力を遡り、Claude API validation failedという警告が出ていないか確認します。upload-resultsを有効にしている場合は、結果JSON内のjustificationフィールドに"Claude filtering disabled"という文字列が含まれていないかを検索する方法もあります。

false-positive-filtering-instructionsを設定していれば影響を受けませんか

影響を受けます。false-positive-filtering-instructionsはフィルタの判定内容をカスタマイズする入力であり、フィルタが有効化されること自体を保証するものではありません。フィルタが有効化される前段のvalidate_api_access()が失敗すれば、カスタム指示ごと無効化されます。

まとめ

anthropics/claude-code-security-review(GitHub Action版のsecurity-review)は、誤検知フィルタの疎通確認に廃止済みのClaude Haiku 3.5モデルを固定で使っており、2026年2月19日の同モデル廃止以降、フィルタがログにも表れにくい形で無効化されています。ENABLE_CLAUDE_FILTERINGは既定で常にtrueのため、素のクイックスタート構成を使うすべてのプロジェクトが対象です。修正案(PR #92)はまだmainへ取り込まれておらず、対処するにはフォークして自前で修正を当てるか、マージを待つかの二択が現実的な選択肢になります。Claude Code CLIの/security-reviewはこのバグの対象外なので、両者を混同しないよう注意してください。

この記事を共有:XはてブLinkedIn