Vibe Codingのリスク、
きちんと知っていますか?
AIを使えばサービスを短期間で作れる時代。ただ、「動く」ことと「安全に使えること」は別の話です。 AI任せの開発が抱えやすいリスクを、重大度別に整理しました。
Vibe Coding(AIと会話しながらコードを生成するスタイル)は、専門知識がなくてもアイデアをすぐ形にできる強力な手段です。
一方でAIは「動作すること」を優先するため、セキュリティ・スケール・運用面の考慮が抜け落ちやすいという特性があります。 このページでは生まれやすいリスクを重大度別にまとめています。
- 01
ハードコードされたAPIキー
コードの中に直接「秘密の鍵」を書いてしまうこと。GitHubに公開した瞬間にボットが自動で見つけ出し、数分以内にAWS課金やStripe不正利用などの被害が起きた実例が多数あります。
解決策の一例`.env` ファイルに移し、`.gitignore` で除外する。VercelやRenderなどは管理画面から環境変数を設定できる。
- 02
決済通知の検証なし
Stripeなどの決済サービスは「決済完了」をサーバーに通知してきます。この通知が本物かどうかを確認しないと、攻撃者が偽の「決済完了」を送りつけてタダでサービスを利用できてしまいます。
解決策の一例Stripeの署名検証機能を使う。公式ドキュメントのサンプルを数行追加するだけで対応できる。
- 03
権限チェックなし
「管理者」「一般ユーザー」などの権限を、APIを呼び出す時点で確認していないこと。URLを直接入力するだけで他人のデータを閲覧・削除できてしまいます。画面上でボタンを隠しているだけでは防げません。
解決策の一例APIの各エンドポイントに権限チェックを追加する。ミドルウェアとして一箇所にまとめると漏れが減る。
- 04
パスワードリセットリンクが無期限
「パスワードを忘れた」メールのリンクに有効期限がないこと。メールが漏洩した場合、永久に使えるリセットリンクが残り続けます。
解決策の一例有効期限(15〜30分)をDBに保存し、使用時に確認する。使用済みフラグも設定して再利用を防ぐ。
- 05
パスワードのハッシュ化なし
ユーザーのパスワードをそのままの文字列でデータベースに保存してしまうこと。データベースが漏洩した瞬間に全ユーザーのパスワードが平文で流出します。bcryptなどのハッシュ化は必須であり、AIが生成したコードで抜け落ちやすい箇所の一つです。
解決策の一例bcryptなどのライブラリで保存前にハッシュ化する。多くのフレームワークが標準対応しており、設定するだけで使える。
- 06
バックアップなし
データのコピーを定期的に保存していないこと。誤操作・ランサムウェア・クラウド障害など、原因を問わず全データが失われた場合に復旧手段がありません。
解決策の一例SupabaseやRenderなどのマネージドサービスは自動バックアップを内蔵。設定画面からオンにするだけ。
- 07
リクエスト制限なし
同じ相手から短時間に大量のリクエストを送られても止める仕組みがないこと。ログインへのパスワード総当たり攻撃や、サーバーへの意図的な過負荷攻撃が通り放題になります。
解決策の一例CloudflareのWAFやUpstashのRate Limitingを使う。`express-rate-limit` などのライブラリなら数行で導入できる。
- 08
クロスサイトアクセス制限なし(CORS)
悪意のある別サイトがユーザーのブラウザを経由して、自分のAPIを勝手に呼び出せてしまう設定になっていること。ブラウザの標準的なセキュリティ機能を正しく設定するだけで防げます。
解決策の一例許可するドメインを明示的に指定する。ワイルドカード(*)は本番環境では使わない。
- 09
ログインセッションが無期限
一度ログインしたら永遠にログイン状態が続くこと。端末の紛失・パスワード変更後も古いセッションが生き続け、アカウントへの不正アクセスが継続します。
解決策の一例セッションに有効期限(24時間程度)を設定する。JWTを使う場合はexpiry(exp)の設定を必ず行う。
- 10
DBインデックスなし
データベースの「目次」がない状態。データが少ない間は気づきませんが、数万件を超えると検索のたびに全データを最初から確認するため、表示に数秒〜数十秒かかりサービスが実質停止します。
解決策の一例検索でよく使うカラム(ユーザーID・メール等)にインデックスを追加する。マイグレーションに1行追加するだけ。
- 11
DB接続の使い回しなし
アクセスが集中した瞬間に「接続数の上限」に達し、新しいリクエストが全部エラーになってサービスがダウンします。接続を使い回す(プーリング)設定が必要です。
解決策の一例PrismaなどのORMは接続プーリングを標準サポート。マネージドサービスは推奨の接続設定を確認する。
- 12
起動時の設定検証なし
本番サーバー起動時に必要な設定値が正しく存在するか確認しないこと。設定が抜けていても起動してしまい、特定の機能だけ静かに壊れた状態で動き続けることがあります。
解決策の一例起動時に必要な環境変数の存在を確認し、不足があれば即停止する処理を追加する。`zod` で数行で実装できる。
- 13
ログなし
サーバーで何が起きたかの記録がないこと。障害が発生した時に「いつ・何が・なぜ壊れたか」を調査する手がかりがゼロになり、問題解決に異常に時間がかかります。
解決策の一例WinstonやPinoでログを記録する。Sentryと組み合わせるとエラー発生時に自動通知が届く。
- 14
ヘルスチェックなし
サーバーが正常に動いているかを自動確認する仕組みがないこと。サービスが落ちても誰も気づかず、ユーザーからの問い合わせで初めて知ることになります。
解決策の一例`/health` エンドポイントを追加し、UptimeRobotで定期監視する。障害時にメール・Slack通知が届く。
- 15
一覧画面で全件取得
一覧画面でデータを全件取得してしまうこと。データが増えるとAPIのレスポンスが巨大になり、表示が極端に遅くなるかタイムアウトします。
解決策の一例取得件数を20〜100件に絞るページネーションを追加する。クエリに `LIMIT` と `OFFSET` を加えるだけで改善する。
- 16
入力値の無害化なし
ユーザーが入力した文字列をそのままDBに渡したり画面に表示すること。データベースへの不正操作(SQLインジェクション)や、悪意あるスクリプトを他ユーザーに実行させる攻撃(XSS)の原因になります。現代のフレームワークがデフォルトで多くを防いでくれますが、生のSQLや直接HTML出力を使っている箇所では即座に重大なリスクになるため、その場所だけは必ず確認してください。
解決策の一例ORMのパラメータ化クエリを使い、SQLの文字列結合を避ける。HTML出力はテンプレートエンジン経由にし、`innerHTML` への直接代入を使わない。
- 17
メール送信が遅い
メール送信処理をAPIの応答の中でそのまま実行すること。メールサーバーが遅い・落ちている場合に、ユーザーが数秒〜数十秒待たされます。
解決策の一例送信処理をバックグラウンドキューに切り出し、APIは即座にレスポンスを返す。Resendなどのサービスは非同期送信を標準サポート。
- 18
自動テストなし
コードが期待通りに動くかを自動で確認する仕組みがないこと。最初は手動確認で回せますが、機能が増えるにつれて「変更のたびに何かが壊れていないか」の確認が難しくなります。セキュリティリスクではなく開発効率・品質の話です。
解決策の一例JestやVitestでユニットテストを追加する。100%を目指さず、決済・権限判定など壊れると困る箇所から始める。
- 19
CDNなし
画像や静的ファイルを世界中に分散配置されたサーバーから配信する仕組み。ないと表示が遅くなりますが、初期の国内ユーザー相手なら許容範囲です。
解決策の一例CloudflareやVercelのエッジキャッシュを利用する。画像はCloudinaryやnext/image経由で自動最適化できる。
- 20
エラー時の画面保護なし
アプリの一部でエラーが起きた時に画面全体が真っ白になることがあります。再読み込みで復帰できるため致命的ではありませんが、UX上は改善が望ましい。
解決策の一例Reactなら `ErrorBoundary`、Next.jsなら `error.tsx` を追加するだけ。エラーが起きても画面全体への影響を防げる。
これらのリスクはどれも「AIが悪い」わけではありません。
AIはコードを生成できますが、「何を作るべきか」「どのリスクを今対処すべきか」を判断するのは人間の役割です。 Vibe Codingを活用しながらリスクを管理するには、エンジニアリングの視点が不可欠です。