Laravel 與後端開發

補丁八週前就到了,公告現在才來:Laravel token guard 嚴重認證繞過,你的 API 還開著門嗎?

Laravel News 的 Paul Redmond 於 2026/10/20 報導,Laravel 公布嚴重等級安全公告 GHSA-f9x3-7vq9-cph6(CVSS 9.2):使用內建 token 驅動的 API guard(Illuminate\Auth\TokenGuard)時,在 MySQL/MariaDB 上,未經驗證的攻擊者可送出特製的非字串憑證,讓查詢比對到非預期的使用者紀錄,進而冒用既有帳號。修補方式是在 user() 與 validate() 加上 is_string() 檢查,已收錄於 2026/8/25 發布的 Laravel 12.68.0 與 13.29.0;Sanctum 與 Passport 不在公告範圍內。同日另有中度公告 GHSA-5wcm-3v2w-8362(CVSS 6.5),影響 12.45 起加入的 JSON:API resources,唯讀請求可能觸發刪除關聯資料表的操作,修補於 12.68.0 與 13.27.0。本文整理受影響條件、檢查步驟與給企業與工作室的實務建議。

Pixar 風格 3D 插圖:圓滾滾的保全機器人在發光的大門前,狐疑地看著小浣熊遞來一堆彩色果凍方塊,後方藍色大象吉祥物高舉一把新的金色掛鎖。
補丁八週前就到了,公告現在才來:Laravel token guard 嚴重認證繞過,你的 API 還開著門嗎?

Laravel 公布 CVSS 9.2 的 TokenGuard 認證繞過漏洞:在 MySQL/MariaDB 上,未登入的攻擊者只要送出特製的「非字串」憑證,就可能直接被當成某位既有使用者。修補早在 8 月 25 日的 12.68.0 與 13.29.0 就已出貨,同一天還公布了一個讓唯讀請求能清空關聯資料表的 JSON:API 問題。給 Laravel 專案負責人與委外客戶的檢查清單。

想像一棟大樓的門禁:保全要你出示門禁卡,你遞過去一張,他看一眼「嗯,有東西,不是空的」,就放你進去,還順手幫你按了某位住戶家的樓層。

這不是冷笑話,這大概就是這次 Laravel token guard 漏洞的白話版。

10 月 20 日,Laravel News 的 Paul Redmond 報導了 Laravel 官方的嚴重等級安全公告:使用內建 token 驅動的 API guard,在 MySQL 或 MariaDB 上,未登入的攻擊者可以在不知道對方 API token 的情況下,以某位既有使用者的身分通過驗證。CVSS 分數 9.2,滿分是 10。

好消息是:修補程式早就在那裡了。壞消息是:如果你的專案從 8 月底到現在都沒更新過框架,那扇門可能一直開著。

發生了什麼事?

問題出在 Illuminate\Auth\TokenGuard,也就是 config/auth.php 裡 guard 設定為 'driver' => 'token' 時背後負責驗證的類別。設定大概長這樣:

'guards' => [
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
],

官方公告的描述是:在特定資料庫設定(MySQL/MariaDB)下,攻擊者可以送出特製的、非字串型態的憑證值,這個值在驗證查詢時被錯誤處理,讓資料庫比對到一筆非預期的使用者紀錄,而不是像預期那樣驗證失敗。

結果就是:任何受這個 guard 保護的路由,帳號都可能被接管。

GitHub 上的公告(GHSA-f9x3-7vq9-cph6)列出的 CVSS 4.0 向量也很直白:透過網路攻擊、攻擊複雜度低、不需要任何權限、不需要使用者互動,機密性、完整性、可用性的影響都是「高」。唯一的「條件」是攻擊需求標為 Present,也就是你得剛好用了這個 guard、剛好跑在 MySQL/MariaDB 上。

漏洞由 Hristijan Manasijev 回報,他在 X 上的說法很有畫面:「我在 Laravel 找到一個嚴重的認證繞過(9.2/10)……在 MySQL/MariaDB 上,Laravel 的 token API guard 讓未經驗證的攻擊者能以既有受害使用者的身分登入。」

怎麼修的?一行 is_string()

修補前,guard 只檢查從請求拿到的 token「不是空的」,就交給 user provider 去資料庫查。修補後,在 user() 和 validate() 兩個方法都多了型態檢查:

if (is_string($token) && ! empty($token)) {

也就是說,陣列或其他非字串的值,在碰到資料庫之前就會被擋下來。

這是一個很經典的教訓:「不是空的」不等於「是對的」。PHP 的請求參數不一定是字串,可能是陣列,而資料庫對不同型態的比較行為,有時會出乎意料。保全不只要確認你手上有卡,還要確認那是一張卡。

另一個同日公布的問題:唯讀請求竟能刪資料

Manasijev 同一天還回報了第二個問題,GHSA-5wcm-3v2w-8362,CVSS v3.1 分數 6.5(中度)。它影響的是 Laravel 12.45 加入的 JSON:API resources。

公告原文的意思是:在特定條件下,對唯讀端點發出的請求,可以被設計成在關聯資料表上觸發破壞性的資料庫操作,而不只是讀取資料。換句話說,一個只有讀取權限的使用者,可能把某張關聯資料表清空。修法是調整 JSON:API resources 載入請求所要求 include 的關聯方式。

受影響版本一覽

公告 嚴重度 受影響 已修補
Token guard 認證繞過 嚴重(9.2) 低於 12.68.0、低於 13.29.0 12.68.0、13.29.0
JSON:API 資料破壞 中度(6.5) 12.45.0 至 12.68.0 之前、低於 13.27.0 12.68.0、13.27.0

有個細節值得注意:Laravel 12.68.0 和 13.29.0 都是 2026 年 8 月 25 日發布的。所以從那之後有更新過框架的專案,兩個修補其實早就裝好了。另外,認證繞過公告把 12.68.0 以下的所有版本都列為受影響,但修補只出在 12.x 和 13.x 兩條分支。如果你的專案還跑在 Laravel 11 或更舊,就沒有官方小版本可以補,只能升級大版本,或確認自己根本沒用 token 驅動。

為什麼這件事值得你停下來五分鐘?

第一,token guard 常出現在「老專案」和「小 API」。 很多團隊新專案會用 Sanctum 或 Passport(這兩者註冊自己的 guard 驅動,不在這份公告範圍內),但幾年前做的後台、給 App 用的簡易 API、或某個外包商留下的內部系統,很可能還在用最原始的 api_token 欄位加 token 驅動。這種系統通常沒人天天看,也最容易「上線後就沒再更新」。

第二,MySQL/MariaDB 在台灣非常普遍。 一般主機商、雲端代管、各種一鍵架站環境,預設幾乎都是 MySQL 或 MariaDB。條件看似很窄,實際上命中率可能不低。

第三,「不需要權限、不需要互動」是最危險的組合。 攻擊者不用騙任何人點連結,也不需要先有帳號。對會員系統、電商、預約平台來說,帳號被接管就代表個資、訂單、點數都可能外洩或被濫用。

實戰檢查清單:今天就能做

  1. 先看版本。 在專案根目錄執行 composer show laravel/framework,確認版本是否已達 12.68.0 或 13.29.0 以上。
  2. 再找 token 驅動。 打開 config/auth.php,搜尋 'driver' => 'token'。如果有,而且資料庫是 MySQL 或 MariaDB,這個專案就是今天的第一優先。
  3. 更新框架。 執行 composer update laravel/framework,跑過測試後部署。12.x 與 13.x 都是小版本更新,一般不會有破壞性變更,但仍建議先在測試環境驗證。
  4. 跑一次 composer audit。 讓 Composer 把已安裝套件和公開的安全公告比對一遍,順便抓出其他過期的依賴。
  5. 檢查 JSON:API 端點。 如果你在 12.45 之後用過 JSON:API resources,確認版本已達 12.68.0 或 13.27.0 以上。
  6. 回頭看日誌。 官方沒有公布是否有實際攻擊案例,但如果你的 API 長期沒更新,可以檢查一下 API 路由有沒有異常的參數格式、或某個帳號突然出現陌生來源的存取紀錄。
  7. 考慮換掉 token 驅動。 長期來看,Sanctum 提供可撤銷、可設定權限範圍的 token,管理起來比單一 api_token 欄位安全得多。這不是緊急修補,而是值得排進下一季的技術債清理。

給委外客戶的話:怎麼問你的開發商

如果你是委託工作室或外包團隊做系統的企業主,不需要自己看程式碼,但可以問三個問題:

  • 「我們的 Laravel 版本是多少?有沒有更新到 12.68.0/13.29.0 以上?」
  • 「我們的 API 是用 Sanctum、Passport,還是內建 token 驅動?」
  • 「我們多久更新一次框架和套件?有沒有固定的維護排程?」

第三題最關鍵。這次的修補在公告前八週就出貨了,有固定更新節奏的專案,在漏洞公開那天就已經是安全的。沒有維護合約、一年才想起來更新一次的專案,才是真正暴露在風險裡的那群。

情境演練:一家電商的小故事

假設某間保養品電商,五年前請廠商做了會員系統和給 App 用的 API,當時用的就是 token 驅動,資料庫是 MariaDB。官網後來改版過,但 API 那台機器「能動就別碰」,Laravel 一直停在 12 的某個舊版本。

在這次公告之前,它看起來一切正常;公告之後,它就成了一個「條件全中」的目標:token 驅動、MariaDB、未修補、對外開放。這時候最好的做法不是恐慌,而是照上面清單:確認版本、更新到 12.68.0 以上、跑測試、部署,再排時間把 API 遷移到 Sanctum。整個緊急處理,順利的話一個下午就能完成。

你可能會問

Q:我們用的是 Sanctum,需要擔心嗎? A:根據 Laravel News 的整理,公告只涵蓋 token 驅動,Sanctum 和 Passport 註冊的是自己的 guard 驅動,不在公告列表中。不過框架本身還是建議更新,因為同一批版本也修了 JSON:API 的問題。

Q:我們的資料庫是 PostgreSQL,是不是就沒事? A:公告明確寫的是 MySQL/MariaDB 的資料庫設定。即使如此,更新框架的成本很低,沒有理由拖著不做。

Q:漏洞有 CVE 編號嗎? A:目前在 GitHub 公告頁上看到的是 GHSA 編號(GHSA-f9x3-7vq9-cph6 與 GHSA-5wcm-3v2w-8362),撰文時公告頁未列出 CVE。依賴 CVE 掃描的工具可能不會提醒你,建議直接用 composer audit 或看 laravel/framework 的安全公告頁。

Q:Laravel 11 或更舊的專案怎麼辦? A:公告列出的修補只在 12.x 與 13.x。舊版本若用了 token 驅動,實際的選擇是升級到有支援的大版本,或改用其他認證方式。

結語:門禁卡要檢查,維護節奏更要固定

這次事件最有意思的地方,不是漏洞本身有多巧妙,而是時間差:修補八週前就到了,公告現在才來。對有固定更新習慣的團隊來說,這只是一則「喔,原來我們早就補了」的新聞;對沒有維護節奏的系統來說,它是一記警鐘。

資安從來不是一次性的工程,而是一種習慣。今天花五分鐘查版本,比明天花五天處理帳號被盜要划算太多了。


來源:Critical Token Guard Auth Bypass Fixed in Laravel 13.29 and 12.68(Paul Redmond,Laravel News,2026/10/20)。

延伸參考:Token-based API guard Auth Bypass · GHSA-f9x3-7vq9-cph6(laravel/framework,GitHub,2026/10/19)。

← 返回技術文章