セキュリティ

AI生成HTMLにSupabase anon keyが残っていないか確認する方法

AIにダッシュボードやデータ一覧のHTMLを生成させると、Supabase接続用のanon keyがJavaScriptの中に埋め込まれたまま納品されることがある。anon keyはRow Level Securityの設定次第でデータベース全体を読み取られるリスクがあり、公開前の確認が必須だ。確認箇所と手順を具体的に解説する。

なぜ危ないのか

Supabaseのanon keyはクライアントサイドに公開することを前提に設計されているが、それはRow Level Security(RLS)が適切に設定されていることが大前提だ。AIが生成したHTMLにはRLSの設定情報が含まれないため、RLSが無効なテーブルへのanon keyを埋め込んだ場合、全行を読み取られるだけでなくINSERTやDELETEまで実行されうる。

さらに問題なのは、AIがanon keyをJavaScriptの変数として直接書き込む点だ。`const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'`のような形式で埋め込まれると、ファイルをそのままメールで送信した場合やブラウザの「ソースを表示」で丸見えになる。特にJWTはBase64デコードするとプロジェクトURLやロールなど付加情報が含まれており、攻撃の手がかりになりやすい。

  • 相手がログインなしで開ける状態か確認する
  • PCとスマホで最低1回ずつ表示を確認する
  • 内部情報・個人情報・不要な外部送信が残っていないか見る
  • レビュー期限と修正時の差し替え方を決めておく

ソースで見る場所

HTMLファイルで `eyJ` という文字列を検索するのが最速だ。JWTはBase64エンコードされたヘッダーが `eyJhbGciOi` で始まるため、このプレフィックスを検索するだけでanon keyや他のJWTトークンを網羅できる。VS Codeなら Ctrl+F で `eyJ` を入力、ファイル内に一致があればその行を確認する。

`supabase.createClient` や `createClient(` の呼び出し箇所もチェックポイントだ。第2引数にキーが直接書かれていることが多い。また、`SUPABASE_ANON_KEY`・`anonKey`・`anon_key` のような変数名で定義されているケースもあるため、これらのキーワードでもファイル内を検索しておくと見落としを防げる。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

安全に共有する設定

anon keyが見つかった場合は、まずSupabase管理画面でそのプロジェクトのRLS設定を確認し、全テーブルでRLSが有効になっているかチェックする。有効でない場合はHTMLを共有する前にRLSを有効化するか、keyをプレースホルダに置き換えた状態でファイルを渡す。プレースホルダに置き換えたファイルであれば、Supabaseへの接続そのものができないため情報漏えいのリスクはない。

ギガサイト便などのプレビュー共有サービスを使う場合も同様で、アップロード前にkey置換を行い、認証付きのURLで共有する。レビュー完了後はプレビューリンクを失効させることを忘れずに。もし動作確認が必要なデモ環境を共有したい場合は、Supabase上にテスト用プロジェクトを別途作成し、本番データを含まない状態でデモ用anon keyだけを使うよう切り替えるのがベストプラクティスだ。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

再発防止ルール

AIへのHTMLプロンプトに「Supabase接続情報(URL・anon key)は変数宣言にせず、`SUPABASE_URL`・`SUPABASE_ANON_KEY`というプレースホルダテキストを使うこと」と明示する。この制約を最初の行に入れるだけで、AIは実際のキー値を出力しなくなる。生成後の確認工数が大幅に下がる。

チームでのレビューフローにも組み込む。コードレビューのチェックリストに「`eyJ`でHTMLを全文検索してJWTがないことを確認」という項目を追加し、Merge/公開前に必須確認とする。CIがある場合は`grep -r 'eyJ' ./public/`をチェックジョブとして追加すると自動化できる。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

よくある質問

anon keyはservice_role keyとどう違い、どちらがより危険ですか?

service_role keyはRLSを完全に無視してすべてのデータを読み書きできるため、anon keyより格段に危険だ。HTMLに含まれてはならないのはservice_role keyで、anon keyはRLS設定が正しければ比較的安全だが、それでも本番データへの不用意なアクセスを防ぐため公開HTMLには含めないのが原則だ。

誤ってanon keyをメールで送ってしまいました。どう対処すればよいですか?

Supabase管理画面の「API」セクションからanon keyを再生成(ローテーション)する。再生成後は旧キーが無効になるため、正規のクライアントアプリに新キーを反映させる必要がある。同時に、RLSが全テーブルで有効になっているか確認しておく。

デモ用途でanon keyをHTMLに含めることは絶対に避けるべきですか?

Supabase側でRLSを有効にし、デモ用の読み取り専用データのみ閲覧を許可するポリシーを設定しているなら、限定的には許容できる。ただし本番データが含まれるプロジェクトのキーをデモに流用するのは避け、必ずサンドボックス用の別プロジェクトを使うこと。

関連記事

セキュリティ

Supabase anon keyを防ぐAIプロンプトと公開前スキャン

Supabaseのanon keyをAI生成HTMLに含めないためのプロンプト設計と、生成後の自動スキャン方法を知りたい開発者向け。具体的なプロンプト例とコマンドを使って実践的な防止フローを選べる。

5分で読める
セキュリティ

AI生成HTMLにStripeキーが残っていないか確認する方法

AI生成HTMLにStripeのキーが含まれていないか確認したいエンジニア・担当者向け。キーの種類ごとのリスク差と、ファイル内で見つけるための具体的な検索手順・対処法を理解できる。

5分で読める
「セキュリティ」の記事をもっと見る →