n8n 是一款強大的工作流自動化平台,允許使用者透過視覺化介面將不同服務串接在一起。為了讓使用者能靈活處理資料,n8n 提供了表達式(Expressions)功能,讓使用者可以在節點中寫簡單的 JavaScript 代碼來處理變數。
然而,讓使用者在伺服器端執行代碼是非常危險的。如果沒有限制,任何人都能直接呼叫 Node.js 的內建模組(例如 child_process)來操作底層作業系統。因此,n8n 實作了一個沙盒(Sandbox)機制,其核心邏輯是使用一個抽象語法樹(AST, Abstract Syntax Tree)重寫器。這個重寫器的作用是攔截使用者寫的 JavaScript 識別碼,將其導向 n8n 預設的資料上下文,而不是讓它直接訪問 Node.js 的全域執行環境。
這次被發現的漏洞(GHSA-gv7g-jm28-cr3m)本質上是一個沙盒逃逸(Sandbox Escape),意即攻擊者找到了繞過 AST 重寫器檢查的方法,重新取得了對 Node.js 全域物件的控制權。
漏洞觸發的技術細節
這次的逃逸路徑是由兩個獨立的漏洞共同構成的,單獨其中一個並不足以完成攻擊。
第一個漏洞出在箭頭函式(Arrow Function)的處理。在受影響的版本中,n8n 的重寫器將箭頭函式表達式放在了一個不執行任何操作(no-op)的分支中。這意味著如果使用者寫一個簡潔的箭頭函式,例如 () => process,重寫器會直接跳過它,導致 process 這個關鍵字被解析為 Node.js 真正的全域 process 物件,而非沙盒化的版本。
第二個漏洞則在於屬性檢查的盲點。n8n 會檢查成員表達式中的靜態屬性名稱,但研究人員發現 Reflect.get() 這個方法可以繞過檢查。因為 Reflect.get() 的屬性名稱是透過函式參數傳遞的,而非靜態寫死在代碼中,這使得攻擊者能利用它來獲取 process.getBuiltinModule,進而載入 child_process 模組。
當這兩個漏洞結合時,攻擊者就能在工作流中執行任意的作業系統指令,且權限等同於執行 n8n 程序的系統帳號。
實際影響與風險
這個漏洞的危險程度被評為高風險(CVSS 4.0 分數 8.7),主要影響在於以下三點。
首先是敏感資訊洩露。一旦能執行 OS 指令,攻擊者可以直接讀取環境變數,獲取 N8N_ENCRYPTION_KEY(n8n 加密金鑰)。有了這把金鑰,n8n 儲存的所有第三方服務憑據(Credentials)都能被解密。
其次是內網橫向移動。n8n 通常被部署在企業內網或雲端環境中,且與許多資料庫、內部 API 和雲端端點連接。攻擊者可以將 n8n 伺服器當作跳板,對內網其他服務發起攻擊。
最後是權限要求。此漏洞不需要受害者點擊任何連結,只要攻擊者擁有一個可以編輯工作流的帳號(即便權限不高),就能直接觸發。
修復建議與防禦措施
n8n 已在 2.31.5 與 2.32.1 版本中修復此問題。官方在更新後的重寫器中加入了專門針對箭頭函式的處理邏輯,確保簡潔箭頭函式中的識別碼也會被導向沙盒上下文。
對於工程師與管理員,建議採取以下行動。
第一,立即更新版本。不要依賴限制存取權限的暫時方案,因為官方已明確表示那些控制措施並不完整。
第二,審查可疑工作流。檢查近期建立或修改的工作流中,是否出現異常的箭頭函式或經過混淆處理的 JavaScript 代碼。
第三,監控系統行為。在伺服器端監控是否有異常的子程序被 n8n 或 Node.js 啟動,例如不正常的 shell、PowerShell、curl 或 wget 指令。
第四,輪換憑據。如果發現有疑似被利用的跡象,必須立即更換所有儲存在 n8n 中的 API Key 與密碼。
來源:thehackernews.com
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。