
自然言語でAIに指示を出すだけで、驚くようなスピードでWebアプリやスクリプトを組み上げられるバイブコーディングが急速に普及しています。プログラミングの文法を1行ずつ書かなくても、プロンプトひとつで画面が動き、データベースが連携し、数時間でサービスが完成する体験はまさに開発の革命と言えます。
しかし、その圧倒的な開発スピードの裏側で、いま世界中のエンジニアやセキュリティ専門家が警鐘を鳴らしているのが「セキュリティ対策の欠落」です。ニュースでもWebサービスの不正アクセスや情報漏洩が頻繁に取り沙汰される中、「AIが書いたこのコードは本当に安全なのか」「他人のデータが勝手に閲覧できてしまうのではないか」と強い不安を感じている方も多いのではないでしょうか。
結論からお伝えすると、AIは「動くもの」を作る能力には極めて長けていますが、セキュリティ要件を指示されない限り「安全に動くもの」を自律的に配慮して作ることは得意ではありません。
この記事では、公的機関や専門機関が発表している信頼できるデータをもとに、バイブコーディングでセキュリティ脆弱性が混入する構造的な原因を解き明かします。さらに、AIエージェントの指示ファイル(ルール、マニュアル、スキル)をどのように設計・役割分担させれば、開発スピードを落とさずに堅牢なシステムを構築できるのか、実践的な3層防御モデルとそのまま使えるテンプレートを交えて詳しく解説します。
この記事で行うこと
- バイブコーディングに潜むセキュリティリスクと構造的な原因の整理
- セキュリティ調査データ(VeracodeやOWASP)に基づくAI生成コードの実態確認
- 安全な開発を実現するセキュア・バイブコーディングの基本原則の把握
- セキュリティ対策の記述先(ルール・SECURITY_DESIGN.md・スキル)の最適な役割分担の確立
- 開発現場ですぐに導入できるセキュリティ指示テンプレートの適用
前提条件・対象読者
- Cursor、Claude Code、Antigravity、WindsurfなどのAIコーディングツールやAIエージェントを活用している方
- Next.js、Python、Node.js、Supabase、FirebaseなどでWebサービスやAPIを開発している方
- 「動いてはいるがセキュリティに不安がある」「安全な設計ルールをAIにどう伝えればよいか知りたい」と感じている開発者・個人開発者
1. バイブコーディングでセキュリティ事故が起きる根本原因
バイブコーディングにおいて、なぜこれほどまでにセキュリティ脆弱性が問題視されているのでしょうか。その根本的な原因は、AIモデルの学習特性と開発者の心理的バイアスにあります。
「動くコード」と「安全なコード」の決定的な乖離
AIコーディング支援ツールは、プロンプトで与えられた「機能要件(〇〇のボタンを押したらデータが一覧表示される)」を満たすコードを最短距離で出力するように訓練されています。
米国のセキュリティ企業であるVeracode社が公表した調査報告(GenAI Code Security Report)によると、80種類のコード生成タスクを対象とした検証において、AIモデルの平均合格率は約62パーセント、脆弱性が検出された割合は約38パーセントでした。構文正解率(Syntax Correctness)はほぼ100パーセントに達しているにもかかわらず、約4割のタスクでセキュリティ上の欠陥が生じている実態が浮き彫りになっています。
なお、これは限定されたテストタスクにおける検証結果であり、Webアプリケーション全体の脆弱性発生率そのものを直接示すものではありません。しかし、「構文的に正しくエラーなく動くコード」と「攻撃に耐えうる安全なコード」の間には大きな乖離が存在し、AIの出力を無条件に信用することがいかに危険かを客観的に示しています。
AIは「画面が崩れず正常に動くコード」を完璧に出力できるため、開発者は「問題なく動いているから大丈夫だろう」と錯覚してしまいます。この「見た目の正常動作」と「内部の堅牢性」のギャップこそが、バイブコーディング最大のリスクです。
AIが特にやらかしやすい脆弱性ワースト4
Webアプリケーションの脆弱性基準であるOWASP Top 10やIPAの指針に照らし合わせると、AIが自律的にコードを書く際に特に見落としがちな脆弱性は以下の4つに集中しています。
認可・アクセス制御の欠落(Broken Access Control / BOLA)
AIは画面にデータを表示するAPIを作成する際、ログインしているユーザーが本当にそのデータの所有者であるかを確認する認可チェックを省略しがちです。たとえば、URLの末尾に含まれるID(/api/users/123/orders)を書き換えるだけで、他人の注文履歴や個人情報が丸見えになってしまう脆弱性(IDOR / BOLA)が典型例です。AIはリクエストされたデータを素直に取得するロジックを優先するため、アクセス権の検証ロジックが抜け落ちてしまいます。
機密情報(シークレット)のハードコードと公開設定ミス
外部サービスとのAPI連携を指示した際、AIは「手っ取り早く疎通確認を通すため」に、StripeのシークレットキーやSupabaseのサービスロールキー、OpenAIのAPIキーをプログラム内の定数やクライアント側JavaScriptに直接埋め込んでしまうことがあります。
さらに、Next.jsの NEXT_PUBLIC_ や Vite の VITE_ のように、ブラウザ側へ公開される環境変数プレフィックスに秘密鍵を設定してしまい、JavaScriptバンドル経由で誰でもAPIキーを閲覧できる状態になってしまう事故も多発しています。
入力バリデーション不備とインジェクション
ユーザーからの入力値を信頼し、SQLクエリやシェルコマンド、HTML出力にそのまま結合してしまうコードを出力することがあります。パラメータ化クエリ(プリペアドステートメント)や安全なORMを使用する指示を出さないと、古典的かつ致命的なSQLインジェクションやクロスサイト・スクリプティング(XSS)が容易に混入します。
存在しない架空パッケージの提案(パッケージ・ハルシネーション)
AIが存在しないライブラリ名を自信満々に提示し、開発者がそれをそのままインストールしようとする現象です。USENIX Securityなどのセキュリティ学会の研究でも報告されているとおり、悪意のある攻撃者がその架空のパッケージ名と同名のマルウェアを公式パッケージリポジトリ(npmやPyPI)に先回りして登録しておく攻撃手法(パッケージ・ハルシネーション悪用 / Slopsquatting)が現実の重大な脅威となっています。
2. セキュア・バイブコーディングの3大原則
バイブコーディングの持ち味である爆速の開発体験を損なうことなく、本番環境に耐えうる安全性を確保するためには、開発者自身が以下の3つの設計原則(セキュア・バイ・デザイン)を意識する必要があります。
原則1:後付けではなく最初から安全を要求する
米国のCISA(サイバーセキュリティ・インフラセキュリティ庁)や英国家サイバーセキュリティセンター(NCSC)が共同策定したAI開発ガイドラインでは、「AIはソフトウェアであり、ソフトウェアは初期設計から安全でなければならない(Secure by Design)」と明記されています。
機能がすべて完成した後に「セキュリティを強化して」とAIに指示しても、全体的なリファクタリングが発生してコードが破損したり、認証ロジックの不整合が起きたりします。プロンプトを投げる最初の段階から、認証・認可・バリデーションの境界線を定義しておくことが鉄則です。
原則2:最小権限と実行環境の隔離
AIエージェントにターミナル操作やコード実行を許可する場合、開発ホスト環境のすべてを明け渡してはいけません。
- 実行環境はDockerコンテナや隔離された開発用サンドボックス内で行わせる
- データベースの接続ユーザーには必要最低限の権限(管理者権限ではなく、特定テーブルへのSELECTやINSERTのみ)を割り当てる
- 本番データベースの接続情報や本番APIキーはローカル開発環境から完全に遮断する
原則3:動いた後の自動ガードレール
人間が数千行のAI生成コードを1行ずつ目視確認するのは現実的ではありません。バイブコーディングとセキュリティを両立する開発環境では、AIの自己レビューだけに頼るのではなく、静的解析ツール(SAST)やシークレットスキャナー、依存関係監査コマンド(npm audit や pip-audit)を組み込み、機械的に脆弱性をブロックする仕組みを導入しています。
3. 【徹底比較】セキュリティ対策はどこに書くべきか?
バイブコーディングを実践しているエンジニアが最も直面する実践的な疑問が、「セキュリティの指示は、スキルファイルに書くべきか?それともシステムデザインのように何かAI向けのマニュアルを作成してそこにセキュリティ項目を設けるべきか?」という点です。
結論から申し上げると、どれか1つのファイルにすべてを詰め込むのは悪手です。AIエージェントのコンテキスト保持能力と動作タイミングを考慮した「3層防御モデル」で役割分担させるのが、最も破綻せず高い効果を発揮します。
セキュリティ指示ファイルの3層防御モデル
| 防御層 | 配置ファイル例 | 読み込みタイミング | 主な役割と記載内容 |
|---|---|---|---|
| 第1層:常時ルール | AGENTS.md, .cursorrules, GEMINI.md | セッション開始時・常時 | 行動の絶対制約(レッドライン)。シークレット直書き禁止、破壊的コマンド禁止、外部パッケージの勝手な追加禁止 |
| 第2層:設計仕様書 | SECURITY_DESIGN.md, DEVELOPMENT_STANDARDS.md | 実装・機能追加時 | アーキテクチャの正解の型。UIにおける DESIGN.md と同じ。認証フロー、RLS定義、入力バリデーション規格 |
| 第3層:監査スキル | SKILL.md, 監査プロンプト・CI連携 | 実装完了・コミット前 | 辛口の検証とスキャン手順。OWASP観点での自己レビュー、静的解析コマンドの実行、コミット前点検 |
SECURITY.md と SECURITY_DESIGN.md の重要な違い
ここで実務上極めて重要なポイントがあります。
GitHubなどのオープンソースリポジトリでは、SECURITY.md というファイル名は「外部のセキュリティ研究者やユーザーが、脆弱性を発見した際の報告窓口や連絡先ポリシー(Security Policy)」を記載するファイルとして国際的に標準化されています。
そのため、AIエージェントに読み込ませる「プロジェクト内部のセキュリティ設計仕様書」は、ファイル名を SECURITY_DESIGN.md(または DEVELOPMENT_SECURITY_STANDARDS.md)として明確に区別して運用することを強く推奨します。これにより、外部向けのセキュリティポリシーと、開発・AI向けの技術設計マニュアルが混同される事故を防ぐことができます。
なぜ単一のファイルでは失敗するのか?
ルール(AGENTS.md等)だけに書いた場合の失敗
AIの常時コンテキストにはトークン制限があります。ルールファイルに「SQLインジェクション対策のコード例」や「SupabaseのRLSポリシーの全パターン」などを書きすぎると、コンテキスト長を過度に圧迫し、AIのプロンプト追従性(指示への集中力)が著しく低下します。また、具体的な設計パターンがブレやすくなります。
仕様マニュアル(SECURITY_DESIGN.md等)だけに書いた場合の失敗
プロジェクト直下にどれほど素晴らしいセキュリティ仕様書を置いても、AIは指示されないと自発的にそのファイルを読みに行かないことがあります。その結果、仕様書を無視した危険なコードが生成されてしまいます。
スキルファイル(監査)だけに書いた場合の失敗
コードが完成した後にしかセキュリティチェックが働かないため、最初に出力されたコードが穴だらけになり、後から膨大な修正・手戻りが発生して開発スピードが大きく低下します。
成功の黄金パターン
- ルール(
AGENTS.md)には、AIが絶対に破ってはならない行動原則と、「セキュリティ実装時は必ずSECURITY_DESIGN.mdを参照すること」という参照トリガーを記載する - プロジェクト直下の
SECURITY_DESIGN.mdには、そのシステムで採用している具体的なセキュリティ設計標準(正解の型)を定義する - 実装完了時やコミット前に、スキルファイルや監査プロンプト、静的解析ツールを呼び出して厳格に自動点検する
この連携により、AIは無駄なトークンを浪費することなく、安全なコードを一発で生成し、最後に漏れがないかを客観的にチェックできるようになります。
4. そのまま使える!セキュア開発用テンプレート集
ここからは、皆さんのプロジェクトですぐに導入できる具体的なテンプレートを3つ提供します。プロジェクトの規模や利用しているツール(Cursor、Claude Code、Antigravity等)に合わせてコピー&ペーストしてご活用ください。
テンプレート1:常時ルール用セキュリティ行動規約
プロジェクトのルートにある AGENTS.md、CLAUDE.md、または .cursorrules に追記する設定です。AIの行動に対する厳格なレッドラインを引きます。
## セキュリティ・行動ガードレール(絶対厳守)
1. 機密情報(シークレット)の保護:
- APIキー、秘密鍵、パスワード、接続文字列をコードや設定ファイルに直接ハードコードしないこと。
- 必ず環境変数(`.env` 等)を介して取得し、クライアントサイド(ブラウザ)へ露出させない構成にすること。
- `NEXT_PUBLIC_` や `VITE_` などの公開用環境変数に、秘密鍵やサーバー専用シークレットを設定しないこと。
- `.env` や認証情報を含むファイルを Git コミット対象に含めないこと。
2. 外部パッケージ・ライブラリの安全確認:
- 新規の依存関係(npm / pip 等)を提案・導入する際は、パッケージ名が実在し、広く使われている正規のものであるかを確認すること。架空のパッケージを捏造しないこと。
3. セキュア・バイ・デザインの遵守:
- データベースアクセス、認証・認可、APIエンドポイントを実装する際は、必ずプロジェクト直下の `SECURITY_DESIGN.md` を参照し、そこに定義された設計仕様を遵守すること。
4. 破壊的操作の事前確認:
- データベースのテーブル削除(DROP)、本番データの上書き、不可逆なファイル削除を行うコマンドは、ユーザーの明示的な許可なく実行しないこと。
テンプレート2:システム設計仕様書(SECURITY_DESIGN.md)
プロジェクトのルートに SECURITY_DESIGN.md として保存し、UIにおける DESIGN.md のように「このシステムにおけるセキュリティの標準仕様」として機能させます。
# システムセキュリティ設計仕様書 (SECURITY_DESIGN.md)
本ドキュメントは、本プロジェクトにおけるセキュリティ設計および実装の統一基準を定義する。AIエージェントはコード生成時、本仕様を最優先で満たすこと。
## 1. 認証・認可(Authentication & Authorization)
- 認証基盤: Supabase Auth(または NextAuth / Clerk)を使用する。
- データベースのアクセス制御(Supabase RLS):
- テーブル作成時は必ず Row Level Security (RLS) を明示的に有効化すること(`ALTER TABLE [テーブル名] ENABLE ROW LEVEL SECURITY;`)。
- ダッシュボードのGUI作成以外(SQL Editorやマイグレーションファイル)ではRLSが初期無効になるため、ポリシーとセットで定義すること。
- すべてのデータ取得・更新 API は、リクエスト元ユーザーの所有権(`auth.uid() = user_id`)を検証すること。
- URLパラメータやリクエストボディの ID を無検証で信用した直接オブジェクト参照(IDOR)を禁止する。
## 2. 入力バリデーションとサニタイズ
- すべての外部入力(APIリクエスト、フォーム送信、クエリパラメータ)は、スキーマ検証ライブラリ(Zod 等)を用いて型と長さを厳密に検証すること。
- 検証に失敗した入力は即座に 400 Bad Request で拒否し、不正なデータを内部ロジックに流さないこと。
## 3. データベースアクセス
- Raw SQL の文字列連結(テンプレートリテラルによる変数展開等)は一切禁止とする。
- 必ずパラメータ化クエリ(Prepared Statements)または安全な ORM(Prisma / Drizzle / Supabase クライアント)を使用すること。
## 4. エラーハンドリングとレスポンス
- クライアントへのエラーレスポンスに、データベースのエラーメッセージ、内部スタックトレース、サーバーの内部パスを含めないこと。
- ユーザーには汎用的なエラーメッセージ(例: 「リクエストを処理できませんでした」)のみを返し、詳細ログはサーバー側でのみ安全に記録すること。
## 5. 通信・セキュリティヘッダー
- CORS 設定において、ワイルドカード(`*`)による無制限の許可を行わないこと。許可するオリジンを明示的に指定すること。
- 機密データを扱う Cookie には、必ず `HttpOnly`, `Secure`, `SameSite=Lax`(または Strict)を付与すること。
テンプレート3:セキュリティ監査用プロンプト・チェックリスト
機能の実装が一通り終わった際や、プルリクエストを作成する前に、AIエージェントへ向けて実行させる監査プロンプトです。機械的な静的解析と組み合わせることで最大の効果を発揮します。
以下のコードおよび変更内容について、セキュリティ監査エージェントとして厳格なクロスレビューを実施してください。
「問題なし」と安易に妥協せず、以下の観点から脆弱性がないかを検証し、懸念点があれば具体的な修正コードを提示してください。
【監査チェックリスト】
1. 認可不備(BOLA/IDOR): 他人のデータや非公開データに不正アクセスできる穴はないか?
2. シークレット漏洩: APIキー、トークン、接続文字列が平文で含まれていないか?公開環境変数への誤設定はないか?
3. インジェクション: SQL、OSコマンド、HTML生成に入力値が無害化されずに渡されていないか?
4. RLSとDB権限: データベースのポリシーやアクセス権限は適切に設定されているか?(RLS有効化コマンドの漏れはないか?)
5. エラー露出: スタックトレースや内部情報が外部レスポンスに漏れ出していないか?
6. パッケージ信頼性: 追加されたライブラリは実在し、脆弱性情報(CVE)がないか?
【併せて実行すべきコマンド】
- 依存関係の脆弱性検査: `npm audit` または `pip-audit`
- シークレットスキャン: `git diff` による平文コミットの事前点検
5. よくある失敗とトラブルシューティング(FAQ)
Q1:プロンプトに「安全に作って」と一言添えるだけでは不十分ですか?
不十分です。AIにとって「安全に」という言葉は抽象的すぎます。「安全に」とだけ指示した場合、AIは一般的な例外処理(try-catch)を追加する程度で終わってしまい、ビジネスロジックに起因する認可不備(BOLA)やRLSの漏れなどの深層的な脆弱性には対処できません。
「OWASP Top 10のアクセス制御不備を防ぐため、リクエストユーザーのIDとデータの所有者IDが一致するか検証するロジックを必ず含めてください」のように、具体的な脅威と対策を指定する必要があります。
Q2:SupabaseやFirebaseを使っていれば自動的に安全になりますか?
自動的には安全になりません。これはバイブコーディングで最も多い落とし穴のひとつです。
BaaS(Backend as a Service)は強力なセキュリティ機能を備えていますが、それは「正しく設定して初めて機能するもの」です。
たとえばSupabaseでは、管理画面(Dashboard)のTable Editorから手動でテーブルを作成した場合は自動的にRow Level Security(RLS)が有効化されます。しかし、SQL Editorからスクリプトを実行したり、AIに生成させたマイグレーションファイルからテーブルを作成した場合は、明示的に ENABLE ROW LEVEL SECURITY を指定しない限りRLSが無効のままテーブルが作成されます。
AIに「Supabaseを使ってテーブルを作って」と指示すると、疎通確認を優先してRLSの有効化やポリシー定義を省略したSQLを出力することが多いため、必ず SECURITY_DESIGN.md にRLS有効化のルールを定めておく必要があります。
Q3:ルールが多すぎてAIが指示を無視してしまいます
常時読み込ませるルール(AGENTS.md や .cursorrules)のテキスト量が多すぎると、AIの注意力が分散し、指示の無視が発生します。
対処法として、常時ルールには「絶対禁止事項(シークレット禁止、破壊コマンド禁止)」と「参照すべき仕様書のパス(SECURITY_DESIGN.md)」のみを簡潔に記載し、具体的なコード例や詳細なポリシーは各ファイルに分割してください。実装する機能に関連するタイミングでのみ、必要な仕様書を読み込ませるアーキテクチャが最も安定します。
まとめ
バイブコーディングは、アイデアを驚異的なスピードで形にできる素晴らしい技術です。しかし、「動くこと」と「安全であること」は全く別の要件であり、AIに任せきりにしたコードには高確率で深刻な脆弱性が潜んでいます。
スピードと安全性を両立させるための鍵は、プロンプトを工夫することだけに頼るのではなく、「3層防御モデル」という仕組みを作ることです。
AGENTS.mdやルールファイルで、AIの行動に厳格なレッドラインを引くSECURITY_DESIGN.mdで、プロジェクト固有のセキュアな設計標準を定義する- 完成時に監査プロンプトや静的解析ツールを通し、客観的に脆弱性を排除する
この防壁を一度整えてしまえば、セキュリティの不安に怯えることなく、バイブコーディングの圧倒的な開発パワーを最大限に引き出すことができます。ぜひご自身のプロジェクトに SECURITY_DESIGN.md を導入し、安全で堅牢なセキュア・バイブコーディングを実践してみてください。
次に読むおすすめ記事

生成AIの最新動向やAIエージェント(Antigravity / Codex / Claude Code)、コーディング支援ツールの実践的な活用法を体系的に学びたい方は、以下の完全ガイドもあわせて参考にしてください。


