開發人員喜愛「捆綁式」API。它們提供原子性和效率,讓您能夠將複雜的狀態變更鏈結到單一網路請求中。然而,安全工程師應該對此感到憂慮。捆綁會引入複雜性,而複雜性正是錯誤潛藏之處。

作為 depthfirst 研究的一部分,我最近在 Temporal 的 ExecuteMultiOperation 端點(CVE-2025-14986)中發現了一個漏洞。這是一個身份綁定錯誤:外部請求通過了一個命名空間的授權,但內部操作卻攜帶了一個伺服器在請求準備期間使用的不同命名空間。

對於不熟悉 Temporal 的人來說,Temporal 是 Netflix、Stripe 和 Datadog 等公司可靠執行的後盾。它確保程式碼即使在伺服器故障時也能可靠運行。當您在 Temporal 中發現錯誤時,它會影響到大型公司所依賴的可靠性層。

該漏洞存在於 ExecuteMultiOperation 中,這是一個設計用於在單一交易中執行 StartWorkflow 和 UpdateWorkflow 命令的處理器。

當請求命中此端點時,Temporal 會正確地對外部命名空間執行授權檢查。如果我以 AttackerNS 的身份通過驗證,系統會檢查我的權限,解析我的 namespaceID,然後打開閘門。

到目前為止,一切順利。守衛檢查了我的身份,並且我被允許進入。

問題出在系統解開捆綁時。ExecuteMultiOperation 請求包含一個操作列表。這些內部操作攜帶它們自己的元數據,包括一個 Namespace 欄位。

在輔助函數 convertToHistoryMultiOperationItem 中,邏輯出現了分歧。程式碼對於「這個使用者是誰?」有兩個不同的真相來源:

該漏洞在請求準備(策略/別名/模式)所使用的身份與路由和持久化所使用的身份之間存在差異:

此漏洞造成了「混淆代理人」的場景。我們可以通過一個命名空間進行授權,同時影響另一個命名空間的策略/模式評估。

以下是利用 JSON 請求的結構:

我發現了兩種利用這種不匹配的方法:

在多租戶 SaaS 中,租戶 A 永遠不應該能夠與租戶 B 的配置進行互動。

2. 「自帶策略」攻擊

在許多組織中,生產和開發環境都受到嚴格策略的保護——執行超時、重試限制和封存設定。惡意開發人員無法覆蓋組織管理員設定的這些 Temporal 策略。

但通過這個漏洞,他們可以。開發人員可以針對 Corporate Org 有效地進行身份驗證,但指向他們個人帳戶的策略配置。

遮罩命名空間之所以奏效,是因為伺服器在外部驗證了遮罩,然後信任了捆綁內部的身份。

此漏洞之所以存在,是因為系統在單一請求中接受了兩個不同的命名空間身份。授權僅對外部命名空間執行一次,但請求準備隨後在衍生策略和模式時信任內部命名空間。隨著 v1.27 版本的發布,Temporal 強制執行一個簡單的不變式:內部操作引用的命名空間必須與外部授權的命名空間相匹配。

修復引入了一個檢查,以確保在任何處理發生之前 Outer.ID == Inner.ID: