Velocity Curve
預約通話
← 回到案例總表
SECSEC-02  ·  資安

留在公開可讀程式碼裡的金鑰,仍打開了 321 套 n8n 設定,因為把金鑰從現行檔案裡拿掉,並不等於把它關掉

暴露範圍
4,576 把 n8n 設定的金鑰,可在 GitHub 上公開發佈的程式碼中讀到,指向 1,255 套獨立的設定 · 可連上的 896 套設定中有 321 套接受了至少一把已公開的金鑰,約為可連上設定的 36%,以及程式碼中被指名的所有設定的約 26% · 129 套可從網際網路連上的設定,其對外提供的識別值與早已出現在公開程式碼裡的弱主金鑰相符 · 所找到的 31,793 套設定中,有 4,398 套正在對外提供由其主金鑰推算出來的識別值,占所觀察設定的 13.8%
損失——未確認
損失未被確立。沒有人能說這些金鑰是否曾被研究團隊以外的人使用,也沒有人能說那些設定背後的系統存放了什麼、又能觸及什麼。
判定

研究人員到公開的 GitHub commit 裡尋找能打開 n8n 自動化設定的金鑰,找到數千把,指向 1,255 套不同的設定。有些設定暴露了不只一把金鑰,因此研究人員把屬於同一套設定的所有金鑰收齊後逐一試用。當時這些設定中有 896 套仍然上線、可供測試。其中 321 套,至少有一把公開可讀的金鑰仍然有效。

事件經過

n8n 是一套自動化工具,許多企業自行架在自己的伺服器上。它會保存所連接的其他系統的登入資料,而每一套設定內部都有一把主金鑰,能解開全部這些登入資料。專門尋找誤上傳金鑰的 GitGuardian,研究了一個人從一把外洩金鑰出發,能走到多遠。

團隊搜尋了發佈在 GitHub 上的程式碼,包含歷史紀錄中保留的舊版本,找到 4,576 把 n8n 設定的金鑰。這些金鑰指向 1,255 套獨立的設定。其中部分設定暴露了不只一把金鑰,因此團隊把屬於每一套設定的每一把金鑰都收齊後試用。在測試當時可連上的 896 套設定中,321 套接受了至少一把已公開的金鑰。這約為可連上設定的 36%,以及程式碼中被指名的所有設定的約 26%。可連上的設定中有 575 套不接受任何一把被試用的金鑰。

在另一項統計中,團隊使用一項全網搜尋服務,找出 31,793 套 n8n 設定。其中 4,398 套正在對外提供一個由主金鑰推算出來的識別值,占所觀察設定的 13.8%。這些之中有 129 套,其對外提供的值與早已出現在公開程式碼裡的弱主金鑰相符。團隊也回報了 n8n 產生用來簽署登入的密鑰時所存在的弱點,且到研究進行時,n8n 已被記錄 48 項安全缺陷。

團隊進一步重現了一種透過 n8n 的 Git 功能進行的攻擊,把一把屬於權限足夠高的帳號的金鑰,變成對主金鑰與加密後登入紀錄的存取權。研究之外是否有人把這些路徑用在運作中的設定上,未知;是否有任何人保存的登入資料被解開,未知。

研究進行期間,GitGuardian 曾多次直接向 n8n 揭露。n8n 確認收到回報,表示已知悉這些問題並計畫處理,後來將它們結案。n8n 在版本 1.123.10 與 2.5.0 修正了 Git 功能的缺陷。團隊自行的檢查發現,自版本 2.25.6 起,該識別值不再以同樣形式對外提供。GitGuardian 發佈時,尚未獨立確認涵蓋金鑰處理相關發現的所有變更都已釋出。

本研究進行時n8n 自 2026 年 1 月以來已收到 48 個 CVE;其中數個讓攻擊者能逃出 workflow 執行環境,在主機上取得程式碼執行或檔案系統存取權。
n8n v2.25.6 之前對 GET /rest/settings 的未經身分驗證請求可能回傳 public instance ID,該值由同一把 encryption key 推導而來,提供了第二種獨立方式來確認候選金鑰。
自 v2.25.6 起依研究人員的驗證,該 public instance ID 行為已不再以同樣形式存在。
研究期間研究人員在 n8n 推導簽署與 session 密鑰的方式中找到三項弱點,並示範了如何從公開的產物離線還原出過弱的 encryption key。
研究期間研究人員使用 CVE-2026-25053 重現了一種攻擊,使一把關聯到權限足夠高的帳號的 API key,能被提權為對 encryption key 與加密憑證紀錄的存取權。
測試當時有 129 個可從網際網路存取的實例,其公開產物仍與先前在 GitHub 上曝光的已知弱 encryption key 樣式相符。
測試當時在可連上的 896 個實例中,321 個接受了至少一把在公開 GitHub commit 中找到的曝光 token。
研究期間GitGuardian 多次直接向 n8n 揭露。
揭露之後n8n 確認收到回報,表示已知悉這些問題並計畫處理,隨後將回報結案。
版本 1.123.10 與 2.5.0n8n 修正了 CVE-2026-25053,即該項嚴重的 Git node 漏洞。
發佈當時GitGuardian 尚未獨立確認與密碼學相關發現的所有變更都已釋出。

主要來源——S1:https://blog.gitguardian.com/n8n-security-encryption-key-compromise存檔快照

損失成因

  • 寫在程式碼裡被公開的金鑰,在從現行檔案中被拿掉之後仍然有效,因為它只有在有人作廢那一把金鑰時才失效。 程式碼的舊版本會一直留在公開的程式碼託管平台上可被讀取,而這類金鑰本身不帶到期日。因此一把金鑰從公開的那一刻起就一直可用,直到有人刻意將它作廢;而當一套設定有好幾把金鑰流落在外,作廢被注意到的那一把,其餘的仍然可用。技術名稱:版本歷史中的長效密鑰(long-lived secret in version history)
  • 每一把被公開的金鑰都帶著建立它的那個帳號的全部權限,因此讀到金鑰的人就繼承了全部權限。 這類金鑰通常是由負責接線的人建立的,而他們持有最高層級的帳號,所以單一把金鑰能觸及的範圍遠超過它原本被建立的那一項工作。持有它的人可以讀取每一個自動化流程、列出已保存的登入資料,並在伺服器上啟動新的自動化流程。技術名稱:權限過寬的憑證(overscoped credential)
  • 由一套設定的主金鑰推算出來的值,被交給了完全不必證明身分的請求。 因為那個值不必登入就會被交出,對主金鑰的猜測可以在不再碰觸該設定的情況下拿去比對驗證。研究團隊把 129 套可連上的設定,比對到早已存在於公開程式碼中的弱主金鑰。技術名稱:未經身分驗證的存取(unauthenticated access)

判讀

不小心公開的金鑰,不會因為承載它的程式碼往前推進而失效;它只有在有人把那一把金鑰作廢時才失效。當同一套設定有好幾把金鑰能打開,作廢你注意到的那一把,其餘的仍然活著,而任何人都能查出哪些設定還連得上。

自我查核

只有你能回答的

  • 你先前是否以為把金鑰從現行程式碼中移除就等於讓它失效?曾經有任何人告訴過你,它會一直有效,直到在自動化工具本身把它作廢為止嗎?
  • 你是否假設你的自動化設定只有一把金鑰、且只有你持有?你今天能說出其他每一把是誰要求的、為什麼要嗎?
  • 如果現在有一把能打開你自動化設定的金鑰正被陌生人讀到,它會觸及你哪些其他帳號、客戶資料與供應商?這樣的觸及範圍是你願意承擔的嗎?

你的 AI 可以幫你查的

僅回報,不要變更任何程式碼或設定。每一項回答都要為每個發現附上檔案或主控台的參照位置,若有無法判定之處,請明白說出。

  1. 搜尋本專案所擁有的每一個 repository 的完整歷史,包含所有 branch、tag、已刪除的檔案,以及匯出的 workflow JSON,尋找 n8n API key 與 n8n encryption key 的值。回報每一筆命中並附上檔案或主控台的參照位置,包含在目前 checkout 中已不存在的命中,並就每一筆說明同一個值是否仍出現在任何運作中的設定裡。
  2. 列出目前註冊在此實例上的每一把 n8n API key,包含其所屬者與建立來源,並回報哪些金鑰仍被接受。接著回報:在檔案被 commit 或分享之前,是否有自動化的密鑰掃描(secret scanning)跑過此 repository 的歷史與匯出的 workflow JSON,以及它是否對每一次變更都執行;請附上檔案或主控台的參照位置。
  3. 針對每一把使用中的 n8n API key,回報它所屬的帳號以及該帳號的角色與權限,並明確指出哪些金鑰能列出已保存的憑證物件、讀取完整的 workflow 定義、檢視執行資料,或建立並啟用 workflow。回報任何由 owner 或管理員帳號簽發的金鑰;請附上檔案或主控台的參照位置。
  4. 回報此 n8n 實例是否可從公開網際網路連上、對其 settings 路徑的未經身分驗證請求是否會回傳 public instance ID,以及它運行的版本與 2.25.6 相比為何。另請回報 public API 及其 Swagger playground 是否已停用,以及是否設定了一組獨立隨機產生的使用者管理簽署密鑰,而非讓驗證用的資料依賴 encryption key;請附上檔案或主控台的參照位置。

預防方式

要作廢的是金鑰本身,不只是它的副本

任何曾經被公開、貼出或匯出的金鑰,都當成仍然有效,直到你在 n8n 裡面把它作廢為止。從檔案、聊天訊息或匯出檔中刪掉它,完全不影響它是否還能打開你的設定。為這套設定曾發出的每一把金鑰保留一份書面清單,記下是誰要求的、用途是什麼,這樣清理才是照著清單一條條處理,而不是只處理那一把浮上來的金鑰。

每個自動化流程用自己的金鑰,絕不交出擁有者帳號

要求每個自動化流程都有各自的金鑰,由一個只能做該流程所需事項的帳號建立,並拒絕用那個擁有一切的帳號來連接工具。當有人替你設定新的連接時,把「你用的是哪個帳號,它能做什麼?」列入你以書面接受的交付內容。

假設你的設定會告訴陌生人的任何東西,都可能被用來驗證對主金鑰的猜測

請當初安裝這套設定的人以書面確認:它有哪些部分會在沒有登入的情況下回應陌生人;並把任何好記的主金鑰(例如你的公司名或專案名)換成一個長的隨機值,而且這個值不同時用來簽署登入。在你拿到書面說明之前,把這套設定移出公開網際網路,放在私有網路或一份嚴格的允許位址清單後面,並把連上它的系統數量維持在最少。

一把金鑰是在有人作廢它時才不再危險,而不是在它從畫面上滾出視線時。