2026年4月、Vercelは内部システムへの不正アクセスを公表し、限定された顧客群の「sensitive未設定」環境変数が侵害対象になった可能性を認めた。起点はVercel自体ではなく、第三者AIツールContext.aiの侵害と、そのOAuth連携を経由したGoogle Workspaceアカウント乗っ取りである。事件直後にはBreachForums上で販売投稿が観測され、API鍵・DB資格情報・ソースコードを含むとする主張が拡散した。Vercelは一部主張を確認しておらず、件数も非公表であるが、開発者にとっては「公開クラウドIDE/ホスティングの利便性」と「秘密情報境界」の設計不備が同時に露出した事案である。
本稿は、2026年4月19日から21日に更新されたVercel公式Bulletinと公開技術文書をもとに、攻撃チェーン、Next.js環境変数モデルで起きる露出経路、そしてOWASP Secret Management・Vault統合を中核にした多層防御の実装指針を示す。
攻撃チェーンの分解: OAuth委任が「秘密境界」を横断した
Vercelの2026年4月19日公表、および4月21日最終更新のBulletinで確定している要点は3つである。第一に、侵害はContext.aiの侵害を起点としている。第二に、攻撃者は第三者ツール連携を通じてVercel従業員のGoogle Workspaceアカウントを奪取した。第三に、その結果として「sensitive」指定されていない環境変数へアクセス可能になった、という点である。
技術的には、これは典型的な「SaaS-to-SaaS OAuthピボット」である。つまり、開発プラットフォーム本体を直接破るのではなく、周辺SaaSのトークンや過大権限スコープを足場に、管理プレーンへ到達する。Google公式ドキュメントが示す通り、OAuth同意画面で要求スコープを最小化しない構成は、ユーザー利便性を優先する一方で権限横断リスクを増幅させる。インシデント後に流通したBreachForums投稿の内容(数千プロジェクト規模の鍵露出など)は未検証情報を含むが、少なくとも「非sensitive変数は潜在露出面になる」という構造は公式情報で裏付けられた。
Next.js時代の露出経路: 環境変数は「保存」だけでなく「配布」で漏れる
Next.jsの公式ガイドは、`NEXT_PUBLIC_`プレフィックスを付与した値がビルド時にクライアントバンドルへインライン化されることを明示している。これは仕様であり脆弱性ではないが、運用設計を誤ると「秘密のつもりで設定した値」が配布物に固定される。つまり、秘密管理は「どこに保存したか」だけでなく「どこへ配布されたか」で評価すべきである。
さらにVercel運用では、Preview/Productionごとの変数分離、デプロイ単位のビルドキャッシュ、CI/CD統合、外部統合の読み取り権限が重なる。結果として、漏えい面は以下の4層に増える。
- 管理プレーン層: ダッシュボード・API・連携アプリによる読み取り
- ビルド層: ビルドログ・アーティファクト・一時ファイル
- ランタイム層: サーバーログ・例外スタック・診断エンドポイント
- クライアント層: `NEXT_PUBLIC_`による意図的公開
2026年4月事案が示したのは、どこか1層で「平文取得が可能」な設定が残ると、攻撃者はそこを最短経路として選ぶという現実である。
利便性vs秘密管理: Vercelの「Sensitive」機能だけでは不十分な理由
Vercel公式ドキュメントでは、Sensitive Environment Variablesは「読み出し不能な形式」で保管されると説明されている。実際、今回もVercelはSensitive指定値へのアクセス証跡は確認していないと述べた。これは重要な防壁である。
ただし、実務では次の理由で単独防御にならない。
- 既存変数の再作成や環境移送時に、sensitive指定漏れが起こりやすい
- Secretがアプリ側で復号・利用された後のログ出力や例外で再露出しうる
- OAuth統合の過大権限が残ると、Secret以外の構成情報から再侵入される
Vercel自身もインシデント後に「環境変数作成のデフォルトをsensitive=onへ変更」しており、これはUI改善であると同時に、人間の設定ミスを前提にしたセーフティ設計への移行を意味する。したがって設計原則は「人の注意に依存しない秘密管理」である。
OWASP Secret Management + Vault統合: 多層防御の実装手順
OWASP Secrets Management Cheat Sheetは、シークレットのライフサイクル管理(作成・保管・配布・ローテーション・失効)を自動化し、可能な限り短寿命の動的資格情報へ移行することを推奨する。HashiCorp VaultのDatabase Secrets Engineはこの方針を実装しやすく、静的なDBパスワードをアプリ設定に常駐させず、TTL付き資格情報へ置換できる。
Next.js + Vercel環境での現実的な導入手順は次の通りである。
- 秘密分類を定義する。`公開可 / 準機密 / 機密 / 高機密`の4段階に分け、`NEXT_PUBLIC_`は公開可のみ許可する。
- Vercelには「参照トークン」だけを置く。DB直パスワードや長寿命API鍵は置かない。
- ランタイム起動時にVaultへ短命トークンで認証し、動的Secretを取得する。
- 取得SecretのTTL満了前に再取得し、失効時は自動ロールバック(read-onlyモード等)へ切替える。
- インシデント発生時は、Vault側のリース失効とロール無効化で即時封じ込めを行う。
この構成では、たとえホスティング管理面の一部情報が露出しても、Secretの有効期間と利用範囲が狭いため、被害半径を時間・権限・経路の3軸で圧縮できる。
React Server Components時代の標準: 「秘密ゼロ配布」と「委任最小化」
React Server Components(RSC)時代は、サーバー実行境界が細分化され、開発者体験は改善する一方で、秘密の取り回しは複雑化する。今後の標準は次の2原則に収斂する。
- 秘密ゼロ配布: フロント配布物・静的ビルド成果物へ秘密値を含めない
- 委任最小化: OAuthスコープ、CIトークン、クラウドIAMを常時最小権限に保つ
具体的な監査KPIとしては、`NEXT_PUBLIC_`変数監査件数、長寿命鍵の残存本数、30日以内ローテーション完了率、第三者OAuthアプリの高リスクスコープ数、の4つを四半期で追うべきである。Vercel事案は単発のニュースではなく、開発インフラが「秘密管理システム」であることを再定義した転換点である。
FAQ
今回のVercel事案で、すべての環境変数が漏えいしたのか?
公式Bulletinでは、影響は限定された顧客群の「sensitive未設定」環境変数とされている。VercelはSensitive指定値についてアクセス証跡を現時点で確認していない(最終更新: 2026年4月21日)。
Next.jsでは `NEXT_PUBLIC_` を使わなければ安全か?
安全性は向上するが十分条件ではない。`NEXT_PUBLIC_` は意図的公開の仕組みであり、サーバー側変数でもログ・例外・管理プレーン経由で露出しうるため、保存・配布・監査を分離して設計する必要がある。
Vault統合は中小チームには重すぎるか?
フル機能導入は運用負荷がある。まずは「高機密のみ動的Secret化」「ローテーション自動化」「失効手順の演習」から開始し、対象を段階拡大する方式が現実的である。
インシデント直後に最優先でやるべき手順は何か?
1) 非sensitive変数と長寿命鍵の即時ローテーション、2) OAuth連携アプリの棚卸しと過大権限削除、3) デプロイ履歴とアクセスログの異常調査、4) 漏えいを前提にした再発行・失効の自動化、の順で実施すべきである。
参考文献
- Vercel April 2026 security incident — Vercel Knowledge Base, 2026-04-21(最終更新)
- App host Vercel says it was hacked and customer data stolen — TechCrunch, 2026-04-20
- Sensitive environment variables — Vercel Docs
- Guides: Environment Variables — Next.js Documentation
- Secrets Management Cheat Sheet — OWASP Cheat Sheet Series
- Database secrets engine — HashiCorp Vault Documentation
- Configure the OAuth consent screen and choose scopes — Google Workspace Developers

