技術 約4分で読めます

SupabaseのAPIキーが丸見えでも安全な理由とRLSの重要性

最近、SupabaseのAPIキーを自動検出するブラウザ拡張機能が話題になった。「APIキーをぶっこ抜く」と聞くとハッキングっぽいが、実際はWebページのソースコードに書かれている文字列を拾っているだけ。

なぜそんな簡単に見つかるのか?それはSupabaseの仕様として、APIキーはフロントエンドに露出する前提で設計されているから。

で、なぜその設計で安全なのか、何が本当のリスクなのかを整理してみた。

Supabaseの2種類のAPIキー

Supabaseには主に2種類のAPIキーがある。

Anon Key(公開キー)

  • フロントエンドで使用する
  • 見られても問題ない
  • 「ログインしていないユーザー」としての権限しか持たない
  • RLS(後述)と組み合わせて使う前提

Service Role Key(秘密キー)

  • サーバーサイドでのみ使用する
  • 絶対に公開してはいけない
  • RLSをバイパスして全データにアクセス可能
  • 管理者権限と同等

公式ドキュメントでも明確に警告されている。

Never expose your service_role and secret keys publicly. Your data is at risk.

なぜAnon Keyは露出しても安全なのか

ブラウザで動くアプリケーションは、そのコードがユーザーのPCにダウンロードされて実行される。つまり、開発者ツール(F12)でソースを見れば、どんなAPIキーでも見つけられる。

これを隠す方法はない。隠したいなら、すべてのSupabase呼び出しを自サーバー経由にするしかない。

Supabaseはこの現実を受け入れた上で、Anon Keyが露出しても安全なアーキテクチャを採用している。その鍵がRLS(Row Level Security)。

RLS(Row Level Security)とは

RLSはPostgreSQLの機能で、テーブルの行単位でアクセス制御を行う仕組み。

例えば「ユーザーは自分のデータだけ読み書きできる」というポリシーを設定できる。

-- usersテーブルでRLSを有効化
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

-- 自分のデータだけ読める
CREATE POLICY "Users can view own data"
ON users FOR SELECT
USING (auth.uid() = id);

-- 自分のデータだけ更新できる
CREATE POLICY "Users can update own data"
ON users FOR UPDATE
USING (auth.uid() = id);

RLSが有効な状態では、Anon Keyを使ってAPIを叩いても、ポリシーで許可された範囲のデータしかアクセスできない。

問題:RLSを設定していないアプリ

Supabaseでテーブルを作成すると、デフォルトではRLSが無効になっている。この状態でAnon Keyを使うと、誰でも全データにアクセスできる

公式ドキュメントより:

Any table without RLS enabled in the public schema will be accessible to the public, using the anon role.

つまり:

  • Anon Keyは見えても安全 → RLSが正しく設定されていれば
  • RLSが無効だと → データベースが全公開状態

AIコード生成ツールで作られたアプリが狙われる理由

2025年、AIコード生成プラットフォーム「Lovable」で作成されたアプリに脆弱性が発見された(CVE-2025-48757)。170以上のアプリが影響を受け、約13,000人のユーザーデータが露出した。

原因はシンプル。RLSポリシーが設定されていなかった

AIに「動くコード」を作らせると、とりあえず動かすことを優先する。セキュリティ設定は後回しにされがち。結果として:

  1. AIがSupabaseの初期化コードを生成
  2. テーブルを作成(RLSはデフォルトで無効)
  3. 動いたのでそのままデプロイ
  4. Anon Keyは丸見え + RLS無効 = 全データ公開

話題になっている拡張機能は、この「RLSなしで公開されているサイト」を効率的に見つけるツールということになる。

SupaExplorer:セキュリティ検証ツール

話題になっている拡張機能の一つが「SupaExplorer」。セキュリティエンジニア向けのChrome拡張機能で、以下の機能を持つ。

  • WebページからSupabase APIキーを検出
  • RLSポリシーの監査
  • 露出しているテーブルの一覧表示
  • AWS、Stripe、OpenAIなど15種類以上のAPIキー検出

すべての処理はローカルで実行され、外部にデータを送信しない。

公式サイト: supaexplorer.com

自分のプロジェクトのセキュリティチェックに使える。

対策チェックリスト

Supabaseを使う場合、以下を確認する。

必須

  • すべてのテーブルでRLSを有効化している
  • 適切なRLSポリシーを設定している
  • Service Role Keyをフロントエンドで使っていない
  • 環境変数にNEXT_PUBLIC_VITE_プレフィックスでService Role Keyを設定していない

推奨

  • Supabaseダッシュボードの「Database > Tables」でRLS状態を確認
  • SupaExplorerなどのツールで自サイトをスキャン
  • 機密性の高い処理はEdge Functionsに移動

まとめ

  • SupabaseのAnon Keyが見えるのは仕様であり、それ自体は問題ない
  • セキュリティはRLS(Row Level Security)で担保する設計
  • RLSを設定していないと、データベースが全公開状態になる
  • AIコード生成ツールはRLS設定を忘れがちなので注意

「玄関の鍵(Anon Key)は置いてあるけど、ドアチェーン(RLS)がかかってない家」を自動で探すツールが登場している、というのが今回の話の本質。

まあ家から出る時は鍵かけろってことだ。