快轉到主要內容

Supabase的RLS警告

·1265 字·3 分鐘
目錄

前情提要
#

最近收到Supabase的警告信,內容說我在Supabase裡的table都是公開的,任何人都可以修改,是嚴重的資安問題。一開始有點不太懂是甚麼意思,Supabase登入是需要身分驗證的,為什麼還有被惡意修改的機會?然後它提到的RLS又是甚麼?

RLS
#

RLS = Row-Level Security,它是一種database的安全管理機制,限制不同的使用者在同一個table中的操作 - 只能看、修改符合特定條件的資料(row)。要使用RLS,你要先啟動它,然後設定Rule決定哪些人能做甚麼事情。
沒有設定RLS會遭受怎麼樣的攻擊? 留言板並沒有’刪除’功能,照理說使用者是無法刪除留言的,但對於hacker來說,他們其實不需要透過你的網頁介面,只要拿到你網頁的API憑證就可以了 - 打開瀏覽器按 F12(開發者工具)-> Network(網路)或檢視網頁原始碼,任何人都能看見Supabase Project URL和Anon Public Key;只要這兩筆資訊,hacker就可以繞過你的網頁直接對Supabase下指令,而因為你沒有設定RLS,可以很容易的刪除惡搞你的資料。

Note

但目前我的留言板是用Waline,後端是Vercel,當有新留言時
➡️ 瀏覽器把留言傳給Vercel後端
➡️ Vercel 拿到資料後,撈出藏好的 Supabase 憑證
➡️ 由 Vercel 把資料寫入 Supabase。實際上用F12是看不到supabase project URL和public key的,但為免後患,設定RLS還是要做。

在Supabase設定RLS
#

Supabase我有三個table: user(也就是我自己,是adminstrator)、count和comment。user是最重要的,如果亂改或刪掉,我等於失去網頁主導權;count是計算觀看次數,comment則是留言內容。
到Supabase中table edit畫面,點進去你的table, 找到Enable RLS的按鈕按下啟動RLS;點進去後找到Create policy編輯可以存取該table的條件。以comment這個table為例,我允許任何人新增和觀看comment,因此添加了兩個rules:

  • Allow public insert
    • Policy command選INSERT
    • Target選ANON
    • with check那邊填true
  • Allow public read
    • Policy command選SELECT
    • Target選ANON
    • using那邊填true

with check和using
#

with check 的字面意思:當有人想要塞新資料(INSERT)進來時,這筆新資料必須符什麼條件,資料庫才願意收。輸入 true 等於告訴資料庫,「這筆新資料不管長怎樣、是誰送來的,通通符合條件」。 假設今天是會員制,只有會員有資格留言的話,with check就可能如下:

with check (
    -- 檢查:新留言的 auth_id 必須等於目前登入使用者的 ID
    auth.uid() = user_id
);

with check是用在寫入全新資料時,如INSERT、UPDATE;using是針對資料庫原本就有的資料的操作,如SELECT(讀)、DELETE。而with check和using不應擅自混用,所以comment這個table會有兩條rules去設定comment的讀寫。


閱讀次數: