はじめに
前回の動画では、クライアントに見せてはいけない API キーなどをコードに記載してしまうと、ブラウザの開発者ツール(ネットワークタブや要素のタブ)から漏れてしまうこと、そしてサービスロールキーは基本的に使わないようにすべきであることを解説しました。
今回は、サービスロールキーを使わず、SPA で通常利用する anon key ベースの URL を使っていたとしても、RLS(Row Level Security)ポリシーを設定していなければ情報が漏洩してしまうという問題を、実際にデータを盗む操作を通して解説します。
RLS が未設定だとデータが筒抜けになる
まず、現状で RLS ポリシーが設定されているかどうかを確認します。Supabase のテーブルに RLS Disabled と表示されている場合、これは Row Level Security が無効な状態です。何もセキュリティが設定されていないため、この状態ではデータが筒抜けになっています。
たとえば第三者がブラウザのコンソールから Supabase に関する関数を呼び出すと、テーブルの内容がそのまま表示されてしまいます。どのユーザーが管理しているか、タイトルは何か、どんな TODO があるか、完了・未完了といった、すべてのデータが取得できてしまう状態です。
ゲストユーザーでも覗ける
「ログインしているからコンソールで見えるだけでは?」と思うかもしれませんが、これはログインしていないゲストユーザーでも中身を覗けてしまいます。
シークレットウィンドウを開いて、ログインしていない状態で localhost を開き、同様に全件取得のテーブルを叩いてみると、データが取得できてしまいます。クライアント側ではフィルターをかけているため画面上の TODO は見えませんが、データベースに対して直接アクセスすると、RLS ポリシーを設定していないため、コンソールで JavaScript を実行するだけで他のユーザーの TODO がすべて覗けてしまうのです。
取得だけでなく挿入もできてしまう
第三者ができるのは取得だけではありません。挿入(INSERT)操作も実行できてしまいます。
今回は select 関数ではなく insert 関数を使ってみます。先ほどユーザー ID が漏洩しているので、それを使うこともできますし、新しいユーザー ID を入れ込んで挿入することもできます。実行すると、3 件のデータが挿入できてしまいました。実際に Supabase の中身を確認すると、新しい TODO が 3 件追加されています。
さらに、漏洩したユーザー ID をコピーして挿入時のユーザー ID 部分を書き換えると、ログインしているユーザーの TODO に勝手にデータが追加されてしまう、ということも起こり得ます。
このように、Supabase を使っている方が「RLS の設定が面倒だから」と Disabled の状態にしてしまうと、第三者に自由にデータをいじられてしまいます。十分に気をつけてください。
対策:RLS を有効化してポリシーを設定する
では、どうすればいいのでしょうか。まず RLS を Enable の状態にします。デフォルトで Enable になっているので通常は問題ありません。
ただし、有効化しただけの状態では RLS が強固すぎて、自分が投稿した TODO さえ見られず、TODO を追加することもできません。そこで、ログインしている自分だけは投稿・閲覧できるという設定を自分で行う必要があります。
Supabase MCP サーバーを使って設定する
RLS ポリシーの設計は、Supabase MCP サーバーを接続して「ログインしているユーザーだけが見えるように RLS ポリシーを設定して」と依頼すれば、AI がやってくれます。
RLS の確認場所は、Supabase の Authentication の Policies というところです。たとえば select(取得)のポリシーに次のような条件が設定されます。
auth.uid() = user_id
これは「ログインしているユーザーのみが操作できる」という意味です。SQL やプログラミングの知識が必要な部分なので難しく感じるかもしれませんが、これを設定しておくことが重要です。AI がなかった時代はこれをすべて手動で付けていたので大変でした。取得・挿入・削除・編集(SELECT / INSERT / DELETE / UPDATE)のすべての操作に対して RLS を設定します。
設定後の挙動を確認する
設定をリロードすると、自分の TODO はきちんと見えるようになります。一方でゲストユーザーは見ることができなくなっています。実際に同じ取得の処理を叩いてみると、データが見えなくなっており、RLS でガードできていることが確認できます。
挿入の処理を試みても、次のようにエラーになります。
new row violates row-level security policy
ローレベルセキュリティのエラーが返るため、ログインユーザーだけが削除・編集でき、第三者のユーザーは攻撃できなくなりました。
運用上の注意点
Supabase を使っている方は、RLS の設定をぜひ見直してみてください。なるべく MCP を紐付けてチェックさせたほうが安全です。
ただし、本番データベースを MCP 経由でいじれる状態にすると、AI が誤ってデータを削除してしまう可能性があります。取り扱いには十分注意してください。確認するのであれば、開発用のデータベースに対して MCP を紐付けてチェックするのがおすすめです。
以上が、RLS 未設定によるハッキングの仕組みと対策でした。引き続き脆弱性を見ていきます。