AI 驅動的網路攻擊:如何偵測、預防及抵禦智慧型威脅

立即閱讀
我們利用人工智慧進行網站翻譯,雖然我們力求準確性,但它們可能並不總是 100% 精確。感謝您的理解。

Mongoose CVE-2025-23061 和 CVE-2024-53900 的技術發現

by OPSWAT 發布
分享此文章

Mongoose 是用於 MongoDB 的物件資料建模 (ODM) 函式庫,可簡化 Node.js 應用程式中的資料庫互動。透過提供基於模式的解決方案,Mongoose 可將 JavaScript 物件映射至 MongoDB 檔案,作為抽象層幫助資料結構化,使管理和驗證更加容易。Mongoose 具備用於自訂邏輯執行的中介軟體和直覺式查詢建置系統等功能,可提升 MongoDB 的工作效率。Mongoose 被形容為「Node.js 的優雅 MongoDB 物件建模」,在 GitHub 上獲得了 27K 顆星星,反映出它在開發人員中的廣泛使用和讚賞。

OPSWAT 研究員計畫與關鍵弱點發現

OPSWAT 關鍵基礎設施網路安全研究生獎學金計畫以越南為基地,提供研究生保護關鍵基礎設施的實務經驗。作為該計畫的一部分,研究員有機會分析並處理網路安全漏洞,與OPSWAT 專家合作解決惡意軟體偵測、檔案安全和威脅預防等領域的實際挑戰。 

在OPSWAT Fellowship 計畫中,參與者有系統地調查和重現各種產品、程式庫和作業系統中已知的 CVE。作為這項計畫的一部分,我們其中一位傑出的研究員 Dat Phung 選擇研究 Mongoose,因為它在生產環境中被廣泛採用。2024 年 11 月,他在對 Mongoose 的函式庫進行深入分析時,發現了該函式庫中的一個重要漏洞。該漏洞允許攻擊者利用$where值,可能導致 Node.js 應用程式伺服器上的遠端程式碼執行 (RCE)。在及時向 Mongoose 報告此問題後,Mongoose 發布了修補程式作為版本 8.8.3 的一部分,並在國家漏洞資料庫(NVD)中披露了 CVE-2024-53900。

CVE-2024-53900 & CVE-2025-23061 時程表

  • 2024 年 11 月 7 日: Dat Phung 在 Mongoose 中發現了一個重要漏洞,並向 Snyk 提交了一份安全報告。 
  • 2024 年 11 月 26 日: Mongoose 發布 8.8.3 版,以處理及修復此漏洞。 
  • 2024 年 12 月 2 日: 國家漏洞資料庫(NVD)揭露此漏洞的 CVE-2024-53900。 
  • 2024 年 12 月 17 日:在分析 Mongoose 的 8.8.3 修補程式時,Dat Phung 發現了一個旁路,仍然可以啟用 RCE (遠端執行程式碼)。一份詳細的安全報告已提交給 Tidelift。 
  • 2025 年 1 月 13 日:Mongoose 發布 8.9.5 版,推出增強修補程式,有效解決繞道問題。 
  • 2025 年 1 月 15 日:國家漏洞資料庫(NVD)正式揭露 CVE-2025-23061,強調新發現漏洞的嚴重性。

Mongoose 的 Populate() 方法

Mongoose 還提供了一個叫做 populate() 的有用功能,它增強了處理檔案之間關係的能力。雖然 MongoDB ≥ 3.2 版本有 $lookup 彙集運算符用於連接,但 Mongoose 的 populate() 提供了更強大的替代功能,可將引用自動替換為相關檔案中的相應資料。這對於管理不同 MongoDB 集合之間的關係特別有用,例如當一個檔案透過 _id 來引用另一個檔案時。[2] 

為作者定義 Mongoose 模式的 JavaScript 程式碼,包含姓名、年齡和履歷欄位
作者模式
JavaScript 程式碼定義書籍的 Mongoose 模式,包括標題、描述、價格和作者參考資料
書籍模式
Node.js 路由的 JavaScript 程式碼片段,可擷取書籍詳細資訊並填入作者或評論欄位
Nodejs 應用程式

在 Mongoose 中定義模式時,可以使用 ref 選項設定欄位參考另一個模型。然後,populate()方法會用相關模型的完整檔案來取代被引用的欄位(ObjectId)。例如,在書店應用程式中,bookSchema中的 author 欄位會參考Author檔案,而review 欄位則會參考Reviews檔案。populate() 方法可讓開發人員在查詢書籍模型時,以完整的Author檔案取代author欄位(它是一個 ObjectId)。

populate() 允許開發人員在查詢書籍模型時,以完整的Author檔案取代author欄位 (這是一個 ObjectId):

MongoDB 文檔的 JSON 表示形式,其中儲存了書籍的詳細資訊,但未擴充作者資訊
不使用 populate()
使用 populate 函式擴充作者詳細資訊的 MongoDB 檔案 JSON 表示法
使用 populate()

此外,Mongoose 的 populate() 方法支援自訂查詢,以定義擷取哪些相關檔案以及擷取的方式。匹配選項等屬性允許開發人員過濾、排序、限制和跳過相關檔案,提供靈活的資料擷取功能。

JavaScript 程式碼示範使用 Mongoose 的 populate 函式,依年齡篩選作者的自訂查詢。
Mongoose 中 populate() 中的自訂查詢

CVE-2024-53900 分析

作為OPSWAT 網路安全研究生獎學金計畫的一部分,Dat Phung 在分析 Mongoose 以重現已知 CVE 的同時,對 populate() 方法的內部運作進行了全面的檢閱,該方法在處理 MongoDB 檔案之間的關係時扮演了關鍵的角色。populate() 方法支援字串和物件參數,開發人員可以使用 match 選項,對擷取的資料套用特定的篩選條件:

JavaScript 程式碼展示如何使用 $where 運算子在查詢中以年齡篩選作者

在上面的範例中,match 選項是一個可以包含 MongoDB 查詢運算符的過濾器物件,詳情請參閱Query and Projection Operators - MongoDB Manual v8.0。其中一個值得注意的操作符是$where,它可以讓 JavaScript 直接在 MongoDB 伺服器上執行。但是,這種在 MongoDB 伺服器上的執行是受限制的,僅支援基本的操作和函式。

列出可用於 MongoDB map-reduce 作業的 JavaScript 函式和屬性的表格

Dat Phung 對 Mongoose 原始程式碼進行了深入分析,以瞭解populate()方法的工作流程。他確定應用程式在模型上呼叫 populate()方法後,會觸發 populate() 函式。在此函式中,Mongoose 會呼叫 _execPopulateQuery() 函式,該函式會在 MongoDB 伺服器上以$where運算子執行查詢。隨後,所有來自外部集合的檔案都會被擷取,以便在接下來的步驟中進行填充。

分析 Mongoose populate 查詢執行的 VS Code 除錯會話截圖

從 MongoDB 擷取資料後,Mongoose 會執行回呼函式_done(),該函式會呼叫_assign()來準備資料,然後透過呼叫assignVals()函式「結合」兩個模型。

在 VS Code 中的除錯會話,顯示與 Mongoose 中 $where 查詢相關的高亮 JavaScript 程式碼

當 Mongoose 的assignVals() 函式處理擷取的資料時,可能會產生此漏洞。此函式會檢查匹配選項是否為陣列,若是,則會將每個運算符號傳給sift()函式。sift() 函數是從同名的外部函式庫匯入,在應用程式伺服器的本機處理這些查詢。本機處理會帶來安全風險,尤其是在處理使用者控制的輸入時。

顯示 JavaScript 函式內變數指定的 VS Code 除錯會話

為了進一步研究這一點,Dat Phung 修改了 match 選項中的值,以確保滿足條件,從而調用sift() 函數對資料流進行額外分析。

使用 $where 過濾條件的 Mongoose 查詢示範 JavaScript 程式碼片段

條件就緒後,$where運算符隨後被傳給sift()函式。

在 JavaScript 函式中顯示篩選值的 VS Code 除錯會話

sift 函式庫是一個輕量級的 JavaScript 工具程式,設計用來使用類似 MongoDB 的語法過濾和查詢資料集合,例如陣列或 JSON 物件。根據官方檔案,「Sift 是一個用於在 JavaScript 中使用 MongoDB 查詢的微小函式庫」。sift()函式會在應用程式伺服器上評估類似 MongoDB 的篩選操作,而非在資料庫伺服器上評估,因此在處理不受信任的輸入時,系統可能會曝露在重大的安全風險中。

使用 Sift.js 根據年齡條件篩選物件陣列的簡單 JavaScript 片段
Sift 程式碼範例

繼續分析之後,我們的研究員在 sift 函式庫的createDefaultQueryTester()函式中發現了一個問題。這個函式會將 match 陣列中的每個操作轉換成可執行的 JavaScript 函式,然後用來在本機過濾和處理 MongoDB 檔案資料。為了達到這個目的,createDefaultQueryTester()會呼叫createNamedOperation()函式,並傳入 match 陣列中的$where等操作作為參數。 

以查詢操作和函式執行為重點的 VS Code 除錯會議

對於匹配陣列中的每個操作,createNamedOperation 會檢查是否支援該操作,然後將其傳給對應的函式。

JavaScript 除錯會話顯示查詢運算符號如 $where、$eq 及 $exists

如果操作為$where,則會使用原始「params」值產生 JavaScript 函式,該函式來自 match 陣列中的$where運算符,且可由使用者控制。

當 CSP(內容安全政策)啟用時,高亮顯示的 JavaScript 擷取片段會顯示函式的執行情況

CVE-2024-53900:攻擊細節

雖然 MongoDB 透過$where操作限制 JavaScript 函式的執行,但如先前所分析的,sift()函式允許這些函式在沒有這些限制的情況下執行。這種缺乏輸入驗證及限制的情況會引發重大的安全漏洞,因為「params」值直接由使用者輸入所控制,因此可能會被利用,導致程式碼注入攻擊。為了更徹底地檢查這個問題,Dat Phung 建立了以下查詢:

一個 JavaScript 擷取片段,顯示使用 $where 條件的 Mongoose 查詢,其中可能有不安全的函式執行

起初,查詢無法執行另一個程序,導致以下錯誤:

由於未定義的全局參照,MongoDB 錯誤記錄顯示伺服器執行失敗

此錯誤表示 Mongoose 嘗試在將控制權傳遞給 sift() 函式之前,在 MongoDB 伺服器上執行$where操作。但是,由於 MongoDB 的$where子句對 JavaScript 函式有限制,因此發生錯誤,導致查詢無法執行。因此,Mongoose 會在到達sift() 函式之前停止處理。

為了繞過這個限制,我們的研究員利用了應用程式伺服器上的 "global "變數,而這個變數在 MongoDB 伺服器上並不存在。這種方法讓他繞過了 MongoDB 伺服器上的限制,並使查詢能夠到達sift()函式:

電腦螢幕上顯示「程式碼無法運作」的文字,突顯編碼過程中的問題

使用此值,當 Mongoose 在 MongoDB 上執行$where操作時,由於沒有 "global「 變數,三元運算符號(typeof global != 」undefined" ? global.process.mainModule.constructor._load("child_process").exec("calc") :1)返回 1,防止 MongoDB 拋出錯誤。因此,查詢可以在 MongoDB 伺服器上順利執行。

但是,當相同的值到達在應用程式伺服器上執行的 sift()函式(該函式在 "global "變數可用的地方執行)時,會觸發以下函式的建立:

以粗體字顯示「hello world」的單色螢幕

遠端執行程式碼 (RCE) 概念驗證

在文章開頭提供的應用程式範例中,如果攻擊者傳送以下要求,他們就可以成功執行遠端執行程式碼 (RCE) 攻擊:

黑白螢幕上以粗體字顯眼地顯示「the new york times」字樣
說明 Mongoose CVE 漏洞技術細節的圖表,顯示資料流程和安全漏洞點

該視訊示範了 CVE-2024-53900 的概念驗證,此 CVE-2024-53900 會影響 8.8.3 之前的 Mongoose 版本,該版本缺乏適當的輸入驗證以防止與sift函式庫一起濫用$where運算符。

不完整修復與 CVE-2025-23061

根據 Dat Phung 的安全報告,Mongoose 在公開揭露之前,已推出修補程式,以解決先前發現的漏洞 (CVE-2024-53900)。相關修補程式(Automattic/mongoose@33679bc) 新增檢查,禁止在傳給populate() 的 match 屬性中使用$where

此片段檢查傳入 populate() 的 match 屬性是否為陣列。如果是,程式碼會遍歷陣列中的每個物件,看看它是否包含 $where運算符號。如果偵測到$where,就會產生錯誤,以防止惡意的 payload 傳播到有風險的 sift() 函式。  

因此,利用 CVE-2024-53900 的有效負載無法通過此檢查,因為匹配陣列中的物件包含$where,因此有效地阻止它到達sift()

雖然這個更新正確地阻止了$where在單一嵌套層級內的直接使用,但卻無法偵測到嵌入在 $or運算符內的$where - 這是 MongoDB 和 sift 函式庫都完全支援的結構。

MongoDB 支援 $or 運算符號
Sift 函式庫支援 $or 運算符號

因此,攻擊者可以將$where嵌套在$or 之下,以逃避修補程式的單層檢查。由於 Mongoose 只會檢查匹配陣列中每個物件的頂層屬性,因此繞過的有效負載仍未被偵測到,並最終到達 sift 函式庫,使惡意 RCE 得以實現。

用於繞過 mongoose 8.8.3 修正的有效載荷

CVE-2025-23061 的概念驗證

為了說明修正的不完整性,Dat Phung 使用 Mongoose 8.9.4 (比 8.8.3 遲) 版本重建範例應用程式。透過將$where嵌套在 $or子句內,攻擊者可成功繞過檢查並達成 RCE。

此概念驗證漏洞利用示範了如何在 8.9.5 之前的 Mongoose 版本中觸發 CVE-2025-23061,允許攻擊者在伺服器上執行任意程式碼:

緩解與指導

為了減緩我們上面討論的漏洞,請確保您的系統已更新至最新版本的 Mongoose。

使用 SBOM 引擎的MetaDefender Core 可偵測此漏洞

OPSWAT MetaDefender CoreMetaDefender Core 配備先進的SBOM軟體物料清單)功能,可讓組織採取主動的方式來處理安全風險。透過掃描軟體應用程式及其相依性,MetaDefender Core 可辨識列出元件中的已知漏洞,例如 CVE-2024-53900 和 CVE-2025-23061。這有助於開發和安全團隊優先進行修補工作,在惡意行為者利用這些漏洞之前減輕潛在的安全風險。 

以下是MetaDefender Core 使用 SBOM 檢測到的 CVE-2024-53900 和 CVE-2025-23061 的截圖:

此外,CVE 也可以透過 MetaDefender Software Supply Chain,利用MetaDefender Core 與 SBOM 識別這些漏洞。

隨時瞭解OPSWAT 的最新資訊!

立即註冊,即可收到公司的最新消息、 故事、活動資訊等。