DBの権限を見直したら、RLSが効かない権限が全テーブルに付いていた

転職用のポートフォリオとして、個人でWebアプリ「Hubpin」を作っています。
制作の経緯は「Hubpin 開発記録」に時系列でまとめています。

データベースには行単位のアクセス制御を入れてあります。
自分の行だけが見える、自分の行だけが書き換えられる、という設定です。

入れてあるので、そこは大丈夫なつもりでいました。

工程の区切りで権限の一覧を見に行ったら、全部のテーブルに余計な権限が付いていました。

目次

テーブルごと空にする権限が残っていました

付いていたのは、テーブルの中身をまとめて消す権限でした。
3つのロールと5つのテーブル、全部の組み合わせに付いています。

作り始めたころに、まとめて全権限を渡す書き方をしていた名残でした。

そのあと必要なぶんだけに絞っています。
ただ、絞った対象が読み取りと追加と更新と削除の4つだけで、それ以外の権限は触っていませんでした。

ここだけ、行単位の制御が効きません

問題は、この権限が行単位の制御の外にあることでした。

行ごとのルールが適用されるのは、読み取り、追加、更新、削除の4つです。
テーブルごと空にする操作は、テーブル単位の権限として動くので、行のルールを一切見ません。

行単位の制御を入れてあるから大丈夫、というのが、ここだけ通じませんでした。

今は届かないと分かったうえで、剥がしました

念のため、その権限に届く経路があるかを調べました。

アプリが使っているAPIの層は、そもそもその操作を発行しません。
データベース側に置いた関数からも呼べないことを、1つずつ確認しました。

つまり、いまこの瞬間は誰も届きません。

それでも剥がすことにしました。

今は届かない、というのは、いま手元にある部品がその経路を使っていないというだけです。
経路そのものが閉じたわけではありません。
関数を1つ足した日に、行の制御が効かない場所として残ります。

1行のマイグレーションで剥がして、権限の一覧と、公開ページと、ログイン後の画面を見て、動くことを確かめました。

翌日、すぐ隣に同じ形が残っていました

これで終わりだと思っていたら、翌日の全体レビューで続きが出ました。

画面をひとつも作っていないテーブルに、書き込みの権限が開いていました。

行を守るルールも入ってはいたのですが、持ち主だけを見ていて、どのカードに紐づいているかを見ていません。
表示する側も、そのテーブルの持ち主を確かめていませんでした。

この組み合わせだと、他人のページに自分のデータを並べられる形になります。

こちらも1行で塞ぎました。

2ヶ月前にも、同じ形を1件直していました

ここが引っかかったところです。

2ヶ月前にも、画面が無いのに書き込み権限が開いている、という状態を1件直しています。

同じ形が、別のテーブルで、2ヶ月後に出ました。

1度直したときに直っていたのは、そのとき見た1枚だけでした。

画面から辿ると、画面の無いところが残ります

2件とも、画面を作っていない場所で起きています。

画面が無いから書けない、とどこかで思っていました。
画面を作っていないことは、権限を閉じた理由にはなりません。

絞ったときも同じです。
使う操作を4つ挙げて、それだけ許可したつもりでした。
実際には、4つについては考えて、残りについては考えていませんでした。

権限は画面から辿るのではなく、権限の一覧のほうから見るしかなさそうです。

目次