このガイドの使い方
2026年4月19日、Vercel と Context.ai のOAuth連携で情報漏洩事件が公表されました。 こーすけさんの環境(Next.js + Supabase + Vercel)は同じ構成のため、自動では確認できない7項目を手動チェックする必要があります。
このページは初心者でも迷わないよう、画面イメージと「押すべきボタン」をSVGで図示しています。 上から順番にやればOK。所要時間の目安も書いています。
- ✅ 全体: 30〜45分
- 🔴 最優先3項目(鍵漏洩確認+Supabase Reset): 10分
- 🟠 デプロイ保護強化: 15分
- 🟡 設計相談が必要なもの: 後日
📋 チェックリスト
posture-* の .env.example に鍵が入っていないか目視確認
.env.example は「環境変数の書き方サンプル」ファイルで、普通は 値を空にして配布します。
ところがこの2ファイルに eyJhbGci... というSupabaseのJWT(パスワードのようなもの)が書かれている可能性があります。
もし完全な形で書かれていたら、GitHubに上がった時点で世界中に公開されています。
手順
= の後ろに 100文字以上の長い文字列があり、ドット「.」で2か所区切られているならJWT本体です。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 だけ(36文字)で終わっていれば安全(これはヘッダー部分のみ)。
Supabase で漏れた鍵をリセット
Supabase の service_role キーは管理者全権限を持っています。
もし漏れていたら、誰でも全患者データを読み書き・削除可能。即座に無効化して新しい鍵に差し替えます。
手順
Resetを押した瞬間から、古い鍵を使っているすべてのサーバー処理が止まります(=エラー500が出る)。 本番稼働中のプロジェクトなら、Vercelの環境変数を新しい鍵に差し替えるまで10分程度のメンテナンス時間になります。
Vercel Dashboard → 該当プロジェクト → Settings → Environment Variables で SUPABASE_SERVICE_ROLE_KEY を編集 → Save → Redeploy。
→ git add .env.example && git commit -m "chore: mask leaked example keys"
Google Workspace で侵害OAuthアプリを検索
2026年4月19日に公表された Vercel の情報漏洩事件で、Context.ai という会社のGoogle OAuthアプリが攻撃に使われました。 もし過去にこのアプリへ「Allow All」で許可を出していると、Gmail/Drive/カレンダーが読まれた可能性があります。 医療法人・full-lafu の両方のWorkspaceで確認する必要があります。
手順
何もしなくてOK。医療法人とfull-lafuの両方で同じ検索を行ってください。両方クリアなら完了。
- 該当アプリの右側メニューから 「アクセスをブロック」を選ぶ
- 許可したユーザーを特定(メールアドレス)
- Google Workspace の [レポート] → [監査と調査] → [Drive] で過去180日の操作ログを確認
- 該当ユーザーのパスワードリセット+2段階認証再設定
- 個人情報へのアクセスがあれば、個人情報保護委員会への報告要否を検討
Vercel の環境変数を「Sensitive」化
Vercel の環境変数には 「Plain(平文)」と 「Sensitive(暗号化)」の2種類があります。 Sensitiveにすると:
- Vercel ダッシュボードでも値が表示されない(鍵アイコン)
- API経由でも読み出せない(書き込みのみ)
- 今回のContext.ai事件で漏れたのはPlainの変数のみでした
手順(プロジェクトごとに実施)
医療データを扱う以下を優先:
endai-systemvisitcaree-signposture-corporate/posture-personalrevenue-attributioneditorial-manager
Edit ボタンを押すとダイアログが出るので、値はそのまま、「Sensitive」のトグルをONにして Save。 ※ 一度Sensitiveにすると値を読み出せなくなるので、値をメモしておきたい場合は先にコピーしておく。
以下のどれかに「NEXT_PUBLIC_」が付いていたら即座に修正(値をサーバー側変数へ移す):
NEXT_PUBLIC_*_SECRETNEXT_PUBLIC_*_TOKENNEXT_PUBLIC_*_SERVICE_ROLENEXT_PUBLIC_ADMIN_*
※ NEXT_PUBLIC_FIREBASE_API_KEY は Firebase の設計上OK(公開前提)
Vercel の Deployment Protection を強化
Vercel は本番以外に Preview デプロイ(プルリクごとに発行されるURL)を自動生成します。 デフォルトではURLを知っていれば誰でも見られるため、開発中の医療データが外部から覗ける状態になりがち。 パスワード or SSO を必須にすれば、URLが漏れても中身は守られます。
手順
Standard Protection は無料プランでも使えます。これだけで Preview 経由の情報漏洩リスクは大幅に下がります。
本番URL(カスタムドメイン)はそのまま公開アクセス可能なので、顧客の利便性は下がりません。
drawing-cognitive-test の Firebase APIキー制限
Firebase の API Key(AIza...)は設計上 クライアント(ブラウザ)に露出する前提なので、git履歴に残っても致命的ではありません。
ただし 制限なしで放置すると、第三者がそのキーを使って Firestore 読み込みや Cloud Functions 呼び出しを試みる可能性があります。
GCP Console で「このキーは特定のウェブサイトからのみ使える」と制限すれば安全です。
手順
※ Firebase プロジェクトに対応するGCPプロジェクトを選択
※ 最後のは開発用。本番公開後は削除してもOK
同じ編集画面の下部で「キーを制限」を選び、以下のみにチェック:
- Firebase Installations API
- Token Service API
- Cloud Firestore API(使っている場合)
- Identity Toolkit API(Auth使用時)
→ 左サイドバー [App Check] → reCAPTCHA v3 or Enterprise で有効化
bento_order_web の GASトークン改修
bento_order_web は Google Apps Script (GAS) でスプレッドシートに書き込んでおり、
その認証に VITE_GAS_AUTH_TOKEN という共有トークンを使っています。
VITE_ プレフィックスはクライアントのビルドに埋め込まれるため、
ブラウザの DevTools を開くと誰でも値が読めてしまいます。
さらにGAS側も !GAS_AUTH_TOKEN なら検証スキップする実装のため、空値のままでも動いてしまう設計。
改修方針(3択)
ユーザーがログイン済みなら Firebase が発行する ID Token を取得し、 GAS 側で Firebase の JWT を検証する。既にFirebase認証を使っているので実装追加コストが少ない。
クライアント → Cloudflare Worker → GAS の構造にし、 認証トークンは Worker に置く。クライアントから見えなくなる。
アプリが社内ネットワーク限定で使われており、一般公開されていないなら現状維持も選択肢。 ただし「社内スタッフがDevToolsで鍵を見られる」リスクは残る。
Claude Code に「bento_order_web の VITE_GAS_AUTH_TOKEN を A案(Firebase Auth ID Token)で改修するプラン出して」と相談するのが最短。 所要時間の見積もり:実装2〜3時間、テスト1時間程度。
✅ すべて完了したら
- Claude Code で
/security-checkを再度実行して仕上げ確認 ~/work/SECURITY.mdの §8 インシデント履歴に対応結果を追記- 次回は月1回(毎月第1月曜朝)の
/morningでOAuth棚卸しを自動化
- Vercel x Context.ai と同種のサプライチェーン攻撃
- Preview URL 経由の情報漏洩
- OAuth アプリ経由の Gmail/Drive 情報漏洩
- git 履歴に残った鍵の悪用