2026年4月19日、Vercel がセキュリティインシデントを公表した。サードパーティ AI ツールの侵害を起点に、Vercel 従業員の Google Workspace アカウントが乗っ取られ、一部の顧客の環境変数が攻撃者にアクセス可能な状態になっていたという話。侵害自体は 2026年2月から続いていたサプライチェーン攻撃で、公表が 4 月のこのタイミングになった形。
攻撃者は「ShinyHunters」を名乗り、奪取したデータを 200万ドル で BreachForums に出品した(BleepingComputer の報道 経由)。暗号資産プロジェクトの Orca などが一斉にデプロイメント認証情報をローテーションする騒ぎに発展している。
影響範囲は「限定的な顧客」にとどまるとされているが、Next.js の主要メンテナである Vercel が関わるインシデントということで、プラットフォーム選定の議論——特に Cloudflare Pages / Workers への移行論——が一気に加熱した。
この記事では、今回のインシデントで実際に何が起きたか、どこに設計上の問題があったか、そして Cloudflare のセキュリティモデルとどう違うかを整理する。
インシデントの攻撃チェーン
攻撃は段階的なサプライチェーン侵害だった。
- 2026年2月: Context.ai(Vercel 従業員が業務で使っていたサードパーティ AI ツール)の従業員が、情報窃取型マルウェア「Lumma Stealer」に感染。認証情報が盗まれる
- OAuth トークン奪取: 攻撃者は Context.ai の Google Workspace OAuth アプリに紐づくトークンを掌握
- Vercel 従業員アカウントの乗っ取り: 少なくとも 1 名の Vercel 従業員が、Vercel エンタープライズアカウントで Context.ai に「Allow All」権限でサインアップしていた。このアカウント経由で Vercel 社内の Google Workspace にアクセス
- 環境変数の露出: 侵害された Vercel 従業員の権限で、「sensitive」フラグが設定されていない環境変数にアクセス
脅威アクター側は BreachForums に「アクセスキー、ソースコード、DB 内容、NPM / GitHub トークン」を含むと主張するリストを出品。Vercel 側は攻撃者について「operational velocity から見て高度に洗練されており、AI を活用している可能性が高い」とコメントしている(CEO 発言、Decrypt の報道 経由の意訳)。
Context.ai の OAuth 権限が過剰に付与されていた点、Vercel 従業員が業務アカウントでサードパーティ AI ツールにサインアップしていた点が、「人間の運用ミス起点のサプライチェーン攻撃」 として典型的な構造になっている。
問題の中心:「sensitive フラグ」のopt-in設計
今回の技術的な肝は、Vercel の環境変数における 「sensitive」フラグの扱い にある。
Vercel では、環境変数に sensitive フラグを立てると以下のように保護される。
- 保存時に暗号化される
- ダッシュボード・CLI からは値が読み出せなくなる
- Vercel の従業員からも読めない
注意したいのは、「非 sensitive な変数が平文で保存されていた」わけではないという点。Vercel 内部では保存時の暗号化自体はされているが、sensitive を立てていない変数は Vercel の内部ツール・従業員権限からは値として読み出せる運用になっていた、という話。今回の攻撃者は侵害した Vercel 従業員アカウントの権限でこの内部ツール経路を踏んだ。Vercel 公式のインシデントレポートでも「sensitive としてマークされていない環境変数に攻撃者がアクセスできた」と明記されている。
ここで問題になるのが、多くの開発者がこのフラグを意識的に設定していなかったという事実。API キーや DB 認証情報、決済プロバイダーの署名鍵など、本来なら絶対に sensitive にすべき値が、デフォルトの「非 sensitive」のまま運用されていたプロジェクトが相当数あったと考えられる。
GitGuardian の分析記事 では、今回のインシデントで危険にさらされた可能性がある代表的なシークレット種類を以下のように挙げている。
- API キー(Stripe、OpenAI、各種 SaaS 連携系)
- データベース認証情報(接続文字列含む)
- 署名鍵(JWT、Webhook 検証用)
- サードパーティ OAuth トークン
- GitHub / NPM トークン(デプロイフローに紐づくもの)
セキュリティメディアの分析では、Vercel は今回のインシデント以降、内部ツールのトークンローテーション強制、RBAC v2 による Just-In-Time アクセス、AES-256-GCM + HashiCorp Vault での環境変数暗号化など、対策強化を進めていると伝えられている(これらは Vercel 公式ブレティンに完全には明記されていない二次情報を含むので、ステータスは変わる可能性あり)。ただしセキュリティ研究者からは「これらはすべて事後対応の延長で、デフォルトの信頼モデル自体を見直していない」という指摘も出ている。
影響範囲と実害
Vercel 公式は「限定的な顧客」にとどまると発表し、該当顧客には個別に通知。Next.js・Turbopack・OSS プロジェクト本体は安全としている。
一方で、Vercel を使っているフロント構成の割合が高い暗号資産業界では連鎖的なクレデンシャルローテーションが発生した。例えば Solana 基盤の DEX である Orca は「フロントエンドが Vercel にホストされているため、予防措置として全デプロイメント認証情報をローテーションした」と発表している(CoinDesk の報道 経由)。オンチェーンプロトコル側・ユーザー資金への影響は確認されていないが、フロントを Vercel に載せているプロダクトはほぼ例外なく警戒モードに入っている。
攻撃者は 200万ドル で出品したが、Vercel 側は「流出したとされるデータの全量については現在も調査中」というステータスで、実害の確定にはまだ時間がかかる見込み。
Vercelユーザーが今すぐやるべきこと
Vercel から「影響を受けた」と通知されていない場合でも、露出の窓(4/17–4/19 あたり)を意識した対策を取っておいた方がいい。公式ブレティンと主要セキュリティベンダーの推奨をもとに、優先順にまとめる。
1. 非sensitiveな環境変数の棚卸しとローテーション
最優先。シークレット性のある値が sensitive フラグなしで登録されていたら、「攻撃者に読まれた前提」で扱うべき。
# ローカルに環境変数をダンプ
vercel env pull .env.vercel
# GitGuardian の CLI で実際に有効なシークレットを検出
ggshield secret scan path .env.vercel
.env.vercel は作業後に必ず削除するか、事前に .gitignore に追加しておく。誤って Git にコミットすると二次事故になる。
ヒットしたシークレットは、まず 上流側(AWS・Stripe・GitHub など)でローテーション してから Vercel 側の値を更新する。順序を逆にすると窓が開く。
2. 全シークレットにsensitiveフラグを適用
Vercel のダッシュボードから、Environment Variables → 該当変数の編集画面で Sensitive にチェックを入れる。今後追加する変数も、値がシークレットなら原則 sensitive を前提にする運用に切り替える。
3. Deployment Protectionの確認
Deployment Protection が Standard 以上に設定されていることを確認し、既存の Protection Bypass Token もローテーション対象に含める。
4. アクティビティログと直近デプロイの監査
Vercel のダッシュボードから Activity Log を開き、4/1〜現在の期間で不審なデプロイ・メンバー追加・設定変更がないか確認。通知されていない顧客でも念のためやっておく価値がある。
5. 連携OAuthアプリの棚卸し
GitHub・Google Workspace 側で、Vercel に紐づく OAuth アプリの一覧と権限をレビュー。不要なものは削除し、残すものも最小権限の原則に沿っているかチェックする。今回の攻撃チェーンの入口はまさにここなので、自社側でも同じ構造になっていないかを確認しておく。
Cloudflareのセキュリティ設計はなぜ違うか
今回のインシデントで改めて注目されているのが、Cloudflare Workers / Pages のセキュリティ設計思想の違い。Vercel が「柔軟なフラグ運用で保護レベルを調整する」opt-in モデルなのに対し、Cloudflare は 「デフォルトで隔離・暗号化」の zero-trust モデル で組まれている。
V8 Isolateベースのサンドボックス
Cloudflare Workers は V8 エンジンの isolate 単位でコードを実行する。各 isolate はメモリ空間が分離されていて、他 isolate のメモリにはアクセスできない。1 プロセス内で数千テナントを同居させても、isolate 境界でメモリ分離が担保される構造になっている。
加えて、プロセスレベルでは Linux namespace + seccomp によるサンドボックスを二重に適用している。
- ファイルシステムへの全アクセスを遮断
- ネットワークアクセスも遮断(Cloudflare 経由のバインドされた通信のみ許可)
- isolate がロードされる前にサンドボックスが構築されるため、一般的なコンテナエンジンより制約が厳しい
Secrets Binding:コードとシークレットの厳格な分離
Cloudflare Workers では、シークレットはコードと完全に分離された「バインディング」として注入される。Worker の実装からは env.MY_SECRET のような形でのみアクセス可能で、平文の値がコード側やデプロイ設定に含まれることはない。
さらに、シークレットは保存時に暗号化されていて、サンドボックスプロセスは Worker のリクエストを受け取るタイミングで、そのリクエストに含まれる「復号キー」を使って初めて自分の Worker のシークレットを復号できる。他 Worker の設定を列挙することも不可能。
Vercel の sensitive フラグが 「立てたら安全」のオプトイン なのに対し、Cloudflare の Secrets Binding は 「立てなくても分離されている」のデフォルト という差になる。
Cordon System:信頼レベルによるワーカー隔離
Cloudflare はワーカーに信頼レベルを割り当て、同一プロセス内に低信頼 Worker と高信頼 Worker を混在させない。具体的には、Free プランの Worker と Enterprise プランの Worker は別プロセスで実行される。
V8 にゼロデイ脆弱性が見つかった場合の多層防御として設計されたもの(仕組みの詳細は Cloudflare Workers 公式のセキュリティモデルドキュメント にまとまっている)。Vercel 側には同等の公開情報はない。
Vercel → Cloudflare Pagesへの移行で考えること
では Cloudflare に移った方がいいかというと、そう単純でもない。移行判断の現実的なポイントを整理する。
Next.js × Cloudflare Pagesは十分実用レベル
@cloudflare/next-on-pages アダプタ経由で、Next.js の App Router / SSR / Middleware が Cloudflare Pages 上で動く。個人開発で Next.js × Cloudflare Pages を実運用している体感としても、ビルド時間・デプロイ体験ともに Vercel と遜色ない。ホスティングコスト(帯域無制限・無料枠の大きさ)はむしろ有利になる。
実際の構成・設定・ハマりどころは別記事にまとめている。
Vercel固有機能の代替
以下は移行時に検討が必要な主な Vercel 固有機能と、Cloudflare 側の代替。
| Vercel 機能 | Cloudflare 側の代替 |
|---|---|
| Edge Config | Workers KV / D1 |
| Image Optimization | Cloudflare Images / next/image custom loader |
| Analytics | Cloudflare Web Analytics |
| Edge Functions | Workers(そもそも全ランタイムが Workers) |
| Cron Jobs | Workers Cron Triggers |
Edge Config のような「低レイテンシ KV」用途は Workers KV が直接の置き換えになる。Image Optimization はカスタムローダーか Cloudflare Images で対応可能。
ただし、Edge Config の読み取りレイテンシ(Vercel 公称で 15ms 未満)と Workers KV のレイテンシ特性は厳密には同じではないので、アクセスパターンによっては設計の見直しが必要になる場合がある。高頻度読み取り・書き込みが少ない前提なら Workers KV、RDB 的な使い方をしているなら D1 を選ぶ、のように用途で分けるのが現実的。
移行が合う人・合わない人
移行のコスト / ベネフィットを踏まえると、以下のような判断軸になる。
移行が合うケース
- 個人開発・小〜中規模プロジェクトで、Vercel 無料枠の制限(帯域・ビルド回数)が気になってきた
- セキュリティの「デフォルト設計」を重視する(今回のインシデントが刺さった)
- Cloudflare の他サービス(R2・D1・Workers AI)と統合していきたい
移行を急がない方がいいケース
- Vercel Enterprise の高度な機能(Preview Deployment Comments、Web Analytics Advanced など)を業務で使っている
- Vercel のチーム機能・権限管理を組織運用で回している
- Edge Middleware で Vercel 固有の API を多用している
今回のインシデントは確かにインパクトが大きいが、パニック移行するほどのものでもない。実害は「限定的な顧客への通知」にとどまっている段階で、Vercel 側の対応強化もそれなりのスピードで進んでいる。冷静にやるべきは、まず Vercel 内の露出範囲を特定してローテーションを終わらせること。その上で、プラットフォーム選定の基準に「デフォルトのセキュリティ設計」を組み込むかを検討する、という順序がいい。
まとめ
今回のインシデントのポイント。
- 攻撃起点は Vercel 本体ではなく、サードパーティ AI ツール(Context.ai)の OAuth 権限
- 影響の核は、
sensitiveフラグなしの環境変数が内部システムから読めた こと - Vercel ユーザーが今やるべきは、非 sensitive シークレットの棚卸し → 上流でローテーション → フラグ適用、の順
- Cloudflare は 「デフォルトで isolate 分離 + Secrets Binding で厳格分離」 の zero-trust 設計で、opt-in フラグに依存しない構造
サードパーティ AI ツールに業務アカウントで「Allow All」権限を渡す運用は、今後あらゆる会社でリスクとして再評価されるはず。プラットフォーム選定の話にとどまらず、AI ツールの OAuth 権限管理 という新しい運用トピックを浮き彫りにしたインシデントだった。
ぱんだツールズ は Cloudflare Pages × Next.js で運用しているブラウザ完結の Web ツール集(70本超)。PDF・CSV・画像処理など、全部無料・登録不要で使える。今回の記事で扱った Cloudflare Pages 構成のリアルな稼働事例としても見られる。
https://sakutto-panda.com
この記事は Zenn にも同じ内容を投稿しています。