觀點 · 資訊分享

Fastify 兩個代理外掛同日公布三個漏洞:編碼過的網址,就能繞過「只開放某些路徑」的設定

Fastify 的 @fastify/http-proxy 與 @fastify/reply-from 在 7 月 18 日公布三個安全公告,其中一個 CVSS 10.0。攻擊者可能碰到本來藏在代理後面的內部路徑,建議升到 11.6.0 與 12.6.4。

發布
2026-07-19
篇幅
約 6 分鐘 · 2,532 字
結構
7 節 + 3 題常見問題
標籤
#Fastify#npm 安全#反向代理#CVE-2026-16117#Node.js
Fastify 兩個代理外掛同日公布三個漏洞:編碼過的網址,就能繞過「只開放某些路徑」的設定

一句話看懂:Fastify 的兩個反向代理外掛在 7 月 18 日一次公布三個安全漏洞,最嚴重的 CVSS 10.0:用編碼過的網址,就可能躲過「只開放某些路徑」的設定,碰到本來藏在代理後面的內部路徑。建議升到 @fastify/http-proxy 11.6.0 與 @fastify/reply-from 12.6.4。

Fastify 代理外掛三個漏洞資訊圖卡:編碼過的網址能繞過前綴設定,碰到本想藏起來的內部路徑

先用白話講:反向代理的「前綴」是什麼?

想像一棟大樓的接待櫃台:訪客只能說「我要去 3 樓的 A 公司」,櫃台再幫他轉接到對應的辦公室,而 B 公司、機房、老闆辦公室不對外。

反向代理就是這位接待員:網站對外只開一個入口,例如 /api/...,收到請求後,代理依規則轉給後端的服務。其中的 prefix(前綴) 是對外看到的路徑,rewritePrefix 則是轉給後端時改寫成的路徑。這次的問題是:有些寫法能讓接待員「看錯路牌」,把訪客帶到不該去的地方。

發生什麼事

Fastify 在 2026-07-18 於 GitHub 公布三個安全公告:

套件 CVE 問題 嚴重度 修正版本
@fastify/http-proxy CVE-2026-16117 路徑用百分比編碼時,前綴改寫失效 10.0(Critical) 11.6.0
@fastify/http-proxy CVE-2026-15631 WebSocket 的路徑穿越,能跳出前綴 8.7(High) 11.6.0
@fastify/reply-from CVE-2026-16158 網址快取鍵撞號,請求被送到別的後端 8.7(High) 12.6.4

CVE-2026-15631 與 CVE-2026-16158 的 GitHub 評分是 8.7,NVD 另外給了 10.0,差別在 NVD 把攻擊複雜度算成「低」、GitHub 公告算成「高」,這裡以 GitHub 公告為主。

三個漏洞各是怎麼回事?

1. 編碼過的路徑(CVE-2026-16117)
Fastify 的路由器會先把網址解碼再比對,所以 /%61pi/data(%61 就是字母 a)會被當成 /api/data 而命中路由;但代理做前綴改寫時,用的卻是「字面比對」,看不懂編碼過的版本,於是跳過改寫,原封不動把 /%61pi/data 丟給後端。後端再解碼,就走到了本來該被藏起來的路徑。依後端的不同,可能造成路徑限制被繞過、SSRF(讓伺服器去連不該連的地方)或授權被繞過。受影響版本是 11.5.0 以下。

2. WebSocket 路徑穿越(CVE-2026-15631)
WebSocket 的轉送路徑是用標準網址函式解析的,會把 ../ 這類片段折疊掉,所以特製的升級請求能跳出前綴、碰到不該公開的後端端點。受影響版本是 9.4.0 到 11.5.0。這是 2021 年一個舊漏洞(CVE-2021-21322)的變體。官方說明要實際利用需要「不會先正規化路徑」的 WebSocket 客戶端,瀏覽器和 ws 套件會先正規化,但原始的 HTTP 客戶端,或原封不動轉送路徑的上游代理,就可能讓它在實際環境成立。

3. 快取鍵撞號(CVE-2026-16158)
reply-from 把「目的地」與「來源路徑」直接串在一起當快取鍵,中間沒有分隔符號。官方舉例:http://127.0.0.1:31001 加 /private,跟 http://127.0.0.1:3100 加 1/private,串起來是同一個字串。快取一旦被其中一組填入,另一組的請求就會被悄悄送到錯的後端。這是預設設定就會碰到的問題,影響版本是 8.3.1 以上、12.6.4 以前;用 getUpstream() 在不同安全等級的後端之間做選擇的程式風險最高。

給開發者的技術細節

先確認專案用到的版本:

npm ls @fastify/http-proxy @fastify/reply-from

升級:

npm install @fastify/http-proxy@^11.6.0 @fastify/reply-from@^12.6.4
  • http-proxy 兩個漏洞官方都說沒有臨時解法,只能升到 11.6.0 以上
  • reply-from:暫時無法升級的話,註冊外掛時加上 disableCache: true 可以避開,代價是每個請求多一次網址解析
  • 官方文章提到的例子是 prefix: '/api'、rewritePrefix: '/safe' 這類設定:只要你依賴 rewritePrefix 來隔離後端路徑,就屬於「會被影響」的設計
  • 更根本的做法:後端服務自己也要做授權檢查,不要只靠前面的代理擋路徑

我的看法

接案時常見的架構是:前面放一個閘道,把 /api、/admin、/files 分別轉給不同後端。很多團隊的心態是「內部路徑反正外面進不來」,所以後端的管理端點就不再另外驗證。這次的漏洞正好打在這個假設上:代理一旦被繞過,後端就是裸的。

升級是第一步;第二步是順便檢查後端,管理端點有沒有自己的身分驗證。如果只靠代理的路徑規則擋人,下一個類似的漏洞還是會出事。

名詞小辭典

  • 反向代理(Reverse proxy):站在後端服務前面的接待員,統一接收請求,再轉給後面的服務。
  • 百分比編碼(Percent-encoding):把特殊字元寫成 % 加兩位數字,例如 %61 代表字母 a,網址裡常見。
  • 路徑穿越(Path traversal):用 ../ 這類片段往上跳,跳出原本應該限制的資料夾或路徑。
  • SSRF:讓伺服器代替攻擊者去連線它本來不該連的內部位址。

資料來源

常見問題

@fastify/http-proxy 是做什麼的?
Fastify 的反向代理外掛,把進來的請求轉送到後端服務,常用來把多個後端整合到同一個對外入口,並可用 prefix 與 rewritePrefix 控制對外與對內的路徑。
我該怎麼知道自己有沒有用到?
在專案裡查看這兩個套件的版本,例如用 npm ls 或 pnpm why。只要 @fastify/http-proxy 在 11.5.0 以下,或 @fastify/reply-from 在 12.6.3 以下,就需要升級。
沒辦法立刻升級怎麼辦?
官方說 http-proxy 的兩個問題沒有臨時解法,要升級。reply-from 的問題可以在註冊外掛時設 disableCache: true,代價是每個請求都要多解析一次網址。
LINE