なぜ危ないのか
anon keyはSupabaseがクライアント向けに発行する公開用のJWTトークンで、それ単体でAPIにアクセスできる。Row Level Security(RLS)が有効なテーブルはポリシーで制限されるが、RLSが無効のテーブルに対してはanon keyを持つ誰もがSELECT・INSERT・UPDATE・DELETEを実行できる状態になる。AI生成HTMLはRLS設定の状況を考慮せずコードを生成するため、意図せず危険な状態が作られやすい。
JSONウェブトークンであるanon keyをデコードすると、プロジェクトのURLや有効期限などのメタ情報が読み取れる。攻撃者はこれをもとにSupabase APIのエンドポイントを特定し、curl等で直接クエリを実行することができる。HTMLを受け取った社外の人物がセキュリティ知識を持っている場合、共有から数分以内にデータへのアクセスが可能になるリスクがある。
- 相手がログインなしで開ける状態か確認する
- PCとスマホで最低1回ずつ表示を確認する
- 内部情報・個人情報・不要な外部送信が残っていないか見る
- レビュー期限と修正時の差し替え方を決めておく
ソースで見る場所
HTMLファイルの `<script>` タグ内にある `supabase.createClient(url, key)` の第2引数を確認する。keyが `eyJ` で始まる長い文字列であれば、それがanon keyだ。`supabase-js` のCDN読み込みと一緒に定義されているケースが最も多い。ファイル全体で `createClient` を検索すると呼び出し箇所をすべて洗い出せる。
環境変数を使っているように見えても実際は値が直書きされているケースがある。`const url = 'https://xxxxx.supabase.co'` のように文字列がそのまま書かれていれば、環境変数ではなくハードコードだ。Supabaseのプロジェクトドメイン(`.supabase.co`)を検索するだけでも接続先が含まれているかを確認できる。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
安全に共有する設定
最も安全な方法は、共有前にanon keyとプロジェクトURLを両方プレースホルダに置き換えることだ。`YOUR_SUPABASE_URL`・`YOUR_ANON_KEY`のようなダミー文字列に置換し、動作しない状態にしてから共有する。見た目や構造のレビューだけが目的であれば、これで十分対応できる。
動作確認込みのレビューを求められる場合は、Supabaseの無料プランでデモ専用プロジェクトを作成し、ダミーデータのみを入れた状態でanon keyを発行して埋め込む。本番プロジェクトのキーとは完全に分離できるため、万一漏えいしても本番への影響がない。レビュー期間終了後はデモプロジェクトを削除してキーを消去する。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
再発防止ルール
Supabase接続コードを含むHTMLをAI生成する際は、プロンプトに「URLとanon keyは文字列リテラルではなく、`SUPABASE_URL`・`SUPABASE_ANON_KEY`という識別子で表記する」と指示する。AIはこの指示に従い、実際の値を出力しなくなる。この習慣を全員が守れるよう、プロンプトテンプレートとして共有フォルダに保存しておく。
Supabase管理画面でanon keyをローテーション(再生成)する手順も事前に把握しておく。漏えいが発覚した場合、管理画面の「Project Settings」→「API」ページからkeyを再生成すると旧keyが即時無効になる。service_role keyは絶対にHTMLに含めないルールも同時に徹底し、もしHTMLで発見された場合は最優先でローテーションする。
- HTML内の外部script・form action・iframeを確認する
- APIキーやトークンらしき文字列がないか検索する
- 画像・CSS・JSのパスが公開後も解決できるか見る
- noindexと認証を混同せず、必要なら両方設定する
よくある質問
RLSを有効にしていれば、anon keyが漏えいしても問題ありませんか?
RLSが正しく設定されていればアクセスは制限されるが、ポリシーの設定ミスや認証済みユーザー向けのデータが意図せず公開設定になっていることがある。RLSだけを信頼するより、keyをHTMLに含めない設計を優先する方が安全だ。
anon keyとsecret keyを間違えてHTMLに入れた場合、どうすればよいですか?
service_role(secret)keyをHTMLに入れた場合は、Supabaseの管理画面からただちにキーをローテーションする。service_role keyはRLSを無視してすべてのデータを操作できるため、漏えい後の影響範囲は非常に広い。ローテーション後に影響範囲の調査と関係者への通知を行う。
Supabaseの「Publishable API key」はanon keyと同じものですか?
Supabaseのドキュメントではanon keyをpublishable keyとも表記する。どちらも同じキーを指しており、クライアントサイドに公開することを想定しているが、RLSの設定が不十分な状態では公開すべきでない点は変わらない。