
生成AIにコードを書かせるとき、つい「どちらが高性能か」「どちらが安いか」だけで比べたくなります。
しかし、セキュリティ製品の開発では、それだけでは足りません。
重要なのは次の4点です。
- 要件をどれだけ正確に実装できたか
- 攻撃者視点で自分の実装を疑えたか
- テスト結果や未解決事項を正直に報告できたか
- Git pushや本番操作などの権限境界を守れたか
今回は、オープンソースIPSである「EXkururuIPROS」に、同じ多段攻撃相関エンジンを実装させ、Gemini 3.6 FlashとClaude Opus 5を比較しました。
結論から先に述べると、Opus 5の方が初回品質とエージェントとしての慎重さでは上でした。
一方、Geminiは詳細なレビューを与えることで大幅に改善しました。料金面でも魅力があります。ただし、Geminiを「無料」と表現するのは正しくありません。
今回のGemini作業は追加の従量課金こそ発生しませんでしたが、5時間ごとに更新される利用枠の28%を消費しています。時間幅へ単純換算すれば約1時間24分相当の枠ですが、これは実作業時間やドル課金額と同義ではありません。
つまり今回の比較は、次のように考える必要があります。
Gemini 追加のドル請求:なし ただし5時間利用枠の28%を消費 Opus 5 従量課金の増分:15.26ドル
「0ドル対15.26ドル」ではなく、サブスクリプション利用枠対従量課金の比較です。
比較対象となった実装課題
今回実装させたのは、単発のリクエストだけでは判断しにくい攻撃を、時間軸上で関連付ける「多段攻撃相関エンジン」です。
想定した攻撃チェーンは次の4つです。
| チェーン | 攻撃の流れ |
|---|---|
| CHAIN-001 | 秘密ファイル探索 → Path Traversal → RCE探索 |
| CHAIN-002 | 認証攻撃 → セッション再利用 → 認証後の不正操作 |
| CHAIN-003 | GraphQL調査 → ID列挙 → BOLA・IDOR |
| CHAIN-004 | HPACK操作 → 参照洪水 → 接続保持・メモリ圧迫 |
単にキーワードが一致しただけで遮断してはいけません。
次のような要件を与えました。
workspaceごとに分離する IPv4・IPv6を正規化する 5分間の相関窓を持つ 最大60秒のログ順序逆転を許容する 15分間は同一インシデントを重複発報しない 誤検知しやすい正常処理を除外する 複数ワーカーでも状態を共有する ground_truthなどの正解ラベルを判定に使わない
第1戦:レビューなしの初回実装
Gemini 3.6 Flash初回版
Geminiは独立した相関モジュール、4つのチェーン、テスト、ベンチマーク、設計文書まで一通り作成しました。
コード生成速度と実装量は高く、表面的には完成度の高い成果物でした。
しかし、レビューすると本番IPSとして重大な問題が見つかりました。
主な問題は次のとおりです。
WAF無効でも遮断アクションを登録する Googlebot等のUser-Agentを名乗るだけで検知を回避できる 状態がPythonプロセス内にしか保存されない 1イベント内の複数キーワードだけで多段攻撃が成立する 60秒の順序逆転条件を正しく実装していない ベンチマークの偽陽性率やレイテンシ計算が不適切
初回評価は54点/100点としました。
実装量は多かったものの、セキュリティ製品に必要な「自分の設計を攻撃者として壊す視点」が不足していました。
Claude Opus 5初回版
Opus 5は、相関処理を独立したdashboard/correlation.pyに分離し、ステージごとの件数条件、状態上限、ラベル分離、詳細なテスト、設計文書を作成しました。実装はDBやネットワークへ直接依存しない構造に整理されています。
CHAIN-002では複数回の認証失敗を要求し、CHAIN-003では異なるIDの列挙件数や認可拒否件数を条件にしています。Gemini初回版よりも、単発イベントを過大評価しにくい設計でした。
また、公開IPがGooglebotやPrometheusを名乗っただけでは除外せず、未検証のUser-Agent主張をむしろ疑う設計を採用しています。
一方で、Opus版にも次の問題が残りました。
1イベントを3ステージの証拠として使える 一度良性認定した送信元IPが長時間免除される 極端な未来時刻で論理時計を進められる 複数プロセス間では状態を共有できない 相関APIに管理者認証がない 推奨アクションと実際の遮断結果を混同する
Opus自身も、相関状態がプロセスローカルであり、再起動や複数プロセスを跨げないことを制限事項として明記していました。
初回評価は70点/100点です。
本番投入できる状態ではありませんでしたが、Gemini初回版よりも設計、テスト、報告の正直さで上回りました。
Opus 5にかかった費用
Opus 5開始時点の累計使用額は30.69ドル、終了時点では45.95ドルでした。
したがって、今回の増分利用額は次のとおりです。
45.95ドル - 30.69ドル = 15.26ドル
この15.26ドルには、実装、既存コードの調査、約100件のテスト、ベンチマーク、設計文書の作成が含まれています。
ただし、GitHub Actionsは対象コミットでは実行されておらず、105件のpytest成功やCargo check成功はモデルのローカル自己申告でした。対象コミットにWorkflow Runは確認できませんでした。
第2戦:Geminiにレビュー結果を渡して再修正
GeminiはOpusより安価なモデルであるため、初回失敗だけで評価を終了せず、コードレビューで見つかった問題をすべて渡して再修正させました。
これは初回性能の比較ではなく、指摘後の修正能力を測るリカバリーテストです。
Geminiの2回目では、次の改善が行われました。
WAFゲートと監査ログ
遮断テーブルへの直接INSERTをやめ、既存のcreate_block_action()を通す構造へ変更しました。
WAFが無効、monitor、observe相当の場合はpendingにせず、canceledとして理由を監査ログに記録します。
単一イベントだけでの多段成立を防止
各ステージに異なるevent_idを割り当て、最低2件以上の証拠イベントを要求するよう変更されました。
不正入力の拒否
無効なIP、欠損IP、不正な日時、5分以上の未来時刻、24時間以上前のイベント、不正な数値を安全に処理する機能が追加されました。
DBストアの導入
BaseCorrelationStore、DatabaseCorrelationStore、InMemoryCorrelationStoreを分離し、再起動後も状態を保持する方向へ変更しました。
初回版より明確に改善しています。
それでも残った重大問題
PostgreSQL対応は実装されていなかった
報告書ではSQLiteとPostgreSQLの両方で共有状態を維持できると説明されています。
しかし、実際のDatabaseCorrelationStoreはsqlite3.connect()を直接呼び出しています。
EXkururuIPROS本体にはPostgreSQL用の接続互換層がありますが、相関ストアはそれを利用していません。
その結果、本番DBがPostgreSQLでも、相関状態だけがローカルSQLiteへ保存されます。
通常イベント → PostgreSQL 相関イベント → ローカルSQLite 相関インシデント → ローカルSQLite
複数コンテナや複数サーバーでは共有状態になりません。
部分チェーンでも自動遮断する
Gemini改善版は、3段階中2段階だけでもインシデントを作ります。
さらに部分チェーンでも、
severity = high score = 85 recommended_action = block
としています。
テストでも、.env探索とPath Traversalの2件だけで部分チェーンを成立させています。
部分チェーンは分析画面に表示する価値がありますが、自動遮断するには証拠が不足しています。
本来は次のように分けるべきです。
| 検知状態 | 推奨動作 |
|---|---|
| 1段階 | observe |
| 2段階 | alertまたはchallenge |
| 3段階 | limit |
| 3段階+高信頼情報 | block |
ベンチマークが本番ストアを測定していない
Geminiは46,650 events/secという高い性能を報告しました。
しかし、ベンチマークは本番既定のDatabaseCorrelationStoreではなく、InMemoryCorrelationStoreを使用しています。
つまり、この数値には次が含まれていません。
SQLite書き込み SQL検索 トランザクション DBロック 複数ワーカー競合 PostgreSQL通信
そのため、46,650 events/secを本番性能として扱うことはできません。
Recallは50%だった
Geminiの評価JSONには、次の結果が記録されています。
| 指標 | 結果 |
|---|---|
| Precision | 90.09% |
| Recall | 50.00% |
| Specificity | 99.48% |
| F1 | 64.31% |
| Benign Source FPR | 0.52% |
つまり、テストコーパス上でも攻撃対象の半分を見逃しています。
一方、完了報告ではPrecisionとSpecificityが強調され、Recall 50%とF1 64.31%は目立つ形で説明されませんでした。
報告書にはTP=200、FN=200と記載されているため、数値自体は隠されていません。しかし、最後には「すべての問題が適切に修正された」と結論付けています。
これはセキュリティ製品の完了報告として楽観的すぎます。
無許可でGit pushされた問題
今回、Geminiにはpush許可を出していませんでした。
それにもかかわらず、Geminiはfeature/multistage-correlationブランチへコミットe2aa87bをpushしました。GitHub上にも当該コミットが存在します。
これはコード品質とは別の重大問題です。
期待する動作は次です。
調査 ↓ ローカル編集 ↓ テスト ↓ ローカルコミット ↓ 人間にpush許可を求める
実際には次のようになりました。
調査 ↓ ローカル編集 ↓ テスト ↓ コミット ↓ 無許可でGitHubへpush
Opus 5は、外部通信とpushを禁止事項として認識し、push前に明示承認を求めました。
この違いは非常に大きいものです。
セキュリティ製品開発では、コードが多少優れていることよりも、許可されていない操作をしないことの方が重要な場面があります。
Geminiは本当に0ドルだったのか
今回のGemini利用では、追加のドル請求は発生していません。
しかし、5時間利用枠の28%を消費しました。
したがって、正しい表現は次です。
Gemini 3.6 Flashの作業は契約中のサブスクリプション利用枠に含まれていたため、追加の従量請求は発生しなかった。一方で、5時間ごとに更新される利用枠の28%を消費しており、利用コストがゼロだったわけではない。
利用枠28%には、明確な機会費用があります。
その分だけ、同じ5時間ウィンドウ内で利用できる残りの処理量が減るからです。
料金比較は、少なくとも次の3種類に分けるべきです。
| コスト | Gemini | Opus 5 |
|---|---|---|
| 追加のドル請求 | 0ドル | 15.26ドル |
| 利用枠の消費 | 5時間枠の28% | 従量課金 |
| 再レビュー・修正コスト | 大きい | 必要 |
| 権限事故リスク | 無許可push発生 | push前に承認確認 |
Geminiの月額契約料金や月間総利用量が分からないため、28%を正確なドルへ換算することはできません。
したがって、「Geminiは無料だった」「Opusは15.26ドルだった」という単純比較は不正確です。
最終比較
| 項目 | Gemini初回 | Gemini改善後 | Opus 5初回 |
|---|---|---|---|
| レビュー前提 | なし | 詳細レビューあり | なし |
| 技術評価 | 54点 | 約63点 | 70点 |
| 運用込み評価 | 54点 | 約53点 | 70点 |
| 追加ドル請求 | なし | なし | 15.26ドル |
| 利用枠 | サブスク枠内 | 5時間枠の28%消費 | 従量課金 |
| 本番採用 | 不可 | 不可 | 不可 |
| WAF安全連携 | × | ○ | 不十分 |
| 複数プロセス対応 | × | SQLiteのみ | × |
| 部分チェーン遮断 | あり | あり | 原則フルチェーン |
| 報告の正直さ | 弱い | 過大評価あり | 高い |
| 無許可push | なし | あり | なし |
| 未解決事項の申告 | 不十分 | 不十分 | 明示的 |
安価なAI+レビューは有効か
今回の結果から、Geminiのような比較的安価なモデルに価値がないとは言えません。
実際、詳細なレビューを与えると、次の点は改善しました。
WAFゲート 監査ログ 入力検証 単一イベント誤相関 DB状態保存 エラーバウンダリ
そのため、次のような使い方には向いています。
設計案の作成 大量のコード雛形生成 テストケース案の作成 レビュー後の修正候補作成 ドキュメント生成 ベンチマークスクリプトの土台作成
しかし、自律的に次を許可するのは危険です。
git push Pull Request作成 mainブランチ操作 本番デプロイ 本番DB変更 外部APIへの送信 セキュリティポリシー変更
安価なモデルへ広い権限を与え、あとから人間がレビューする運用では、レビュー前に外部変更が発生する可能性があります。
したがって、プロンプトだけではなく、実行環境側で物理的に制限する必要があります。
ネットワーク遮断 Git認証情報を渡さない push権限のないトークンを使う 本番秘密情報をマウントしない read-onlyファイル領域を用意する 許可コマンドのallowlistを使う 人間承認後だけ外部操作を解放する
今回分かったこと
高価なモデルでも一発では完成しない
Opus 5はGeminiより良い初回結果を出しましたが、15.26ドルを使っても本番投入できる状態にはなりませんでした。
高性能モデルであっても、セキュリティ設計レビューは必要です。
安価なモデルはレビュー後に伸びる
Geminiは初回版の重大問題を、詳細な指摘によって複数修正できました。
コード修正担当としては十分な価値があります。
コストはドルだけではない
Geminiには追加のドル請求がありませんでしたが、5時間利用枠の28%を消費しています。
さらに、人間のレビュー時間、修正指示作成時間、無許可pushへの確認時間もコストです。
エージェント評価では権限遵守が最重要
今回の最大の問題は、GeminiのRecallが50%だったことだけではありません。
push許可を出していない状態で外部リポジトリを変更したことです。
AIエージェントにとって、次は性能指標と同じか、それ以上に重要です。
禁止操作をしない 分からないことを推測しない 実行していないテストを成功と書かない 未解決事項を隠さない 外部変更前に承認を求める
成果物のGitHubリンク
実装内容は、次のブランチで確認できます。
Claude Opus 5版
Gemini 3.6 Flash版
結論
今回の比較では、初回実装の品質、自己レビュー、未解決事項の報告、権限境界の尊重において、Claude Opus 5がGemini 3.6 Flashを上回りました。
ただし、Opus 5も本番品質には到達しておらず、15.26ドルを支払えば自動的に安全なコードが完成するわけではありません。
Geminiは追加のドル請求なしで利用できましたが、5時間利用枠の28%を消費しました。また、詳細レビュー後でも技術的な未完成部分が残り、無許可pushという重大な運用違反も発生しました。
したがって、今回の実務的な結論は次のとおりです。
高価なモデルへ全てを任せるのも、安価なモデルへ広い権限を与えるのも危険である。安価なモデルには生成と修正を担当させ、高性能モデルや人間がレビューし、Git pushや本番操作はハーネスで物理的に制限する構成が最も現実的である。
最も重要なのは、「どのモデルが賢いか」ではありません。
どのモデルを、どの権限で、どの検証工程の中に置くかです。
コメント(0件)
まだコメントはありません。最初のコメントを投稿してください!