
Firebaseの代替となるオープンソースBaaS(Backend as a Service)として、個人開発やスタートアップで圧倒的な人気を誇るのがSupabaseです。PostgreSQLの強力なリレーショナル機能に加え、認証(Auth)、自動生成API、ストレージ、Edge Functionsが統合されており、Webアプリやモバイルアプリを迅速に構築できます。
しかし、その強力さの裏返しとして、アクセス制御の設計ミスやAPIキーの誤管理によるセキュリティインシデントが後を絶ちません。「RLS(Row Level Security)を有効化し忘れて顧客データが第三者に丸見えになっていた」「誤ってフロントエンドに service_role 秘密キーを公開してしまい、全データベースをダンプ(持ち出し)された」「身に覚えのない大量のスパムユーザーがAuthに登録されている」。このような事態に直面したとき、Supabaseのどのログを、どのように確認すれば侵害状況を正確に把握できるでしょうか。
この記事では、Supabaseを利用する個人開発者やエンジニア向けに、不正アクセスの体系的な調査手順を解説します。Auth Audit Logsによる不審な認証イベントの追跡、PostgreSQLおよびAPIログの精査、全テーブルにおけるRLS有効化状況のSQL検証、APIキー(anon vs service_role)の漏洩点検、そしてプランごとのログ保持日数の違いまで詳しく整理しました。
この記事で行うこと
- Supabaseで頻発する代表的な3大侵害シナリオを理解する
- Auth Audit Logsを用いて不正ログイン・未知のサインアップ・接続元IPを特定する
- データベース内の
auth.audit_log_entriesテーブルを直接SQLで調査する - API Logs(REST / Storage / Edge Functions)とPostgres Logsから異常リクエストを追跡する
- 全テーブルでRLS(行単位セキュリティ)が有効化されているかをSQLで一括点検する
anonキーとservice_roleキーの違いを把握し、キー漏洩時のローテーション手順を学ぶ- FreeプランとProプランにおけるログ保持日数の差とPlatform Audit Logsの仕様を押さえる
前提条件・対象読者
- Supabaseを利用してWebアプリケーションやモバイルアプリを個人開発・運用している方
- データベースやユーザー認証に不正アクセスの兆候があり、ログを調査したい方
- Supabase Studio(管理ダッシュボード)およびSQL Editorを操作できる方
- 最終確認日:2026年11月(Supabase公式ドキュメントに基づく)
1. Quick Reference:Supabase不正アクセス調査の優先度別早見表
異常を察知した直後は、被害データの特定と情報流出の遮断を速やかに進める必要があります。
| 優先度 | 調査対象・作業項目 | 主な確認画面 / ツール | 検出できる異常・目的 |
|---|---|---|---|
| P1 | APIキー露出の点検 | Settings > API / クライアントコード | service_role 秘密キーがフロントエンドに混入していないか |
| P1 | RLS有効化状況の一括検証 | SQL Editor(pg_tables 照合クエリ) | RLSが無効で誰でも読める危険なテーブルの特定 |
| P1 | Auth Audit Logsの確認 | Authentication > Logs(またはSQL) | 攻撃者のログイン成功、未知IPからのサインアップ |
| P2 | 不正な登録ユーザー点検 | Authentication > Users | スパムボットによる大量登録、未認証アカウント |
| P2 | API Gateway Logs追跡 | Logs > Log Type: API Gateway | anon キー経由の大量データ取得、401/403多発 |
| P2 | Storage Logsの点検 | Logs > Log Type: Storage | プライベートバケットからの不正ダウンロード |
| P3 | Postgres Logsの確認 | Logs > Log Type: Postgres | 実行時間の長い不審なクエリ、DBエラーの急増 |
| P3 | Platform Audit Logsの確認 | Organization Settings > Audit Logs | チームメンバーによる管理設定変更・キー再発行(Team以上) |
2. Supabaseで頻発する代表的な3大侵害シナリオ
Supabaseのインシデントは、インフラ自体の脆弱性ではなく、開発者の権限設計ミスや設定漏れに起因するものが大半です。
2-1. RLS(Row Level Security)未設定による全件データ持ち出し
PostgreSQLのRLSは、行単位でアクセス権限を制御する機能です。Supabaseでは、テーブルを作成した際に明示的にRLSを有効化しない場合、初期設定のままでは「anon キー(誰でも入手できる公開APIキー)を持つ外部の第三者が、REST API経由でテーブル内の全レコードを SELECT できてしまう」という致命的なセキュリティホールになります。 外部の攻撃者は、WebサイトのJavaScriptからSupabaseのURLと anon キーを抽出し、https://<project-ref>.supabase.co/rest/v1/users?select=* のようなエンドポイントを直接叩いて、顧客リストや個人情報を一括ダウンロードします。
2-2. service_role 秘密キーのクライアント側露出
Supabaseには、ブラウザやアプリに持たせる「anon キー(公開用)」と、サーバーサイドでのみ使用する「service_role キー(管理者用秘密鍵)」の2種類が存在します。 service_role キーは、RLSポリシーを完全にバイパスしてデータベース内の全テーブル・全レコードを自由に読み書き・削除できる絶対的な権限を持っています。Next.jsなどのフロントエンドコードで誤って環境変数に NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY と名付けてビルドしたり、リポジトリにコミットしたりすると、キーを拾った攻撃者にデータベースを完全に掌握されます。
2-3. 認証突破とスパムユーザーの自動登録
メールアドレス確認(Confirm email)を無効化した状態でサインアップエンドポイントを公開していると、攻撃者のスクリプトによって使い捨てメールアドレスを用いた架空ユーザーが何千件・何万件も自動生成されます。 また、パスワードポリシーが脆弱だったり、レートリミットを設けていなかったりすると、既存ユーザーに対するクレデンシャルスタッフィング(パスワード総当たり)攻撃を受け、正規ユーザーのアカウントが乗っ取られます。
3. Auth Audit Logs(認証監査ログ)の調査手順
認証機能(Supabase Auth)への侵入や不審な操作は、Auth Audit Logsを精査することで追跡できます。
3-1. ダッシュボードでの確認方法
Supabaseダッシュボードの左メニュー「Authentication」>「Logs(またはAudit Logs)」を開きます。
記録される主なイベント種別
login: ユーザーのログイン試行(成功および失敗)signup: 新規ユーザー登録token_refreshed: JWTアクセストークンの更新user_recovery_requested: パスワードリセットメールの送信要求user_updated: メールアドレスやパスワードの変更logout: セッションのログアウト
ログから見つけるべき異常の兆候
- 同一のメールアドレスに対して、短時間に大量の
login失敗が記録されている(ブルートフォース攻撃) - 海外(見覚えのない国やデータセンター)のIPアドレスから、管理者ユーザーへの
login成功が記録されている - 深夜帯に複数のユーザー宛てに一斉に
user_recovery_requestedが発行されている
3-2. SQL Editorを用いた高度な監査ログ調査
Supabaseでは、認証監査ログが内部データベースの auth.audit_log_entries テーブルに記録されています。SQL Editorから直接SQLクエリを実行することで、ダッシュボードのGUIよりも柔軟かつ詳細に分析できます。
直近のログイン・サインアップ履歴をIPアドレス付きで抽出するSQL
SELECT
created_at,
ip_address,
payload->>'action' AS action,
payload->>'actor_username' AS username,
payload->>'actor_id' AS actor_id,
payload
FROM auth.audit_log_entries
ORDER BY created_at DESC
LIMIT 50;
不審なIPアドレスからのアクセスをグループ化して集計するSQL
SELECT
ip_address,
COUNT(*) AS request_count,
payload->>'action' AS action,
MIN(created_at) AS first_seen,
MAX(created_at) AS last_seen
FROM auth.audit_log_entries
GROUP BY ip_address, payload->>'action'
HAVING COUNT(*) > 10
ORDER BY request_count DESC;
特定のIPアドレスから突出してリクエストが集中している場合、そのIPアドレスを特定してファイアウォールやWAFでブロックするなどの対策を講じることができます。
3-3. 不審なユーザーアカウントとアクティブセッションの点検
左メニュー「Authentication」>「Users」を開き、登録ユーザー一覧を点検します。
確認すべきポイント
- 登録日時(Created)が直近で、ランダムな文字列(例:
abc12345@tempmail.com)のユーザーが短時間に急増していないか - 「Last Sign In」が最近になっている管理者アカウントに見覚えがあるか
- 不正ログインが疑われるユーザーが存在する場合は、対象ユーザーの詳細画面から「Log out user」をクリックして既存の全セッションを即時無効化するか、アカウントを削除する
4. API Gateway・Postgres・Storageログの精査手順
Supabaseダッシュボードの左メニュー「Logs」は、全サービスを一元管理する統合ログ(Unified Logs)画面になっています。画面上部にある「Log Type」ドロップダウンから対象のサービスを切り替えて調査します。
4-1. API Gateway Logs(REST / GraphQL / Edge Functions)の確認
「Log Type」で「API Gateway」を選択すると、外部からSupabaseのAPIゲートウェイ(Kongリバースプロキシ)を通過した全HTTPリクエストの一覧が表示されます。
調査すべきポイント
- メソッドとパス:
GET /rest/v1/customers?select=*やDELETE /rest/v1/ordersのような、機密テーブルに対する全件取得や一括削除リクエストがないか - HTTPステータス: 401(Unauthorized)や403(Forbidden)が連続して発生している場合、攻撃者がAPIキーを推測したり、RLSポリシーを突破しようと試行錯誤している痕跡です
- クライアントIPとリクエスト数: 通常時と比べて特定の時間帯に特定IP(
cf-connecting-ip)からのリクエスト数が急増していないか
4-2. PostgreSQL Logsの確認
「Log Type」で「Postgres」を選択すると、データベースエンジンが出力したログやスロークエリ、エラーメッセージを確認できます。
調査すべきポイント
FATAL: password authentication failed for user "postgres": データベースの直接接続ポート(5432 / 6543)に対してパスワード総当たり攻撃が行われている兆候- 構文エラーやテーブル走査エラーの多発: 攻撃者がSQLインジェクションを試みたり、存在しないシステムカタログを探している痕跡
4-3. Storage Logsの確認
Supabase Storageにファイル(画像、PDF、ドキュメント等)を保存している場合は、「Log Type」で「Storage」を選択します。
調査すべきポイント
- プライベートに設定しているはずのバケットから、未知のIPアドレス宛てに大量のファイルダウンロード(GETリクエスト)が行われていないか
- 容量の大きなファイルが短時間に連続してダウンロードされ、Egress(送信帯域)が跳ね上がっていないか
5. RLS(Row Level Security)有効化状況の完全検証
Supabaseにおいて最も重大な情報漏洩原因となるのが「RLSの有効化忘れ」です。全テーブルの安全性を一括で検証する手順を押さえましょう。
5-1. 全テーブルのRLS状態を検証するSQL
SQL Editorを開き、以下のSQLクエリを実行します。公開スキーマ(public)内に存在する全テーブルについて、RLSが有効化されているかどうかを一括チェックします。
SELECT
schemaname,
tablename,
rowsecurity AS is_rls_enabled
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY rowsecurity ASC, tablename ASC;
クエリの実行結果で、is_rls_enabled が false になっているテーブルが存在する場合、そのテーブルはRLSが無効化された無防備な状態です。
5-2. RLSが無効化されていた場合の緊急対処
is_rls_enabled が false のテーブルが見つかった場合は、直ちに以下のSQLを実行してRLSを強制有効化します。
-- 対象テーブルのRLSを有効化する(全アクセスが初期状態で拒否される)
ALTER TABLE public.your_table_name ENABLE ROW LEVEL SECURITY;
重要:RLSを有効化しただけでは、ポリシー(Policy)が存在しないため、service_role 以外のすべてのアクセス(認証済みユーザー含む)が遮断されます。続いて、適切なアクセス権限を定義するポリシーを作成します。
-- 例: ログイン中のユーザー自身が作成したレコードのみ閲覧・操作を許可するポリシー
CREATE POLICY "Users can only access their own records"
ON public.your_table_name
FOR ALL
USING (auth.uid() = user_id);
6. APIキーの点検と漏洩時の緊急ローテーション手順
APIキーの取り違えや流出は、データベースの完全崩壊を招きます。
6-1. APIキーの役割と点検ポイント
「Settings」>「API」を開き、発行されているキーを確認します。
anon(Publishable)キー
公開を前提としたキーです。ブラウザやモバイルアプリに直接埋め込んで使用します。ただし、このキーは「RLSが完全に有効化されていること」を大前提として安全性が担保されています。
service_role(Secret)キー
管理者権限を持つ秘密鍵です。RLSをすべてバイパスしてデータベースの全操作が可能です。このキーは絶対にフロントエンドのコードやGitHub公開リポジトリに露出させてはいけません。
クライアントコードの点検
開発中のプロジェクトリポジトリで、以下のコマンドを実行して service_role キーが誤って含まれていないか検索します。
git grep -i "service_role"
もしフロントエンド側の .env.local やJavaScriptファイル内で参照されている箇所が見つかった場合は、直ちに該当コードをサーバーサイド専用(API RoutesやServer Actions、Edge Functions)へ退避させます。
6-2. キーローテーション(秘密鍵の再生成)手順
もし service_role キーやデータベースパスワードが外部に漏洩した疑いがある場合は、速やかにローテーションを実行します。
ローテーションの実施手順
- Supabaseダッシュボードの「Settings」>「API」を開く
- 「JWT Settings」セクションにある「JWT Secret」の再生成(Generate a new secret)を行う
- JWT Secretを再生成すると、既存の
anonキーおよびservice_roleキーがすべて無効化され、新しいキーが即座に発行されます - Vercelなどのホスティング環境で設定している環境変数を、新しく発行されたキーに更新して再デプロイする
- データベースの直接接続パスワードも同様に、「Settings」>「Database」から「Reset database password」を実行して再設定する
注意点:JWT Secretの再生成を行うと、現在ログインしている全エンドユーザーの認証セッション(JWT)も無効化されるため、ユーザーは再ログインが必要になります。インシデント発生時は安全を最優先し、影響範囲をアナウンスした上で実施してください。
7. Supabaseで確認できること・確認できないこと(調査の限界)
インシデント調査を行う際、Supabaseの契約プランによって遡れる期間が大きく異なります。
7-1. プラン別のログ保持日数の違い
| プラン区分 | ログ保持日数(Retention) | 備考 |
|---|---|---|
| Freeプラン | 1日間(24時間) | 24時間以上前のAPIログやAuthログは閲覧不可 |
| Proプラン | 7日間 | 直近1週間のインシデント追跡が可能 |
| Teamプラン | 28日間 | 月次の監査・分析に対応 |
| Enterpriseプラン | 90日間 | 長期コンプライアンス要件に対応 |
Freeプランで運用している個人開発プロジェクトでは、ログの保持期間がわずか24時間しかありません。週末に発生した不正アクセスに週明け月曜日に気づいた場合、すでにダッシュボードからは当時のログが消失している可能性があります。
7-2. Platform Audit Logsとの違い
Supabaseには、エンドユーザーの動きを追跡する「Auth Audit Logs」とは別に、組織やプロジェクト自体の変更を記録する「Platform Audit Logs」が存在します。
Platform Audit Logsの対象と特徴
- 対象プラン:TeamプランおよびEnterpriseプラン
- 記録される内容:チームメンバーの追加・削除、プロジェクトの作成・削除、データベースパスワードの変更、APIキーの再発行、Edge Functionsのデプロイなど
- 目的:「誰がいつプロジェクトの設定を変更したか」という管理者側の操作証跡を保全する
個人運用のFree/ProプランではPlatform Audit Logsのフル機能は利用できませんが、チーム設定画面の一般的なアクティビティ履歴から主要な変更を確認できます。
7-3. Supabaseで「確認できること」と「確認できないこと」
Supabaseで確認できること
- ユーザー登録、ログイン失敗、パスワードリセットなどの認証イベント(Auth Audit Logs)
- REST API、GraphQL、Edge Functionsへのリクエスト履歴とHTTPステータス(API Logs)
- PostgreSQLで実行されたSQLクエリおよびエラーログ(Postgres Logs)
- Storageバケットへのファイルアップロード・ダウンロード履歴
- 全テーブルに対するRow Level Security(RLS)の有効化状況と適用ポリシー
Supabaseで確認できないこと・調査の限界
- Freeプランにおける24時間以前の過去ログ(保持期間終了に伴う自動消去)
- クライアント側(ブラウザやモバイルアプリ)に漏洩した秘密キーを使って直接外部から行われた通信の全容
- セッションテーブルに記録されていない過去の接続元IPアドレスの完全な追跡
- Enterpriseプラン以外の一般的なプランにおけるOS内部やPostgreSQL設定ファイルレベルの直接操作ログ
8. よくある質問(FAQ)
Q1. anonキーが漏洩したのですが、すぐに再発行すべきですか?
anon キーはもともとクライアント(ブラウザ)へ渡すことを想定して設計された公開キーであるため、Webサイトを公開している以上、誰でも開発者ツールから確認できます。したがって、anon キーが見えること自体は漏洩ではありません。最も重要なのは、全テーブルでRLSが正しく有効化されており、不正なデータ取得がブロックされているかどうかです。ただし、プロジェクトを完全に非公開にしたい場合や不正利用が著しい場合は、JWT Secretを再生成してキーを刷新することができます。
Q2. RLSを有効化すると、アプリの動作が遅くなりますか?
適切なインデックスが設定されていれば、RLSによるオーバーヘッドは通常ミリ秒未満であり、体感できるほどの遅延は生じません。ただし、ポリシーの条件式で auth.uid() = user_id などの評価を行う際、user_id 列にインデックス(B-treeインデックス)が作成されていないと、テーブル全件スキャン(Seq Scan)が発生してパフォーマンスが著しく低下します。RLSポリシーで参照する列には、必ずインデックスを作成してください。
Q3. Freeプランで過去のログを長期保存するにはどうすればよいですか?
Supabaseの「Log Drains」機能を利用して、Datadog、BigQuery、Axiom、あるいは自前のHTTP Webhookエンドポイントへログをリアルタイム転送(ストリーミング)する構成をとることで、外部ストレージに長期保存できます。また、認証ログに関しては、定期的に auth.audit_log_entries テーブルの内容をバッチ処理で外部ストレージへバックアップするスクリプトを組むことも有効です。
Q4. メールアドレスなしの匿名サインイン(Anonymous Sign-ins)を悪用された場合の対処法は?
匿名認証を有効にしていると、ボットによって大量のゲストセッションが作成され、データベースの容量やAuthユーザー枠を圧迫することがあります。攻撃を受けた場合は、「Authentication」>「Providers」から匿名認証を一時的に無効化するか、Cloudflare TurnstileなどのCAPTCHAをフロントエンドのサインアップフローに導入して、ボットによる自動生成を遮断してください。
Q5. Logs画面に「API」というメニューがありません。「API Gateway」のことですか?
はい、その通りです。現在のSupabaseダッシュボードは「Unified Logs(統合ログ)」画面に刷新されており、左メニュー「Logs」を開いた後、画面上部の「Log Type」ドロップダウンから「API Gateway」を選択します。この「API Gateway」ログに、REST API(PostgREST)やGraphQL、Edge FunctionsへのすべてのHTTPリクエスト履歴(メソッド、パス、ステータス、クライアントIP)が記録されています。
9. まとめ
Supabaseにおける不正アクセス調査は、認証層(Auth)、API層、そしてデータベース層(PostgreSQL/RLS)を多層的に検証することが本質です。
pg_tablesを照会するSQLを実行し、RLSが無効になっている危険なテーブルが1件もないか一括確認する- フロントエンドのコードに
service_role秘密キーが露出していないかgit grepで点検する - Auth Audit Logsおよび
auth.audit_log_entriesテーブルから、不審な接続元IPや未知のサインアップを特定する - 不正ログインが疑われるユーザーのアクティブセッションを即時無効化する
- API LogsおよびPostgres Logsで異常なエラーや集中的なデータ取得リクエストを追跡する
- Freeプランのログ保持期間(24時間)の制約を意識し、重要な本番アプリではProプランへの移行やログ転送を検討する
強力な機能を備えたSupabaseだからこそ、RLSの厳格な設定とキー管理を徹底し、安全なバックエンド環境を維持しましょう。
次に読むおすすめ記事
Supabaseと組み合わせてフロントエンドをホスティングしているVercelの不正アクセス調査手順や、クラウド全体の点検手順は、以下の記事で詳しく解説しています。
個人で運用するWebアプリやクラウド全体のセキュリティ対策まとめは、以下の完全ガイドを参考にしてください。


