はじめに
「バイブコーディング」で、驚くほど簡単にWebアプリケーションが作れる時代になりました。
私自身今まで6回以上Webアプリを作成し、
計10万行はAIにコードを書いてもらったと思いますが、
すべてのコードを読み切れているかと言われたら正直答えはNoです。

その中でも特に気をつけないといけないのが、
「セキュリティとコスト」だと私は思っているので、
この記事では、バイブコーディングで作成したアプリを公開する前に確認すべきポイントをチェックリスト形式でまとめました。
もしこの記事の内容でここも気をつけたほうが良いなどありましたら、
コメントいただけるとよりよい記事になるのでご協力ください![]()
対象読者
- バイブコーディングでWebアプリを作った初心者
- AIが生成したコードのレビュー方法がわからない方
- 「動くけど、これで公開して大丈夫?」と不安な方
なぜこのチェックリストが必要なのか
AIは「動くコード」は書けますが、以下のような問題を見落とすことがあります。
- APIキーをフロントエンドに露出させてしまう
- 他人のデータにアクセスできてしまう実装
- 予算アラートなしでクラウドを使用し、高額請求が発生
最悪の場合、数百万円の請求や個人情報漏洩につながる可能性があります。
優先度の見方
このチェックリストでは、以下の優先度を設定しています。
| マーク | 優先度 |
|---|---|
| 🔴 | 必須 |
| 🟡 | 推奨 |
フロントエンド編
セキュリティ
APIキーの露出 🔴
JavaScriptのコードにAPIキーが含まれていると、誰でもそのキーを悪用できてしまいます。
- JavaScriptのコード内にAPIキーが含まれていないか
- ブラウザの開発者ツールでAPIキーが見えないか
-
環境変数が
NEXT_PUBLIC_等でうっかり公開されていないか
Next.jsでは
NEXT_PUBLIC_プレフィックスを付けた環境変数はクライアント側に公開されます。APIキーには絶対に使わないでください。
XSS(クロスサイトスクリプティング) 🔴
ユーザーが入力した内容をそのまま表示すると、悪意のあるスクリプトが実行される危険があります。
- ユーザー入力をそのままHTMLに表示していないか(エスケープ処理)
-
dangerouslySetInnerHTML(React)やv-html(Vue)を安易に使っていないか
認証トークンの保存場所 🔴
JWTなどの認証トークンをlocalStorageに保存すると、XSS攻撃でトークンを盗まれる危険があります。
-
認証トークンを
localStorageに保存していないか -
可能であれば
HttpOnly属性付きのCookieを使用しているか - トークンの有効期限が適切に設定されているか
// ❌ 危険な実装(XSSでトークンが盗まれる可能性)
localStorage.setItem('token', jwtToken);
// ⭕ より安全な実装(HttpOnly Cookieを使用)
// サーバー側でSet-Cookieヘッダーを設定
// Set-Cookie: token=xxx; HttpOnly; Secure; SameSite=Strict
![]()
localStorageはJavaScriptからアクセス可能なため、XSS脆弱性があるとトークンが盗まれます。HttpOnly属性付きCookieはJavaScriptからアクセスできないため、より安全です。
認証状態の管理 🔴
ログインが必要なページに、ログインせずアクセスできてしまうと大問題です。
- ログインしていない状態で保護されたページにアクセスできないか
CSRF(クロスサイトリクエストフォージェリ)対策 🟡
別のサイトから勝手にリクエストを送られ、ユーザーの意図しない操作が実行される攻撃です。
- 重要な操作(削除、購入等)でCSRFトークンを使っているか
-
Cookieに
SameSite属性が設定されているか
入力チェック 🟡
想定外の入力でアプリが壊れないかを確認します。
- フォームに何も入力せず送信した時の動作確認をしたか
- 異常に長い文字列を入力した時の動作確認をしたか
パフォーマンス
API呼び出し 🟡
無駄なAPI呼び出しは、パフォーマンス低下と課金増加の原因になります。
- ボタン連打で同じAPIが何度も呼ばれないか
- 画面表示のたびに同じAPIを何度も呼んでいないか
動作確認方法
| 確認項目 | 方法 |
|---|---|
| APIキーの検索 | コード全体で sk- api_key apiKey secret を検索 |
| XSS | 入力欄に <script>alert('test')</script> と入れてみる |
| トークン保存 | ブラウザの開発者ツール → Application → Local Storage を確認 |
| 認証バイパス | ログインせずに直接URL(/dashboard等)にアクセス |
| CSRF | 別タブでログアウトした状態でフォーム送信してみる |
| 連打テスト | 送信ボタンを素早く10回押してみる |
バックエンド編
セキュリティ
APIキー・パスワードの管理 🔴
バックエンドでも、APIキーの管理は最重要事項です。
-
APIキーがコードに直接書かれていないか(
sk-xxxx等の文字列がないか) -
.envファイルがGitにコミットされていないか(.gitignoreに含まれているか) - ログにAPIキーやパスワードが出力されていないか
他人のデータへのアクセス(認可) 🔴
URLのIDを変えるだけで他人のデータが見れてしまう実装は、非常に危険です。
- URLのIDを変えるだけで他人のデータが見れないか
- 他人のデータを削除・編集できないか
// ❌ 危険な実装
app.get('/users/:id', (req, res) => {
const user = await db.users.findById(req.params.id);
res.json(user);
});
SQLインジェクション 🔴
ユーザー入力を直接SQLに埋め込むと、データベースを乗っ取られる危険があります。
- ユーザー入力を直接SQLに埋め込んでいないか
- プレースホルダ(プリペアドステートメント)を使っているか
// ❌ 危険な実装
const query = `SELECT * FROM users WHERE id = ${userId}`;
// ⭕ 安全な実装(プレースホルダを使用)
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);
CORS設定 🔴
CORS(Cross-Origin Resource Sharing)の設定が不適切だと、意図しないサイトからAPIにアクセスされる危険があります。
-
Access-Control-Allow-Originに*(ワイルドカード)を設定していないか - 許可するオリジンを明示的に指定しているか
-
認証が必要なAPIで
Access-Control-Allow-Credentials: trueを使う場合、オリジンが*になっていないか
// ❌ 危険な実装(すべてのオリジンを許可)
app.use(cors({ origin: '*' }));
// ❌ 危険な実装(認証ありで全オリジン許可は動作しないが、意図として危険)
app.use(cors({ origin: '*', credentials: true }));
// ⭕ 安全な実装(許可するオリジンを明示)
app.use(cors({
origin: ['https://myapp.com', 'https://www.myapp.com'],
credentials: true
}));
// ⭕ 開発環境と本番環境で分ける
const allowedOrigins = process.env.NODE_ENV === 'production'
? ['https://myapp.com']
: ['http://localhost:3000'];
app.use(cors({ origin: allowedOrigins, credentials: true }));
特にAPIサーバーとフロントエンドが別ドメインの場合、CORS設定は必須です。AIが生成するコードでは
origin: '*'が使われがちなので要注意です。
HTTPS 🔴
本番環境では必ずHTTPSを使用してください。
- 本番環境でHTTPS(SSL証明書)が有効になっているか
セキュリティヘッダー 🟡
適切なセキュリティヘッダーを設定することで、攻撃を防げます。
-
X-Frame-Optionsが設定されているか(クリックジャッキング対策) -
Content-Security-Policyが設定されているか
Webhook(Stripe等を使う場合) 🟡
決済サービスのWebhookは、署名検証が必須です。
- Webhookの署名検証をしているか(なりすまし防止)
- Webhookエンドポイントが公開されすぎていないか
エラー情報の露出 🟡
エラー発生時に詳細情報が見えると、攻撃者にヒントを与えてしまいます。
- エラー発生時にスタックトレースやDB情報がユーザーに見えないか
- 本番環境でデバッグモードがオフになっているか
パフォーマンス
データベース 🟡
非効率なクエリは、パフォーマンス低下と課金増加の原因になります。
- N+1クエリ問題がないか(ループ内でDBアクセスしていないか)
-
必要なカラムだけ取得しているか(
SELECT *を避ける)
無限ループ防止 🔴
AI APIが失敗した時に無限リトライすると、高額請求の原因になります。
- AI APIが失敗した時、無限にリトライしないか(最大3回程度)
- 処理のタイムアウトが設定されているか
動作確認方法
| 確認項目 | 方法 |
|---|---|
| APIキーの検索 | コード全体で sk- api_key apiKey secret を検索 |
| 他人のデータアクセス | URLのIDを適当な数字に変えてアクセスしてみる |
| SQLインジェクション | 入力欄に '; DROP TABLE users-- と入れてみる |
| CORS確認 | ブラウザの開発者ツール → Networkタブで Access-Control-Allow-Origin ヘッダーを確認 |
| HTTPS確認 | 本番URLが https:// で始まるか確認 |
| Webhook署名 | 署名なしのリクエストを送って拒否されるか確認 |
| N+1クエリ | 一覧画面表示時のDBクエリ数をログで確認 |
クラウドコスト管理編
予算管理(最重要)
アラート設定 🔴
予算アラートを設定していないと、気づかないうちに高額請求が発生します。
- クラウドプロバイダー(AWS/GCP/Vercel等)で予算アラートを設定しているか
- AI API(OpenAI等)で利用上限を設定しているか
- 請求が一定額を超えたら通知が来るようになっているか
AI API呼び出し制限
利用回数の上限 🔴
悪意あるユーザーにAI APIを使い放題にされると、高額請求が発生します。
- 無課金ユーザーの1日の利用回数を制限しているか
- 1ユーザーあたりの呼び出し回数に上限があるか
無限ループ防止 🔴
- AI APIが失敗した時、無限にリトライしないか(最大3回程度)
- 処理のタイムアウトが設定されているか
データ転送量・ストレージ
画像・動画 🟡
大きなファイルをそのまま配信すると、転送量課金が高額になります。
- 画像を適切なサイズに圧縮しているか(WebP形式の検討)
- 一覧表示でフルサイズの画像/動画を読み込んでいないか(サムネイルを使う)
キャッシュ 🟡
- 静的ファイル(画像、CSS、JS)にキャッシュヘッダーが設定されているか
リソース管理 🟡
使っていないリソースを放置すると、毎月無駄な課金が発生します。
- 使っていないサービス・インスタンスが動いていないか
- 開発環境のリソースが本番と同じサイズになっていないか
動作確認方法
| 確認項目 | 方法 |
|---|---|
| 予算アラート | クラウドの管理画面で予算上限とアラートが設定されているか確認 |
| AI API上限 | OpenAI等の管理画面でUsage limitsが設定されているか確認 |
| AI API制限 | 同じ操作を10回繰り返して止まるか確認 |
| キャッシュ確認 | ブラウザの開発者ツールでCache-Controlヘッダーを確認 |
| 不要リソース | クラウドの管理画面で動いているサービス一覧を確認 |
公開前の最終チェックリスト
🔴 必須(公開前に必ず確認)
| # | 確認項目 | 方法 | ✓ |
|---|---|---|---|
| 1 | APIキー露出 | コード全体で sk- api_key secret を検索 |
|
| 2 | .env確認 |
git status で .env が表示されないか確認 |
|
| 3 | 他人のデータ | URLの /users/123 を /users/999 に変えてアクセス |
|
| 4 | XSS | 入力欄に <script>alert('test')</script> と入れてみる |
|
| 5 | トークン保存 | 開発者ツールでlocalStorageにトークンがないか確認 | |
| 6 | SQLインジェクション | 入力欄に '; DROP TABLE users-- と入れてみる |
|
| 7 | CORS設定 |
Access-Control-Allow-Origin が * になっていないか確認 |
|
| 8 | HTTPS | 本番URLが https:// で始まるか確認 |
|
| 9 | 予算アラート | クラウド管理画面で設定済みか確認 | |
| 10 | AI API上限 | OpenAI管理画面でUsage limits設定済みか確認 |
🟡 推奨(公開後早めに対応)
| # | 確認項目 | 方法 | ✓ |
|---|---|---|---|
| 1 | CSRF | 別タブでログアウトした状態でフォーム送信してみる | |
| 2 | 連打テスト | 送信ボタンを素早く10回押してみる | |
| 3 | Webhook署名 | 署名なしのリクエストを送って拒否されるか確認 | |
| 4 | N+1クエリ | 一覧画面表示時のDBクエリ数をログで確認 | |
| 5 | 画像圧縮 | 大きな画像がそのまま表示されていないか確認 | |
| 6 | 不要リソース | クラウドの管理画面で動いているサービス一覧を確認 |
見落とすと危険なポイントまとめ
| 優先度 | 項目 | 最悪のケース |
|---|---|---|
| 🔴 | APIキー露出 | 第三者に悪用され、数百万円の請求 |
| 🔴 | 他人のデータアクセス | 個人情報漏洩、法的問題 |
| 🔴 | トークンのlocalStorage保存 | XSS経由でセッションハイジャック |
| 🔴 | CORS設定ミス | 悪意あるサイトからAPIを不正利用 |
| 🔴 | 予算アラート未設定 | 気づかないうちに数十万円の請求 |
| 🔴 | AI API上限未設定 | 悪意あるユーザーに使い放題にされる |
| 🟡 | Webhook署名なし | 偽の決済完了通知で商品を騙し取られる |
| 🟡 | 連打対策なし | 同じ処理が大量に実行され、高額請求 |
| 🟡 | 開発環境の放置 | 毎月無駄な課金が継続 |
まとめ
バイブコーディングは開発を劇的に効率化してくれますが、セキュリティとコスト管理は人間が責任を持って確認する必要があります。
このチェックリストを活用して、安全にアプリケーションを公開しましょう。
推奨する運用
- 公開前に必ず🔴項目をすべてチェック
- 公開後1週間以内に🟡項目を対応
- 月に1回、クラウドの課金状況とリソースを確認
- 新機能追加時は、関連するチェック項目を再確認
AIと一緒にコードを書く時代だからこそ、人間がレビューする力が大切です![]()
参考リンク
- OWASP Top 10 - Webアプリケーションセキュリティのトップ10リスク
- OpenAI Usage limits - OpenAI APIの利用上限設定
- AWS Budgets - AWSの予算アラート設定
- GCP Budgets - GCPの予算アラート設定