vibe codingの失敗事例 2025年9月7日

【権限バグ】AI生成コードに潜む時限爆弾

ある会社のCTO、Patric Edwardsは、自社で起きた事件についてこう証言しました。 **「ジュニア開発者が、AIとStackOverflowでユーザー権限システムを "vibe" 構築した」**。

川西智也

合同会社ロイヤルピース 代表

権限システムの時限爆弾

CTOの証言

ある会社のCTO、Patric Edwardsは、自社で起きた事件についてこう証言しました。

「ジュニア開発者が、AIとStackOverflowでユーザー権限システムを “vibe” 構築した」

その結果が、本章で紹介する事件です。


すべてのテストに合格

ジュニア開発者が作った権限システムは、一見すると完璧でした。

合格した項目:

チェック項目結果
開発環境での動作OK
単体テスト全て合格
統合テスト全て合格
初期QAテスト問題なし

すべての関門を通過し、システムは本番環境にデプロイされました。

チームは安心していました。「テストを通ったのだから、大丈夫だ」と。


2週間後の発覚

本番稼働から 2週間後、問題は発覚しました。

発見された問題:

非アクティブ化されたアカウントのユーザーが、特定のバックエンドツールにアクセス可能

退職した従業員、契約終了した外部協力者、アカウント停止されたユーザー——これらの人々が、本来アクセスできないはずのバックエンドツールに、依然としてアクセスできていたのです。


なぜテストで発見できなかったか

なぜ、すべてのテストを通過したのに、この問題は発見されなかったのでしょうか。

問題の根本:

テストは「正常系」を確認していました。

  • アクティブユーザーがアクセスできること → OK
  • 未認証ユーザーがアクセスできないこと → OK

しかし、「非アクティブ化されたアカウント」という エッジケース はテストされていませんでした。

AIが生成したコードは、「頼まれたこと」は実装しますが、「考慮すべきだが頼まれていないこと」は実装しません。


AI生成コードの権限チェックの穴

技術的に見ると、問題は権限チェックのロジックにありました。

問題のあるロジック(概念図):

if (user.role === "admin") {
  allowAccess();
} else if (user.role === "user") {
  allowAccess();
} else {
  denyAccess();
}

このロジックでは、user.isActive のチェックが欠落しています。

正しいロジック:

if (!user.isActive) {
  denyAccess();
  return;
}

if (user.role === "admin" || user.role === "user") {
  allowAccess();
} else {
  denyAccess();
}

この違いは微細ですが、セキュリティ上は決定的です。


シニアエンジニアの2日間

問題が発覚した後、修正はシニアエンジニアに任されました。

修正にかかった時間:2日間。

なぜ、単純な権限チェックの修正に2日もかかったのでしょうか。

理由:

  1. コードの意図を理解するのに時間がかかった
  2. AIが生成した複雑なロジックを解読する必要があった
  3. 他の場所に同様の問題がないか全体を確認した
  4. 安全な修正方法を慎重に検討した
  5. テストケースを追加した

ジュニア開発者が数時間で「生成」したコードを、シニアエンジニアが2日かけて「理解」し、修正したのです。


「Trust Debt(信頼負債)」

CTOのPatric Edwardsは、この事件を通じて新しい概念を提唱しました。

“Trust debt” — シニアエンジニアを「永続的なコード探偵」にしてしまう負債

Trust Debtとは:

  • vibe codingで生成されたコードへの「見えない不信感」
  • 「どこかに問題が隠れているかもしれない」という継続的な懸念
  • シニアエンジニアが常にコードを疑い、調査し続ける状態

これは、技術的負債とは異なる、心理的・組織的な負債 です。


時限爆弾の本質

この事件は、vibe codingの問題を「時限爆弾」として捉えることの重要性を示しています。

時限爆弾の特徴:

  1. 最初は動く — テストも通る、QAも通る
  2. 問題は潜伏する — 特定の条件でのみ発現
  3. 発見が遅れる — 本番稼働後に発覚
  4. 影響が拡大する — 発見までの期間、被害が蓄積

権限システムの場合、2週間の間に、本来アクセスできないはずのデータに、不正なアクセスが行われていた可能性があります。


人間が見落とすもの、AIが見落とすもの

この事件は、人間とAIの「見落とし」の違いも示しています。

人間の開発者が見落としがちなもの:

  • タイポ(誤字脱字)
  • 構文エラー
  • ボイラープレートの書き忘れ

AIが見落としがちなもの:

  • ビジネスロジックの考慮
  • エッジケースの処理
  • セキュリティ上の意図

人間は「書き間違い」をしますが、経験があれば「考え忘れ」は少なくなります。

AIは「書き間違い」はしませんが、「頼まれていないこと」は一切考慮しません。


権限システムの重要性

権限システムは、あらゆるアプリケーションの中で最も重要なコンポーネントの一つです。

権限システムが守るもの:

  • ユーザーデータ
  • ビジネス機密情報
  • 金融情報
  • 個人情報
  • システム設定

権限システムに穴があれば、すべてが危険に晒されます。

だからこそ、権限システムだけは vibe codingで作ってはいけない のです。


この事例から学ぶべき教訓

権限システムの時限爆弾事件から学ぶべきことは以下の通りです。

  1. テストに合格しても安全とは限らない

    • エッジケースは網羅されていない可能性
  2. 権限システムはセキュリティの要

    • vibe codingで作るべきではない
  3. 「動く」ことと「正しい」ことは違う

    • 正常系が動いても、異常系で穴がある可能性
  4. Trust Debt(信頼負債)を認識せよ

    • vibe codedコードへの継続的な不信感
  5. シニアエンジニアのレビューは必須

    • 特にセキュリティクリティカルな領域では
  6. 「非アクティブ化」のテストを忘れるな

    • アカウント停止後のアクセス制御は必須

まとめ:重要ポイントの振り返り

  • ジュニア開発者がAIとStackOverflowで権限システムを構築
  • 開発環境、テスト、初期QAをすべてパス
  • 本番稼働2週間後に問題発覚
  • 非アクティブアカウントがバックエンドツールにアクセス可能
  • シニアエンジニアが2日かけて修正
  • 教訓:テストに合格しても安全とは限らない

参考リンク・出典

実践的なスキルを習得しませんか?

ブログで学んだ知識を、研修で実践に変えましょう。