跳到主要內容
知識分享
資安2026.08.057 MIN READ

權限不是上線前才補的東西

「先把功能做出來,權限之後再說」是很常見的順序,但它幾乎一定會讓你在最後一週重寫一次資料存取邏輯。

在系統開發裡,權限常常被排在很後面。先把畫面做出來、先讓流程跑得動,權限「之後再加」。

聽起來很合理,但實際上這個順序有一個問題:權限不是一層可以外掛的東西,它會決定資料怎麼查、怎麼存、怎麼分頁。等到功能都做完才回頭處理,通常會發現要改的不是幾行判斷,而是整個資料存取的寫法。

三個不同層次的權限

把權限分開來想,會比較容易決定每一層要做什麼。

介面層:這個按鈕要不要顯示。這是最表面的一層,也是唯一一層可以被使用者繞過的。

應用層:這個請求可不可以執行。伺服器收到請求時要自己判斷,不能相信前端已經檢查過。

資料層:這筆資料可不可以被讀到。資料庫本身也應該有規則,這樣即使應用層有漏洞,也不會直接把整張表倒出去。

只做第一層,等於沒有做。三層都做,才有辦法在某一層出錯的時候還有東西擋著。

從最小權限開始

比較安全的預設是:一開始什麼都不給,再依角色一項一項加回來。

反過來做(先全部開放,再逐一關掉)幾乎一定會漏掉東西,而且漏掉的地方通常不會有人回報,因為使用者不會抱怨「我看到了不該看的資料」。

-- 不是「這個角色不能看什麼」,
-- 而是「這個角色只能看什麼」
select * from orders
where store_id = current_store_id();

前端隱藏不是安全機制

v-if="isAdmin" 只是讓畫面乾淨,不是保護。任何人打開開發者工具都可以看到前端拿到了哪些資料。

判斷方式很簡單:如果把這個請求直接用 curl 打一次,會發生什麼事?如果答案是「會拿到資料」,那這個地方就沒有真的被保護。

環境也是權限的一部分

正式環境的金鑰不應該出現在開發環境,開發用的測試帳號也不應該出現在正式資料庫。這兩件事聽起來很基本,但在時間趕的時候特別容易被跳過。

比較實際的做法是一開始就把環境變數分好,讓「拿錯金鑰」這件事在流程上就做不到,而不是靠記得。

什麼時候處理

我們的習慣是在畫資料表的時候就一起決定:這張表有哪些角色會碰到、各自能做什麼。

這個階段做這件事幾乎不花時間,因為還沒有任何程式碼需要改。等到上線前一週才想,成本就完全不一樣了。