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に「動くコード」を作らせると、とりあえず動かすことを優先する。セキュリティ設定は後回しにされがち。結果として:
- AIがSupabaseの初期化コードを生成
- テーブルを作成(RLSはデフォルトで無効)
- 動いたのでそのままデプロイ
- 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)がかかってない家」を自動で探すツールが登場している、というのが今回の話の本質。
まあ家から出る時は鍵かけろってことだ。