ClaudeやCursorでバイブコーディングしたアプリを、これから有料クライアントに渡そうとしていますか。ちょっと待ってください。AIが生成したコードには予測可能なセキュリティ穴がある — APIキーが露出していたり、入力検証がなかったり、すべてのユーザーが他のユーザーのデータを見られるデフォルトデータベース権限。これらはエッジケースではありません。ほぼすべての初期段階のAI生成コードベースで起こります。
このガイドは、ローンチ前のセキュリティチェックリストです。実際のユーザーがアプリに触れる前に、ステップバイステップで従ってください。最も一般的なバイブコーディングスタック(Next.js + Supabase + Vercel)向けに書かれていますが、使用しているツールに関わらず原則は適用できます。
AIが生成したコードになぜセキュリティ問題があるのか
AIモデルは「動作するか?」を最適化しており、「安全か?」ではありません。Claudeに「ユーザーアカウント付きのタスクマネージャーを作って」と言うと、ユーザーを作成し、タスクを保存し、表示するコードが生成されます。自動的に行わないこと:ユーザーAがユーザーBのタスクを見られないようにすること、入力フィールドが悪意のあるスクリプトを受け入れられないようにすること、ブラウザの開発者ツールからAPIキーを隠すこと、エンドポイントを叩かれ続けるのを防ぐレート制限を追加すること。
これらはAIの失敗ではなく、プロンプトのギャップです。AIはあなたが求めたものを構築します。おそらくセキュリティは求めていなかったでしょう。機能に集中していたから。今が戻ってセキュリティを追加する時です。
ステップ1:環境変数を監査する
これはバイブコーディングアプリで最も一般的で、最も危険なミスです。プロジェクト内のすべてのファイルをハードコードされたAPIキー、データベースURL、またはシークレットについて確認してください。
何を探すべきか: sk-、eyJ、sbp_、supabase、postgres://で始まる文字列、または長くてランダムに見える文字列について、コードベースを検索してください。これらのファイルを特に確認してください:/appまたは/pagesディレクトリ内のすべてのファイル、あらゆるコンポーネントファイル、next.config.js、およびあらゆるユーティリティファイル。
修正: すべてのシークレットを環境変数に移動してください。Next.jsでは、NEXT_PUBLIC_で始まる変数のみがブラウザに公開されます。データベースURL、サービスロールキー、APIシークレットはこのプレフィックスを付けてはいけません。
# .env.local (このファイルは決してコミットしないでください)
SUPABASE_SERVICE_ROLE_KEY=your-secret-key
DATABASE_URL=postgres://...
# これらはブラウザに公開しても大丈夫です:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
確認: .gitignoreファイルに.env.localが含まれていることを確認してください。既にシークレットをGitにコミットしている場合、削除後もそれらは履歴に残っている — 露出したすべてのキーを即座にローテーション(再生成)してください。
ステップ2:Supabaseで行レベルセキュリティを有効にする
Supabaseを使用している場合、これは最も重要な単一ステップです。デフォルトでは、Supabaseテーブルにアクセス制限がありません — anonキーを持つ誰もが、すべてのテーブルのすべての行を読み書きできます。つまり、ユーザーAは簡単なAPI呼び出しでユーザーBのデータを見ることができます。
修正: すべてのテーブルで行レベルセキュリティ(RLS)を有効にしてから、アクセスを制限するポリシーを作成してください。
Supabaseダッシュボード → テーブルエディタ → 各テーブルを選択 → 「RLS Disabled」をクリックして有効にします。次にポリシーを追加してください:
ユーザーが自分のデータのみを見るべき一般的なアプリの場合、SELECTポリシーを作成してください:auth.uid() = user_id。INSERT、UPDATE、DELETEについても同様のポリシーを作成してください。
テスト: ユーザーAとしてログインし、APIを通じてユーザーBのデータにアクセスしてみてください。見ることができれば、ポリシーが間違っています。Supabaseにはポリシーを直接テストできるSQLエディタがあります。
一般的なAIのミス: Claudeは、anonキーとRLSポリシーの代わりにservice_roleキー(RLSをバイパス)を使用するSupabaseクエリを生成することがよくあります。クライアント側のコードがanomキーのみを使用していることを確認してください。サービスロールキーはサーバー側のコード(APIルート、サーバーアクション)にのみ存在し、決してブラウザに公開されてはいけません。
ステップ3:認証を適切に追加する
AIが生成した認証コードはしばしば機能しますが、ショートカットを使用しています。これらの特定の問題をチェックしてください:
セッション管理: セッションが有効期限切れになることを確認してください。認証設定が合理的なセッションタイムアウトを含むことを確認してください(Supabaseのデフォルトは一般的に問題ありませんが、確認してください)。ログアウトが単にローカルクッキーをクリアするのではなく、実際にセッションを無効にすることを確認してください。
パスワード要件: メール/パスワード認証がある場合、最小パスワード長(8文字以上)を強制してください。Supabaseはプロジェクト設定 → 認証 → パスワード要件で処理します。
保護されたルート: ユーザー固有のデータを表示するすべてのページに認証ミドルウェアが必要です。Next.js App Routerでは、有効なセッションをチェックし、認証されていないユーザーをログインページにリダイレクトするミドルウェアを作成してください。クライアント側のチェックのみに頼らないでください — ユーザーはAPIを直接叩くことでそれらをバイパスできます。
メール確認: Supabase Auth設定でメール確認を有効にしてください。これは偽のメールアドレスでアカウントを作成するのを防ぎ、アカウント有効性の基本的なレイヤーを追加します。
価値を得られていますか? 私たちはAIツール、ワークフロー、実践的なガイドについて、週1回の深掘り記事を公開しています。最初に受け取る読者に参加してください →
ステップ4:すべての入力を検証する
AIが生成したフォームは通常、基本的な検証(必須フィールド、メール形式)を持っていますが、悪意のある入力から保護することはほとんどありません。
追加すること:
すべてのAPIエンドポイントでサーバー側の検証。クライアント側の検証のみを信頼しないでください — APIに直接リクエストを送信することでバイパスできます。Zod(TypeScriptの場合)のような検証ライブラリを使用して、アプリが受け入れるすべてのデータについてスキーマを定義してください。
ブラウザに表示されるユーザー生成コンテンツ内のHTMLをサニタイズしてください。アプリにコメント、説明、またはブラウザでレンダリングされるテキストフィールドがある場合、DOMPurifyのようなライブラリを使用して危険なスクリプトを削除してください。これがないと、誰かが他のユーザーのセッションを盗むJavaScriptを注入できます(クロスサイトスクリプティング/XSS)。
アプリがファイルアップロードを受け入れる場合、ファイルアップロードサイズとタイプを制限してください。AIが生成したアップロードハンドラーには制限がないことが多く、誰かが2GBのファイルまたは実行可能ファイルをアップロードできることを意味します。サイズ制限を追加してください(ほとんどのアプリで5MBは合理的)し、ファイルタイプを実際に必要なもの(画像、PDFなど)に制限してください。
ステップ5:APIルートを保護する
アプリ内のすべてのAPIルートまたはサーバーアクションについて、これらの問題をチェックしてください:
すべてのエンドポイントで認証。 ユーザーデータを返したり変更したりするすべてのAPIルートは、最初にユーザーのセッションを確認する必要があります。AIはしばしば、誰からのリクエストも受け入れるAPIルートを生成します。
認証を超えた認可。 ユーザーがログインしていることを確認した後、彼らが要求している特定のリソースにアクセスできることを確認してください。「ユーザーAはログインしている」は「ユーザーAはユーザーBのプロフィールを編集できる」を意味しません。すべてのデータアクセスで所有権をチェックしてください。
レート制限。 レート制限がないと、誰かが1秒あたり数千のリクエストをAPIに送信でき、データをスクレイプするか、サーバーを圧倒することができます。rate-limiter-flexibleなどのライブラリを使用して基本的なレート制限を追加するか、Vercelの組み込みレート制限をEdge Functionsで使用してください。
HTTPメソッド。 APIルートが応答すべきHTTPメソッドのみに応答することを確認してください。POSTリクエストを処理するルートは、明示的に設計しない限り、DELETEリクエストにも応答すべきではありません。
ステップ6:デプロイメント設定を確認する
デプロイメントプラットフォームにはAIが設定しないセキュリティ設定があります。
Vercelの設定を確認: 「デプロイメント保護」を有効にする(プレビューデプロイメントを表示するために認証が必要 — クライアントが誤ってプレビューURLを共有するのを防ぐ)。トラフィック急増でアプリが予期しない課金を受ける場合に備えて、支出制限を設定してください。CORSヘッダーで許可されたドメインを設定してください。
カスタムドメインとSSL: クライアントにこれを配信している場合、カスタムドメインをHTTPSで設定してください。VercelとNetlifyはSSLを自動的に処理します。クライアントアプリを.vercel.appサブドメインで配信しないでください — 非専門的に見えて、クライアントは転送しづらいです。
ヘッダー: next.config.jsまたはvercel.jsonにセキュリティヘッダーを追加してください:X-Content-Type-Options: nosniff、X-Frame-Options: DENY(サイトがクリックジャッキングのためのiframeに埋め込まれるのを防ぐ)、Strict-Transport-Security(HTTPSを強制)。これらは攻撃のクラス全体を防ぐ1回の追加です。
ステップ7:最終セキュリティスキャンを実行する
クライアントに何かを渡す前に、これらの無料チェックを実行してください:
npm audit: プロジェクトディレクトリでnpm auditを実行してください。依存関係で既知の脆弱性にフラグを立てます。重大で高重大度の問題を修正してください。利用可能な場合は、自動修正についてnpm audit fixを実行してください。
Lighthouse: デプロイされたサイトをChromeで開き、DevToolsを開き、Lighthouseの監査を実行してください。「Best Practices」スコアを確認してください — HTTPSがない、脆弱なライブラリ、不安全なヘッダーのような一般的なセキュリティ問題をキャッチします。
手動テスト: 1人のユーザーとしてログインし、URLまたはAPI呼び出しを変更して別のユーザーのデータにアクセスしてみてください。空のフォーム、サイズの大きい入力、特殊文字(エンコードされたXSSペイロードなど)を送信してみてください。これらのいずれかが機能する場合、修正すべき問題があります。
ローンチ前チェックリスト
これを印刷して、公開前にすべての項目をチェックしてください:
- すべてのシークレットが環境変数内(ハードコードされたキーはない)
.env.localが.gitignore内にある(Gitの履歴にシークレットはない)- Supabase RLSがすべてのテーブルで有効化
- RLSポリシーがテスト済み(ユーザーAがユーザーBのデータを見られない)
- クライアント側のコードがanomキーのみを使用(サービスロールキーはサーバー側のみ)
- すべてのAPIルートで認証
- データアクセスで認可チェック(所有権確認)
- すべてのフォームで入力検証(クライアント側だけでなくサーバー側)
- ファイルアップロード制限(該当する場合、サイズとタイプ)
- APIエンドポイントのレート制限
- セキュリティヘッダー構成済み
npm audit実行済みで重大な問題は修正済み- カスタムドメインとSSL構成済み
- プレビューデプロイメントが保護されている
- マニュアルクロスユーザーデータアクセステスト合格
まとめ
バイブコーディングアプリを保護することは、セキュリティエキスパートになることではありません。AIが後ろに置いていく予測可能なギャップをキャッチするチェックリストを実行することです。上記のステップは2~4時間かかり、最も一般的な脆弱性を防ぎます。クライアント向けアプリの場合、これはオプションではありません — 専門的な仕事と責任の違いです。
初めてバイブコーディングアプリを構築している場合は、バイブコーディングへの完全なガイドから始めてください。ClaudeまたはCursorで使用するプロンプトを改善したい場合は、無料プロンプト最適化ツールを試してください。最高のコーディングツールの分析については、Claude CodeとCodexを参照してください。
これは私たちが毎週行うことです。 AIツール、ワークフロー、正直な見解についての1つの深掘り — ハイプなし、フィラーなし。参加してください →
開示:この記事の一部のリンクはアフィリエイトリンクです。個人的にテストして定期的に使用しているツールのみを推奨します。完全な開示ポリシーを参照してください。