転職用のポートフォリオとして、個人でWebアプリ「Hubpin」を作っています。
制作の経緯は「Hubpin 開発記録」に時系列でまとめています。
データベースには行単位のアクセス制御を入れてあります。
自分の行だけが見える、自分の行だけが書き換えられる、という設定です。
入れてあるので、そこは大丈夫なつもりでいました。
工程の区切りで権限の一覧を見に行ったら、全部のテーブルに余計な権限が付いていました。
テーブルごと空にする権限が残っていました
付いていたのは、テーブルの中身をまとめて消す権限でした。
3つのロールと5つのテーブル、全部の組み合わせに付いています。
作り始めたころに、まとめて全権限を渡す書き方をしていた名残でした。
そのあと必要なぶんだけに絞っています。
ただ、絞った対象が読み取りと追加と更新と削除の4つだけで、それ以外の権限は触っていませんでした。
ここだけ、行単位の制御が効きません
問題は、この権限が行単位の制御の外にあることでした。
行ごとのルールが適用されるのは、読み取り、追加、更新、削除の4つです。
テーブルごと空にする操作は、テーブル単位の権限として動くので、行のルールを一切見ません。
行単位の制御を入れてあるから大丈夫、というのが、ここだけ通じませんでした。
今は届かないと分かったうえで、剥がしました
念のため、その権限に届く経路があるかを調べました。
アプリが使っているAPIの層は、そもそもその操作を発行しません。
データベース側に置いた関数からも呼べないことを、1つずつ確認しました。
つまり、いまこの瞬間は誰も届きません。
それでも剥がすことにしました。
今は届かない、というのは、いま手元にある部品がその経路を使っていないというだけです。
経路そのものが閉じたわけではありません。
関数を1つ足した日に、行の制御が効かない場所として残ります。
1行のマイグレーションで剥がして、権限の一覧と、公開ページと、ログイン後の画面を見て、動くことを確かめました。
翌日、すぐ隣に同じ形が残っていました
これで終わりだと思っていたら、翌日の全体レビューで続きが出ました。
画面をひとつも作っていないテーブルに、書き込みの権限が開いていました。
行を守るルールも入ってはいたのですが、持ち主だけを見ていて、どのカードに紐づいているかを見ていません。
表示する側も、そのテーブルの持ち主を確かめていませんでした。
この組み合わせだと、他人のページに自分のデータを並べられる形になります。
こちらも1行で塞ぎました。
2ヶ月前にも、同じ形を1件直していました
ここが引っかかったところです。
2ヶ月前にも、画面が無いのに書き込み権限が開いている、という状態を1件直しています。
同じ形が、別のテーブルで、2ヶ月後に出ました。
1度直したときに直っていたのは、そのとき見た1枚だけでした。
画面から辿ると、画面の無いところが残ります
2件とも、画面を作っていない場所で起きています。
画面が無いから書けない、とどこかで思っていました。
画面を作っていないことは、権限を閉じた理由にはなりません。
絞ったときも同じです。
使う操作を4つ挙げて、それだけ許可したつもりでした。
実際には、4つについては考えて、残りについては考えていませんでした。
権限は画面から辿るのではなく、権限の一覧のほうから見るしかなさそうです。
