跳至主要內容
>_ITDITD網站資安平台

資安指南

只加了登入就以為安全了嗎 — 身分驗證與授權的差別

身分驗證(你是誰)與授權(你可以做什麼)是兩回事。只加了登入卻沒有依擁有者篩選資料,就會變成「登入=看到全部資料」。本文說明為何發生與如何防禦。

發布於 2026-06-30 更新於 2026-07-03 閱讀時間 2 分鐘

「我加了登入,所以現在有保護了」——這是個危險的假設。登入(身分驗證)和權限(授權)是不同的東西,把兩者搞混就會釀成一場事故:凡是登入的人都能看到全部資料,包含別人的。 這裡不寫任何攻擊步驟——只講它是怎麼發生的,以及如何防禦。

身分驗證與授權是不同的東西

它們很容易被混為一談,但角色完全不同。

只有身分驗證(常見的誤解)

  • 以為「能登入=安全」
  • 把登入後的資料讀取當成對所有人都一樣
  • 結果:凡是登入的人都能抵達全部資料

身分驗證+授權(應有的樣子)

  • 由身分驗證確認「你是誰」
  • 由授權限縮到「只有這個人可以碰的資料」
  • 資料讀取永遠依擁有者做範圍限制

身分驗證是「入口的身分核對」;授權是「控制可以進入哪些房間」。登入只保證前者。「誰可以碰哪些資料」是你必須另外寫的東西。

authn
在入口確認「你是誰」(登入)
authz
逐個房間控制「誰可以進來」(依擁有者篩選)
no authz
進得了門=每個房間都能進=凡是登入的人都能看到全部資料
身分驗證只在門口核對身分。少了各房間的鑰匙(授權),只要進得了門的人就能進入每一個房間。

「看到全部資料」在真實應用中是怎麼發生的

在現場,同一個漏洞在彼此獨立、各自自建的系統上一再出現。個人的待辦/筆記應用,或是小型的商品・訂單管理系統(帶有外部 API 整合)——起因都是相同的兩個缺陷的重疊。

1

① 註冊是開放的(而且分佈在兩條路由上)

驗證腳手架(像是 Laravel 的 Breeze/Jetstream 那類)往往預設就把註冊頁公開。而當註冊路由在 UI 函式庫和驗證套件兩邊重複時,關掉其中一條,/register 仍然留著。知道網址的陌生人就能註冊。

2

② 有身分驗證但沒有授權(缺少擁有者範圍限制)

資料表沒有擁有者欄位(user_id),或列表/讀取/更新/刪除的查詢沒有限縮到目前使用者。於是「登入=存取全部資料」。若應用在註冊後隨即自動登入,陌生人一註冊就會落在別人的資料列表上。

3

結果:authn ≠ authz 的事故

入口(登入)有了,但房間的鑰匙(授權)沒有。因為陌生人的行為就像「一個正常登入的使用者」,未授權存取幾乎不留下任何痕跡。

牽涉的業務資料越多,波及範圍就越大(客戶記錄、訂單、整合用的 API 金鑰都可能受影響)。而且用相同方式自建的另一個系統,很可能也有同一個漏洞。

如何防禦

1

永遠把資料依擁有者做範圍限制

把每一次讀取與寫入都限縮到「登入使用者自己的那幾筆」。透過 ORM 的全域 scope 或授權策略(policy/gate),在讀取/更新/刪除全部強制加上擁有者條件。如果資料表沒有擁有者欄位,先從那裡重新設計。

2

關閉你不需要的註冊——並懷疑路由有重複

在個人/內部應用上停用註冊。實際用 HTTP 量測 /register 之類的路徑是否回傳 404,並同時檢查 UI 函式庫和驗證套件兩邊的註冊路由。

3

在管理介面做多層防禦

內部/管理用途不要只靠身分驗證——疊上 IP 限制、Basic 驗證之類的手段。一道牆被攻破,還有下一道能擋下。

4

在事故發生*之前*備好稽核與存取記錄

沒有「誰、在何時、從哪個 IP、做了什麼」,事後就無法還原「有哪些東西被看過」。至少要保留登入成功/失敗的稽核記錄,並保存與輪替 Web 存取記錄。

5

偵測新的註冊與異常

這次的核心教訓是「很長一段時間都沒被察覺」。加上能快速察覺的辦法——新使用者註冊時發通知、定期盤點使用者/資料。沒有偵測,漏洞就會靜靜地一直開著。

本站的觀點:函式庫只保證「你是誰」

驗證函式庫替你處理的只到「你是誰」——就到此為止。「這個人可以做什麼」除非身為設計者的你去寫,否則並不存在。而且——在一個系統中發現的結構性缺陷,很可能也存在於用相同方式打造的其他系統中。不要修好一個就收工;請橫向盤點所有同型的建置。當你無法判斷某樣東西是否被讀取過時,正確的姿態是把它當成已被讀取,並將任何外洩的機密失效/輪替掉。

接下來閱讀

出處

FAQ

Q身分驗證與授權有什麼不同?
A

身分驗證是確認「你是誰」(登入)。授權是決定「這個人可以做什麼」(權限)。打個比方,身分驗證是在大樓入口做的身分核對;授權則是控制這個人可以進入哪些房間。只加了登入,做到的僅是身分驗證——授權(誰可以碰哪些資料)是你必須另外寫的東西。把這兩者混為一談,就會落得「凡是登入的人都能看到全部資料」。

Q明明有登入,為什麼所有人都能看到全部資料?
A

因為取資料的查詢沒有限縮到「只有目前登入使用者自己的那幾筆」。只要在列表/讀取/更新/刪除的任何一處忘了加上擁有者(user_id)條件,一旦有人登入,全部資料列就都會回傳——包含別人的。這是與有沒有身分驗證無關的設計漏洞,正是 OWASP 排名第一的經典 Broken Access Control(存取控制缺陷)。

Q如果是個人工具或內部應用,把註冊開著不是沒關係嗎?
A

很危險。許多驗證腳手架預設就把註冊(例如 /register)公開出去。陌生人只要知道網址就能註冊,若沒有授權,就會直接走到裡面的資料上。而且註冊路由有時會重複(UI 函式庫和驗證套件各有一條),關掉其中一條並不代表關掉全部。停用你不需要的註冊,並在管理介面上疊加 IP 限制之類的防禦。