一行 curl 就能搬走你整台電腦的祕密:Vitest UI 路徑遍歷漏洞(CVE-2026-47429)全解析

作者: Calpa Liu
字數:2285
出版:2026 年 10 月 30 日
分類:前端開發
#Vitest#Security#Path Traversal
CVSS 9.8 滿級分:測試框架 Vitest 的 UI 伺服器被發現路徑遍歷漏洞,攻擊者一行 curl 就能讀走專案外的任何檔案,甚至執行任意程式碼。誰會中鏢、怎麼防、該升級到哪裡,這篇一次說完。

最近整理部落格依賴的時候,Dependabot 的一條告警讓我停了下來。

不是常見的「某套件有個小問題」那種提示,而是一行加粗的描述:「當 Vitest UI server 正在監聽時,任意檔案可以被讀取與執行。」編號 CVE-2026-47429,CVSS 9.8,滿級分。

花了些時間研究它,發現這可能是 2026 年前端工具鏈最值得關注的安全事件之一。這篇文章把攻擊怎麼做、為什麼可行、誰會中鏢、該怎麼防,一次講完。

兩行 curl,搬走整台電腦的祕密

先看結論。這個漏洞的攻擊只需要兩行指令。

第一步,向受害開發者電腦上正在運行的 Vitest UI 伺服器要一把 API token:

curl http://localhost:51204/__vitest__/

第二步,拿著這把 token,用一個精心構造的路徑,把專案目錄之外的檔案「附帶」出來:

curl "http://localhost:51204/__vitest_attachment__?path=C:\path\to\project\?\..\..\secret.txt&contentType=text/plain&token=$TOKEN"

回應的內容,就是 secret.txt 的全文。而這個檔案,位於專案目錄之外。

secret.txt 可以是任何東西:.env 檔裡的資料庫連線字串與第三方服務金鑰、SSH 私鑰、瀏覽器儲存的登入憑證匯出、公司內部文件。對開發者來說,專案目錄之外的世界,往往藏著比專案本身更值錢的東西。

為什麼「讀檔」會升級成「執行程式」

如果故事停在讀檔,這會是一個中規中矩的路徑遍歷漏洞。但官方公告的標題寫的是「可以被讀取與執行」。

拆開 Vitest 的 API 會發現,這個測試框架的伺服器本身內建了兩個強大的功能:把內容存成測試檔案(saveTestFile),以及重新執行測試(rerun)。

把兩個功能串起來,攻擊路徑就完成了:先利用檔案寫入,把一段惡意腳本存成 .test.ts 測試檔;再呼叫 rerun,讓 Vitest 把它當成正規測試執行。從這一刻起,攻擊者在你的電腦上擁有了一個程式碼執行環境。

官方公告的結論寫得很直白:把 Vitest UI 或它的 API 暴露到網路上,等同於直接交出腳本執行權。

洞從哪裡來

漏洞的本體藏在 Vitest 原始碼的一個函式呼叫裡。

Vitest 在服務檔案之前,會呼叫 isFileServingAllowed 來判斷「這個路徑是否允許被讀取」。問題是,這個函式已經被標記為棄用,而且它的使用方式有個致命細節:檢查邏輯假設你會先用 cleanUrl() 把路徑清理乾淨再做判斷,但這段程式碼直接把未清理的路徑丟了進去。

在 Windows 上,路徑支援一種以 \\?\ 開頭的長路徑語法。攻擊者把這個前綴與 ..\ 遍歷組合之後,有缺陷的檢查就整個失效了。官方統計,同樣的檢查缺陷在原始碼中至少散布在六個位置:API 初始化、附件端點、瀏覽器模式的檔案讀寫與快照儲存。

還有一層防護的失效加劇了問題。API token 本該是一道鎖,但這把鎖的鑰匙就掛在同一扇門上:token 可以從同一個伺服器的另一個端點取得。信任邊界沒有分隔,等於大門敞開。

誰會中鏢

官方公告給出的影響條件非常精確,只有兩種人:

第一,明確把 Vitest UI 伺服器暴露到網路的人。使用 --api.host 參數或設定檔中的 api.host 選項,讓伺服器綁定到非本機位址。CVSS 的評分中,攻擊向量是「網路」、攻擊複雜度「低」、不需要任何權限、也不需要受害者互動。換句話說,伺服器一旦對網路開放,攻擊就是一行指令的事。

第二,在 Windows 上執行 Vitest UI 或瀏覽器模式的人。\\?\ 的路徑遍歷是 Windows 專屬的繞過手法,Linux 系統因為不存在名為 ? 的目錄而直接報錯。這意味著大量的 Windows 開發者,即使完全沒有對外開放任何連接埠,也處於檔案讀取的風險面。

這個分布對企業環境是個警訊:Windows 恰好是大多數企業開發機的作業系統。

CVSS 9.8 攻擊向量拆解:網路向量、低複雜度、無需權限與互動,機密性完整性可用性全數最高衝擊
CVSS 9.8 攻擊向量拆解:網路向量、低複雜度、無需權限與互動,機密性完整性可用性全數最高衝擊

修復方式與新版內建的保險絲

根本解是升級。這個漏洞在 Vitest 3.2.6 修復,低於此版本都在風險範圍:

npm install -D vitest@latest

值得稱許的是,修復版本的 Vitest 也加入了兩條新的設定旗標:allowWrite 與 allowExec。它們直接對應這次漏洞的兩段攻擊路徑:寫入測試檔案、執行測試。當伺服器綁定到非本機位址時,這兩個旗標預設關閉,遠端客戶端不再隱式取得寫檔與執行的能力,UI 也會進入唯讀模式。

需要完整互動功能的開發者,必須主動把旗標打開。這種「預設最小權限」的設計,正是這類開發工具漏洞該有的修法。

除了升級,還有幾個習慣可以降低暴露面:沒有遠端查看需求就不要加 --host;真的需要時用 SSH 通道代替直接開放連接埠;CI 環境一律用 headless 模式,不啟動 UI;開發機的 5100 到 5200 連接埠範圍預設拒絕外部連線。

防護四層:升級修復版、不加 host、SSH 通道取代暴露、防火牆擋 5100-5200
防護四層:升級修復版、不加 host、SSH 通道取代暴露、防火牆擋 5100-5200

本站的實際處理

最近整理依賴的過程中,我把本站的測試框架從 Vitest 3.2.7 大版本升級到了 4.1.12。

升級的動機一開始是另一個問題:Vitest 3 鎖定的 tinypool 依賴有兩條 critical 告警,而修復版卡在 Vitest 3 拿不到的版本範圍。升級到 Vitest 4 之後,tinypool 從依賴樹中整個消失,那兩條告警直接斷根。

事後回頭核對安全公告才發現,這次升級順帶把 CVE-2026-47429 也免疫了:Vitest 4 不在受影響範圍內。67 個測試全數通過、設定檔零改動、12 秒跑完。升級的成本,遠低於評估「我們會不會中鏢」的成本。

這也是這類依賴升級最值得投資的地方:當修復版本已經存在,升級的收益是確定的,拖延的成本才是未知數。

不只一個:Vitest 的漏洞家族

整理資料的過程中才發現,CVE-2026-47429 並不是孤例。Vitest 的開發伺服器攻擊面在 2026 年被研究者連續挖出了四個漏洞,組成了一個家族。

Vitest 漏洞家族四卡:47429 UI 路徑遍歷 RCE、84373 mocker 遍歷、112950 反斜線解析、47428 Browser Mode
Vitest 漏洞家族四卡:47429 UI 路徑遍歷 RCE、84373 mocker 遍歷、112950 反斜線解析、47428 Browser Mode

CVE攻擊面修復版本Vitest 4.1.12
CVE-2026-47429UI 伺服器路徑遍歷與程式碼執行3.2.6免疫
CVE-2026-84373瀏覽器模式與 mocker 路徑遍歷4.1.11免疫
CVE-2026-112950反斜線路徑解析差異近期版免疫
CVE-2026-47428瀏覽器模式的釣魚 URL行為防護需使用者留意

四個漏洞的共通點一模一樣:開發伺服器把使用者的輸入當作檔案系統路徑,而路徑解析在各平台上又各有眉角。這不是 Vitest 團隊不專業,開發伺服器的攻擊面是前端工具鏈的結構性挑戰,Vite 本身在 2023 年也修過同類的檔案服務遍歷問題。

寫在最後

一天之內,路徑處理以兩種完全不同的面貌出現在我面前:一次是攻擊者手中的武器,一行 curl 讀走專案外的檔案;一次是平台手中防禦過度的規則,檔名含雙點就拒絕服務。

路徑處理是資訊安全最古老的主題之一。從目錄遍歷到 dev server,十幾年過去,它的本質從來沒有變過:任何把使用者輸入當作檔案系統路徑的程式碼,都必須假設有人會試著跳出去。

如果你的團隊還停在 Vitest 3.2.5 或更早,這個週末就是升級的好時機。

常見問題(FAQ)

我只用 Vitest 跑單元測試,也受影響嗎?

不受影響。這個漏洞只存在於 UI 模式啟動的 HTTP 伺服器。vitest run 是純 headless 執行,不開任何連接埠。

我沒有加 host 參數,真的安全嗎?

Mac 與 Linux 使用者若未暴露伺服器,檔案讀取的繞過手法無法觸發。但重執行與寫檔的攻擊鏈與作業系統無關,只要伺服器暴露就有風險。防護建議對三個平台一視同仁:升級、不暴露。

Vitest 4 也受影響嗎?

CVE-2026-47429 的受影響範圍是 Vitest 3.2.6 之前的版本,Vitest 4 不在範圍內。本站升級到 4.1.12 後,Dependabot 的這條告警已自動關閉。

怎麼確認我的專案有沒有中鏢?

兩個檢查:一,package.json 或 lock 檔裡的 vitest 版本是否低於 3.2.6;二,檢查 git 歷史與 CI 日誌有沒有 UI 模式搭配 host 參數的使用痕跡。兩者同時成立才構成實際暴露。

延伸閱讀

關於 Calpa

Calpa 擅長使用 TypeScript、React.js 和 Vue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章