セキュリティは「アプリのコードを書く前」に、入口で効かせるのが最もコスト効率が良い領域です。Vercel はプラットフォーム層に DDoS 緩和・WAF・BotID の3層を持ち、コード変更を最小限に攻撃面を削れます。この記事は Vercel Firewall と Vercel WAF、BotID の公式仕様に忠実に、実コードで入口の守り方をまとめます。
全体像は Vercel 本番運用ガイド を参照してください。
重要な前提:本稿は**プラットフォーム層(入口)のセキュリティです。アプリ層の認可・RLS・注入対策(IDOR/SQLi/XSS/SSRF)**は WAF では守れません。両者は別レイヤーで、両輪で設計します。アプリ層は Next.js × Supabase アプリ層セキュリティ を参照してください。
3層の役割分担
| 層 | 守るもの | プラン |
|---|---|---|
| DDoS 緩和 | 大量リクエストによる枯渇攻撃 | 全プラン(自動・無料) |
| WAF | 不正リクエストの遮断・チャレンジ・レート制限・IPブロック | Hobby/Pro/Enterprise(規模差) |
| BotID | 人間を装う高度なbot(スクレイピング・クレデンシャルスタッフィング) | Basic 全プラン無料 / Deep Analysis Pro・Ent |
「広く自動で効く DDoS 緩和」を土台に、「ルールで狭く制御する WAF」と「人間/bot を見分ける BotID」を重ねる——これが入口の多層防御です。
DDoS 緩和:全プランで自動
Vercel の DDoS 緩和は全プランで自動に効きます。設定不要で、L3/L4/L7 の大量リクエストを吸収します。攻撃が激しいときは後述の Attack Challenge Mode を併用します。これは「何もしなくても土台が守られている」状態で、ここに WAF と BotID で意図的な制御を足していきます。
Vercel WAF:300msで反映される入口ルール
Vercel WAF は、サイトへの通信をログ・遮断・チャレンジで監視・制御する仕組みです。最大の特徴は運用性——設定変更が 300ms でグローバル反映され、問題があれば監査ログから即時ロールバックできます(WAF docs)。
3つの制御手段
| 手段 | 内容 |
|---|---|
| IP ブロック | 特定 IP/CIDR を遮断 |
| カスタムルール | 条件 → アクションの宣言的ルール |
| マネージドルールセット | OWASP 等の既製ルール群(Enterprise) |
プラン別の上限
| 機能 | Hobby | Pro | Enterprise |
|---|---|---|---|
| プロジェクト IP ブロック | 最大3 | 最大100 | 最大1000 |
| カスタムルール | 最大3 | 最大40 | 最大1000 |
| マネージドルールセット | — | — | あり |
カスタムルールの考え方
カスタムルールは「条件(パス・IP・地域・リクエストヘッダ・User-Agent・JA4 等)」に「アクション」を紐づけます。アクションは——
- Allow:通す(許可リスト)
- Deny:遮断
- Challenge:チャレンジ(人間か検証)
- Log:記録のみ(まず観測してから締める)
- Rate Limit:一定時間あたりの回数で制限
実務の鉄則は 「まず Log で観測 → 影響を確認 → Deny/Challenge へ昇格」。いきなり Deny にして正規ユーザーを巻き込む事故を避けます。300ms 反映と即時ロールバックがあるので、この「観測してから締める」運用が安全に回せます。
レート制限:濫用を構造で止める
ログインや検索のような濫用されやすい高価値ルートは、WAF のレート制限で「同一 IP から N 回/分」を超えたら Challenge/Deny にします。
Fluid Compute との関係:アプリ内のレート制限(メモリカウンタ)はサーバーレスで正しく効きません(インスタンスが共有・分散するため)。入口で効く WAF のレート制限か、Upstash(Redis) を使った分散レート制限を使うのが正解です。WAF レート制限は関数を呼ぶ前に効くので、Active CPU 課金も防げます。
設定とロールバック(運用フロー)
ダッシュボード → プロジェクト → Firewall
① Custom Rule を Log で追加 → トラフィックを観測
② 影響を確認したら Deny / Challenge / Rate Limit へ昇格(300msで反映)
③ 誤遮断が出たら View Audit Log → 過去構成へ Restore(即時ロールバック)
CLI でもルールをステージングして一括適用できます(vercel firewall)。Infrastructure as Code 的にルールをレビュー・適用したいチームに向きます。
Attack Challenge Mode:攻撃時の緊急弁
攻撃が激しいときは Attack Challenge Mode を ON にすると、全訪問者に一時的なチャレンジを課して自動化トラフィックを大幅に削れます。正規ユーザーには軽微な確認で済み、攻撃が収まったら OFF にします。「平時は精緻なルール、有事はモード一発」の二段構えです。
BotID:見えないCAPTCHA
reCAPTCHA のような「画像を選ぶ」UI は、UX を損ねる割に高度な bot には破られます。BotID は Kasada を基盤にした見えない CAPTCHA——ユーザー操作なしで、Playwright/Puppeteer のような「人間を装う」bot を検知します(BotID docs)。
2つのレベルと料金
| レベル | 内容 | プラン | 料金 |
|---|---|---|---|
| Basic | チャレンジ応答の整合性検証。多くの単純な bot を捕捉 | 全プラン | 無料 |
| Deep Analysis | 数千のクライアントシグナルを ML で解析。最高度の bot に対応 | Pro / Enterprise | Pro: $1 / 1000 checkBotId() 呼び出し、Ent: カスタム |
課金の起点は
checkBotId()の呼び出し。受動的なページ閲覧では課金されません。だから「高価値ルートでだけcheckBotId()を呼ぶ」のがコスト最適です。
計装:クライアント+サーバーの2点
BotID は「クライアントでチャレンジを仕込み、サーバーで検証する」2点計装です。
// ① クライアント側:保護したいルートのチャレンジを初期化
// app/providers.tsx ("use client")
"use client";
import { initBotId } from "botid/client";
initBotId({
protect: [
{ path: "/api/checkout", method: "POST" },
{ path: "/api/signup", method: "POST" },
],
});
// ② サーバー側:高価値エンドポイントで検証して分岐
// app/api/checkout/route.ts
import { checkBotId } from "botid/server";
export async function POST(request: Request) {
const verification = await checkBotId(); // ← Deep Analysis課金はここで発生
if (verification.isBot) {
return new Response("Forbidden", { status: 403 });
}
// 人間と判定された場合のみ本処理へ
return handleCheckout(request);
}
checkBotId() は、Basic 検証を通った後に Deep Analysis(設定時)を実行し、結果(isBot など)を返します。チェックアウト・サインアップ・問い合わせ・在庫APIのような「bot に荒らされると損害が出る」ルートに絞って入れます。
正規bot・バイパス・可観測性
- 検索エンジン等の正規 botは許可リストで通せます(Verified Bots)。
- 誤検知時は WAF のバイパスルールで、BotID 判定を迂回させて通せます。
- BotID のチェックは Firewall タブのトラフィックフィルタや Observability Plus で可視化できます。
環境変数とOIDC:秘密を入口に置かない
入口の防御と並んで重要なのが「秘密をコード・クライアントに漏らさない」ことです。
- API キー・DB 接続文字列は環境変数へ。
NEXT_PUBLIC_接頭辞はブラウザに露出するので機密には付けない(env リーク防止)。 - 外部クラウドへは長命のアクセスキーを置かず、OIDC 鍵レスで一時クレデンシャルを得る。
- Fluid Compute ではグローバル状態にユーザー固有データを置かない(テナント越境防止。Functions ガイド)。
本番チェックリスト(入口セキュリティ)
- DDoS 緩和が効いている(自動)。攻撃時の Attack Challenge Mode 手順を共有
- WAF カスタムルールは Log で観測 → 昇格 の順で導入
- 高価値ルートに WAF レート制限(関数を呼ぶ前に止める)
- 誤遮断時の 監査ログ → 即時ロールバック手順を確認
- チェックアウト/サインアップ等に BotID、
checkBotId()は対象ルートに限定 - 正規 bot は許可、誤検知は WAF バイパスで救済
- 秘密は環境変数、
NEXT_PUBLIC_に機密なし、外部は OIDC - アプリ層セキュリティ(認可/RLS/注入)は別途設計(WAFでは守れない)
まとめ
Vercel のプラットフォーム層セキュリティは、「広く自動の DDoS 緩和」+「狭く精緻な WAF」+「人間/bot を見分ける BotID」 の多層防御です。
- DDoS 緩和は土台(全プラン自動)
- WAF は Log→昇格で安全に締め、300ms 反映と即時ロールバックで運用
- レート制限は入口で(Active CPU も守る)
- BotID は高価値ルートに限定し、課金起点の
checkBotId()を絞る - WAF はアプリ層の認可・注入対策を代替しない——両輪で
次は、状態を置く ストレージ・Blob・Edge Config ガイド へ。
本記事は Vercel Firewall / Vercel WAF / BotID 公式ドキュメント(2026年6月時点)に基づきます。仕様・上限・料金は更新されるため、本番採用時は公式で最新値を確認してください。