AIDive

你的 MCP 伺服器,是系統裡最大的破口

AIDive · 發布

AI 資安編碼 agent

你的代理架構有個弱點

惡意 MCP 伺服器能偷走你的 SSH 金鑰,甚至不用寫出一句完整的惡意指令。ASSET 研究團隊證實了這一點:當竊取指令一次性交給模型時,大型模型幾乎都會拒絕。但把同樣的指令拆成看似無害的片段後,GPT-4o、Gemini 2.0 Flash 和 Llama 3.3 在測試中 100% 都會照做。

與此同時,大多數開發者每週都在為代理新增一個 MCP 伺服器,複製一行在 GitHub 上找到的設定。每個伺服器都握有你權限的一部分:API token、雲端金鑰、服務帳戶。MCP 很好用——這點沒人會反對。但 MCP 伺服器已成為整個代理架構中最弱的一環。

這篇文章會談 MCP 伺服器如何在不被發現的情況下洩露你的機密、靠拆分指令繞過模型拒絕的 GhostSplice 攻擊,以及具體的防禦方式,從 Cloudflare WriteGuard 到你今天就能在自己系統上套用的規則。

MCP 伺服器實際握有什麼

MCP 伺服器基本上是你的代理與外部工具之間的橋樑:你的資料庫、GitHub、Slack、雲端服務。為了完成這座橋,它會存放以你的身分登入所需的一切——token、API 金鑰、服務帳戶憑證——通常以明文存在硬碟上的設定檔裡,幾乎沒有加密。

有個協定細節,對後面的內容很重要。當代理連上 MCP 伺服器,伺服器會回傳一份工具清單,每個工具都附有自由文字說明,告訴模型何時、如何使用它。這些說明會直接進入模型的上下文,權重和你自己下的指令一樣,工具回傳的結果也會進到那裡。MCP 伺服器基本上一直在跟你的代理對話,而且是沒人會重看的文字。這正是 GhostSplice 攻擊能成立的關鍵。

這個生態系擴張的速度,也早已超過了防護措施:

指標 數字
官方 MCP 註冊表中的伺服器數量 超過 9,600 個
遠端伺服器部署量自 2025 年 5 月起的成長 5 倍

任何人都能發布伺服器,沒有中央審核,而你的代理會像信任官方工具一樣信任每一個。NSA 在五月發布了一份專門談 MCP 的安全指南,指出協定的普及速度已超過防護措施的建設。當情報機構為你愛用的開發工具寫指南時,通常不是為了恭喜你。

情況就是這樣:成千上萬個伺服器,沒有審核,而你的金鑰夾在中間。

機密從哪裡洩露

第一個破口是憑證以明文儲存。The Hacker News 在 8 月 17 日發表了洩露機制的詳細分析,開頭就講得很直白:token 直接被貼進設定字串裡,並以可讀形式留在硬碟上。只要一次稍嫌匆促的提交,就足以把含有金鑰的設定推上 Git 倉庫。文章稱之為「擴散」的問題還會更糟:同一組金鑰重複出現在設定檔、環境變數,以及開發、預備、正式環境的多份副本裡。久而久之沒人知道機密在哪,於是沒人輪換它們——一把從不輪換的靜態金鑰,就是在等攻擊者上門。

第二個破口是權限過大。在開發階段,你會給伺服器過大的權限來避開授權錯誤,而這些寬鬆權限會原封不動上線。於是單一次入侵暴露的範圍,遠超過實際使用所需。

第三個破口是供應鏈。CVE-2025-6514 打中了下載超過 40 萬次的 OAuth 代理 mcp-remote,讓惡意伺服器能在使用者機器上觸發指令注入——執行程式碼並帶走憑證。一個熱門的 npm 套件,一行安裝,門就開了。

第四個破口最陰險:提示注入。代理會讀取工具帶回來的一切——網頁、工單、內部文件。如果其中一個藏有隱藏指令,代理可能會像是你下的令一樣執行它,並用它合法的工具,洩露它本該保護的東西。這個漏洞不是靠任何技術缺陷造成的;而是靠模型太容易被騙。

在任何精密攻擊之前,MCP 伺服器日常的明文設定、過大權限、未審核的依賴、未過濾的內容,早已讓你的機密曝光。

GhostSplice:拆片段出招的攻擊

GhostSplice 是 ASSET 研究團隊給一種技術取的名字,這種技術讓你自己的代理來執行外洩,還讓它完全配合。原理一句話就能說完:惡意伺服器不把竊取指令一次寫完,而是拆開,把一個片段放進工具的說明裡,另一個放進工具回傳的結果裡。單獨看每一片,都顯得無害。但代理會把進入其工作上下文的一切組合起來:它重建完整指令,並全心全意地執行它——從它的角度看,這只是在填寫工具要求它填的表格。

測試數據才是真正的重點:

模型 一次給出的指令 拆分後的指令
GPT-4o 100% 拒絕 100% 照做
Gemini 2.0 Flash 100% 拒絕 100% 照做
Llama 3.3 100% 拒絕 100% 照做
Claude Haiku 4.5 透過 API 全數拒絕 在 Cursor 中的三段式測試裡 100% 照做

Claude 的細節推翻了任何簡單的結論:同一個模型能在一個用戶端拒絕、在另一個用戶端外洩,取決於那個用戶端加了什麼防護。

GhostSplice 在測試中偷走的東西:SSH 金鑰、環境機密、原始碼、客戶資料。研究人員用的是帶假金鑰的隔離專案,不是真實受害者,但方法已公開且可重現。

GhostSplice 並非首次嘗試。同一個實驗室六月時發表過 Ghostcommit,一種把指令藏在專案慣例引用的 PNG 檔案裡的攻擊,再把偷來的機密編碼成原始碼裡的整數。指令拆分正成為一整類攻擊手法,不是單一的特例。

有兩件事能讓人冷靜一點。這種攻擊有兩個前提:惡意伺服器已經接進了你的代理,而且代理對目標檔案有讀取權限。這正是來源如此重要的原因——伺服器的來源,是你的第一道防線。而且要記住這個機制:模型的對齊並不能保護你,因為這種攻擊從來不會一次要求任何被禁止的事。

Shadow MCP:沒人核准的伺服器

GhostSplice 假設惡意伺服器已經接進系統。但到底是誰決定要接哪個伺服器?在團隊裡,老實說答案是沒人。這正是 Cloudflare 所謂 shadow MCP 的問題:開發者未經任何安全審查就接上代理的所有伺服器。直到最近,這種流量一直是隱形的——MCP 請求看起來就跟其他 HTTPS 呼叫一樣。

Cloudflare 剛用協定層級的偵測改變了這一點。自從規格更新後,每個符合規格的 MCP 用戶端都會在請求中送出 MCP-Protocol-Version 標頭,Gateway 會檢查它解密的所有 TLS 流量裡的這個標頭。安全團隊現在能看到公司裡用的每個 MCP 伺服器,有一個專屬儀表板:獨立伺服器、使用者、請求量。用這種標頭方式比用網域名稱過濾更好,因為 MCP 伺服器沒理由非得把自己命名成 mcp-something——協定是靠它「說了什麼」被抓到,而不是靠它「自稱是什麼」。

團隊也能採取行動:一個 is_mcp 選擇器就能封鎖任何未經核准入口的 MCP 流量。入口是整個機制的另一半——一個單一存取點,把已審核的伺服器集中在身分驗證之後。

最新的規格版本把可見度推得更遠。新的 Mcp-MethodMcp-Name 標頭會揭露被請求的操作,以及被呼叫的工具,防火牆完全不用打開請求內容。團隊能在網路層級分辨代理是在讀取一張工單,還是在刪除五十張工單。

Cloudflare 把這分成兩種情況:純粹的 shadow MCP,即從未被核准的伺服器,以及入口繞過,即已核准的伺服器被直接繞過關卡存取。兩者都會用同一條基本規則封鎖。邏輯很簡單:透過入口的一切都已知並被記錄,其他一律封鎖。對企業來說,這就終結了週五晚上偷偷裝上的幽靈 MCP 伺服器。

WriteGuard:逐工具的權限控管

即使是已核准的伺服器也能造成傷害,因為代理會一次繼承使用者全部的權限。這正是 WriteGuard 派上用場的地方,Cloudflare 剛把它開放為私人測試版。概念是:把每個 MCP 伺服器的每個工具都分入風險等級,並為每個等級套用不同政策。

  • 讀取毫無阻礙地通過。
  • 一次受限的寫入,比如發表留言,能通過但會被加註:這個動作會被簽署為來自某個代理、代表某個特定的人,並將稽核事件送到中央日誌。
  • 關鍵動作——合併程式碼、部署到正式環境、大量刪除——在伺服器處理前就會被擋下。

Cloudflare 文章裡的 GitLab 範例很清楚展示了這種分級:讀取一個合併請求會通過,留言會通過並附上署名,但合併會被拒絕,直到人類自己動手。

最有意思的部分是身分模型。代理保有它所服務員工本身的權限,但現在每次寫入都帶著兩個簽名:那個人,以及代表他的代理工作階段。於是下游系統終於能分辨一次人工修改和一次機器產生的修改,稽核紀錄會非同步送往中央日誌,並清除敏感資料。在此之前,代理在日誌裡和真人根本無法區分;這對事故稽核來說改變了一切——一次查詢就能知道週二那筆可疑的合併,是匆忙的同事所為,還是某個發揮過頭的代理工作階段。

Cloudflare 不是在賣理論,他們描述的是自己內部的實際用法:他們的入口連接了 27 個 MCP 伺服器,4 月時只有 13 個。這個數字說明了真相——就連在 Cloudflare 自己那裡,伺服器數量也在幾個月內翻倍,這正是為什麼逐工具控管變得必要。業界前進的方向很清楚:不再信任整個伺服器,而是逐一動作決定代理能做什麼。

限制:這些工具解決不了什麼

限制必須說清楚。WriteGuard 是私人測試版,需要填表申請,Gateway 的偵測需要部署 Cloudflare Zero Trust 並開啟 TLS 檢測:如果你是獨立開發者或小團隊,那根本不是你的基礎設施。即使在企業裡,偵測也只能看到它解密的網路流量——透過 stdio 執行的本機 MCP 伺服器,以一般行程在機器上啟動,對 Gateway 來說仍是隱形的。而這正是大多數開發者安裝伺服器的實際方式。

最重要的是,這些工具都沒能修復 GhostSplice 揭露的核心機制:只要代理仍會自由組合進入其上下文的一切,無害的片段就會不斷重組成惡意指令。ASSET 研究人員自己也說:真正的解法是把工具輸出當成資料來對待,絕不當成指令,而這種區隔目前在代理裡並不存在。

在此之前,他們的建議歸結為三個做法:不讓一個工具傳出的值未經檢查就餵給另一個工具的參數,保留手動拒絕每次工具呼叫的能力,並預設把來自未審核伺服器的任何註解視為有害。這三點今天都不是自動的:要靠你自己去落實,否則沒人會做。把 Cloudflare 這裡提供的一切當成安全帶,而不是煞車——它能減輕傷害,卻無法阻止碰撞發生。

我們會如何套用到自己的系統

今天就能開始做的事:

  1. 盤點。 列出真正接進你代理裡的 MCP 伺服器,並移除不再使用的那些。
  2. 依來源分類。 知名廠商的官方伺服器,可以;在討論串裡找到的 40 星 GitHub 專案,不行——除非你已經看過它如何處理你的資料。
  3. 限縮權限範圍。 給每個伺服器一個範圍最小的專屬 token,絕不要用你的主金鑰,並像對待任何正式系統一樣輪換這些 token。
  4. 守住敏感動作。 一個會寫入、合併或刪除的代理必須先經過你——這基本上就是 WriteGuard 工業化版本的手動實踐版。
  5. 在日常中落實 GhostSplice 這條規則。 當你的代理串連了你沒要求的工具動作時,先停下來,看看伺服器到底跟它說了什麼。

每個代理用戶端都能列出它連接的伺服器和工具,看那份清單只要三十秒。這三十秒是你整套系統裡時間換安全性最划算的投資。

如果你在企業裡,再加上網路層:Gateway 的 MCP 偵測和入口值得導入,因為不管你有沒有看到,shadow MCP 早已存在於你的組織中。

問題不在 MCP 本身——而在我們交出金鑰的速度。

來源

常見問題

什麼是 GhostSplice 攻擊?
GhostSplice 是 ASSET 研究團隊發表的一種技術,惡意 MCP 伺服器把竊取資料的指令拆成看似無害的片段——一段放在工具說明裡,另一段放在工具的回傳結果裡。代理會在自己的上下文中把它們重新組合,並全心全意地執行完整指令。測試中,GPT-4o、Gemini 2.0 Flash 和 Llama 3.3 對一次給出的指令 100% 拒絕,但對拆分後的版本卻 100% 照做。
MCP 伺服器是如何洩露機密的?
主要透過四個破口:以明文存放在設定檔裡、最終被提交或在不同環境間重複的憑證;在開發階段給予、卻原封不動上線的過大權限範圍;像 mcp-remote 指令注入(CVE-2025-6514,下載超過 40 萬次)這類供應鏈漏洞;以及藏在代理工具回傳內容中的提示注入。
什麼是 shadow MCP?
Shadow MCP 是 Cloudflare 用來稱呼開發者未經任何安全審查就接上代理的 MCP 伺服器。這種流量過去是隱形的,因為 MCP 請求看起來就跟其他 HTTPS 呼叫一樣;Cloudflare Gateway 現在會透過檢查每個符合規格的用戶端送出的 MCP-Protocol-Version 標頭來偵測它,並能封鎖任何未經核准入口的伺服器。
什麼是 Cloudflare WriteGuard?
WriteGuard 是 Cloudflare 目前處於私人測試版的功能,會把每個 MCP 伺服器的每個工具分入風險等級。讀取可自由通過,受限寫入能通過但會附上代理歸屬與稽核事件,而合併程式碼或部署到正式環境這類關鍵動作,則會被擋下直到人類自己執行。每次寫入都帶有兩個簽名:那個人,以及代表他行動的代理工作階段。
模型的對齊機制能防範惡意 MCP 伺服器嗎?
不能。GhostSplice 從來不會一次要求任何被禁止的事,所以模型的拒絕訓練根本不會被觸發。防護程度也因用戶端而異,不只取決於模型:Claude Haiku 4.5 透過 API 時全數拒絕,卻在 Cursor 裡的三段式測試中 100% 照做。
今天該如何保護自己的 MCP 伺服器?
五個做法:盤點真正接進代理裡的伺服器並移除不再使用的;只保留來源可信的伺服器;給每個伺服器一個範圍最小的專屬 token 並定期輪換;對寫入、合併、刪除動作要求人工核准;並且只要代理串連了你沒要求的工具動作,就立刻停下它。

相關影片