IdeaValue

Supabase の RLS を確認する方法:anonキーで他人のデータが読めないか

執筆:IDEAVALU運営 · 更新:

Supabase や Firebase は、ブラウザから直接データベースを読み書きできるのが特長です。そのぶん、データを守る仕組みはデータベース側の設定だけです。RLS が無効なテーブルは、サイトの JS から anon キーを取り出した人に、全件読まれたり書き換えられたりします。

anon キーが公開されていても安全な理由

anon キーは「ログインしていない人」として API を呼ぶための鍵です。どの行を読めるかは、各テーブルの RLS ポリシーで決まります。RLS を有効にしてポリシーを書いていれば、anon キーを持っていても許可された行しか読めません。

反対に、service_role キーは RLS を無視してすべての行を読み書きできる管理者用の鍵です。ブラウザや公開リポジトリに置いてはいけません。

RLS が無効なテーブルを見つける

Supabase のダッシュボードの Security Advisor(Advisors)に、RLS が無効な public スキーマのテーブルが警告として表示されます。SQL Editor で次のクエリを実行しても確認できます。

RLS が無効なテーブルの一覧

select tablename
from pg_tables
where schemaname = 'public'
  and rowsecurity = false;

RLS を有効にしてポリシーを書く

RLS を有効にした直後は、ポリシーがないため誰も読み書きできなくなります(service_role は除く)。必要な操作ごとにポリシーを追加します。次は、ログインユーザーが自分の行だけを扱える例です。

RLS を有効にする

alter table public.todos enable row level security;

自分の行だけ読める・作れる・変えられる

create policy "own rows: select" on public.todos
  for select to authenticated
  using ((select auth.uid()) = user_id);

create policy "own rows: insert" on public.todos
  for insert to authenticated
  with check ((select auth.uid()) = user_id);

create policy "own rows: update" on public.todos
  for update to authenticated
  using ((select auth.uid()) = user_id)
  with check ((select auth.uid()) = user_id);

Firebase の場合

Firestore と Cloud Storage は、セキュリティルールでアクセスを制御します。テスト用の「誰でも読み書きできる」ルールのまま公開していないか確認してください。

Firestore:本人のドキュメントだけ読み書きできる例

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/{document=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

よくある質問

RLS を有効にしたらアプリでデータが読めなくなりました
RLS を有効にするとポリシーがない操作はすべて拒否されます。読み込み(select)・作成(insert)・更新(update)・削除(delete)ごとに、必要なポリシーを追加してください。
この診断で RLS の設定まで確認できますか?
外から見えるのは Supabase を使っていることまでです。実際にどのテーブルが読めるかは、他人のデータベースへのアクセスになるため確認していません。自分のプロジェクトは、上の SQL や Security Advisor で確認してください。
Supabase の RLS 設定を確認する方法|anonキーで読めるデータ | IDEAVALU