How did postmark-mcp silently exfiltrate 3,000-15,000 emails a day for 15 versions?
A trusted MCP server added one BCC line in a version bump and quietly copied thousands of emails daily; signature scanning never saw it because the malicious version had a clean history.
postmark-mcp 這個 MCP server 在被發現之前,已經連續 15 個發佈版本、每天 BCC 轉發估計 3,000 至 15,000 封 email。攻擊只有一行行為:一個受信任、早已安裝好的 MCP server,開始在外寄郵件裡偷偷加上一個隱藏的 BCC 收件人。沒有崩潰,沒有錯誤跳出。agent 完全照指令繼續寄信,而每一封信的靜默副本都被送到了別的地方。這不是什麼新穎的 exploit。它只是一次版本更新,把一個乾淨的工具變成了外洩通道,而它剛好對應到 OWASP Agentic Top 10 裡的兩個類別。
它能撐過 15 個版本,正是整件事的教訓所在:特徵碼與防毒掃描看著一個檔案問「這是已知的壞東西嗎?」。一個乾淨了好幾個月、然後才在更新裡加上 BCC 的受信任 MCP server,在你安裝的當下永遠不是已知的壞東西。惡意版本繼承了乾淨版本累積下來的全部信任。你需要看的是這個工具對 email 做了什麼,而不是它的檔案雜湊值有沒有被標記過。
postmark-mcp 事件到底發生了什麼?
postmark-mcp 是一個包裝 Postmark 交易型 email API 的 MCP server,讓 AI agent 能夠寄信。它大部分的生命週期裡就只做這件事,而且做得乾乾淨淨。然後某個版本加入了透過 BCC 把外寄郵件複製到攻擊者控制位址的邏輯。因為 BCC 對寄件者與可見收件者都是隱形的,所以無論是 agent 的操作者,還是收到信的人,都沒有任何訊號能察覺有第三方在這條 thread 上。
每天 3,000 至 15,000 封的量級估計,正是讓這件事從一個奇聞變成供應鏈事件的關鍵。一個負責寄交易型 email 的 MCP server,坐在密碼重設、發票、收據、登入連結、內部通知的正上方。這裡面每一項對攻擊者都是高價值目標。外洩持續了 15 個版本,代表它有足夠時間,在被抓到之前,變成那些安裝它的 agent 裡承重的基礎設施。
為什麼這是 ASI04 供應鏈與 ASI03 身分濫用模式?
OWASP Agentic Top 10 裡有兩個類別精準描述了這件事。ASI04 Agentic Supply Chain Vulnerabilities 是入口:你信任了一個相依套件,這個相依套件變了,而這次改動帶有敵意。信任關係是由早期的乾淨版本建立起來的,然後被後來的某個版本靜默利用。這正是供應鏈入侵的典型形狀,而單靠鎖定版本救不了你,因為人們升級就是為了拿到修補。
ASI03 Identity and Privilege Abuse 是 payload。這個 server 本來就握有代替 agent 寄信的正當權限。它不需要提權,也不需要突破邊界。它濫用的是被交到手上的身分與權限。那一行 BCC 是騎在操作者自願授予的憑證上運作的。當惡意動作重用的是你早已授予的權限時,就沒有任何權限邊界被跨越,也就沒有東西能讓傳統資安控制觸發。
| 屬性 | postmark-mcp 事件 |
|---|
|---|---|
| 攻擊面 | 受信任、早已安裝的 MCP server |
|---|
| 手法 | 外寄 email 上的隱藏 BCC |
|---|
| 量級 | 每天 3,000 至 15,000 封 |
|---|
| 未被發現時長 | 15 個發佈版本 |
|---|
| OWASP Agentic 對應 | ASI04 供應鏈、ASI03 身分濫用 |
|---|
為什麼特徵碼與防毒永遠抓不到「先乾淨後下毒」的版本更新?
特徵碼工具只回答一個問題:這個成品符不符合黑名單上的某個東西?一個剛被下毒的 MCP 版本什麼都不符合,因為它是新的,而且它的血緣是乾淨的。防毒的信譽系統在這裡反而幫倒忙。這個套件因為好幾個月誠實發佈而擁有好信譽,於是被下毒的版本繼承了那個信譽分數。那段本該讓你對行為改動提高警覺的歷史,反而成了讓掃描器放行它的理由。
postmark-mcp 不是唯一暴露這個盲區的案例。MCPJam Inspector 出廠時預設綁定 0.0.0.0(CVE-2026-23744),使得在 v1.4.3 之前的每一個版本,一個 HTTP 請求就能達成遠端程式碼執行。Azure MCP Server 有一個 SSRF(CVE-2026-26118),會竊取 managed-identity token 並把它變成對 Azure 資源的存取。Claude Code 本身的 hooks 與 MCP 設定曾被濫用來執行任意 shell 與竊取 API key(CVE-2025-59536 與 CVE-2026-21852)。在這每一個案例裡,危險的都是工具「有能力做出的行為」,而不是檔案裡的某個位元組樣式。以雜湊為基礎的掃描器根本沒有東西可以比對。
行為層級的掃描如何在安裝前就標記出外洩?
解法是掃「這個 server 做了什麼」,而不是掃它叫什麼名字、雜湊值是多少。ATR(Agent Threat Rules)是一套獨立、開放、MIT 授權的偵測標準,它把「外寄 email 被複製到呼叫者未指定的位址」當成一個可描述、可偵測的行為。機制是 threat crystallization:AI 理解一次某個攻擊模式後,把它寫成一條確定性規則,這條規則接著以毫秒等級為所有人執行。一個新攻擊大約一小時內就變成一條規則,每一個安裝都能拿到這個檢查,不必等特徵碼廠商。
ATR 是標準;PanGuard 是建立在它之上、並負責營運它的免費 MIT 授權工具。這個關係就像 Sigma 或 CVE 之於營運它的那一方。在你安裝一個 skill 或 MCP server 之前,先跑 pga scan <target>,它會拿工具宣告的與可觀察的行為去比對規則庫。Guard 接著在 runtime 做同一件事,所以就算是安裝後才加上隱藏 BCC 的版本更新,也會在它動作的當下被抓到。
這個規則庫是真實而且可量測的。ATR 提供將近 690 條規則(截至 2026 年 7 月,npm agent-threat-rules v3.5.6),涵蓋 10 個類別,共 866 條規則對類別的映射,覆蓋全部 10 個 OWASP Agentic Top 10 類別。在它的 Layer 1 確定性規則上,498 筆真實世界樣本的 SKILL.md 語料測得 100% recall、97% precision、0.2% 的誤報率。這些是該特定語料上的 Layer 1 數字,不是單一混合的全引擎數值;而且誤報行為是分 lane 的:對 65,000 筆 benign gate 而言,enforce lane 約 0.24%、預設的 hunt lane 約 9%。請如實說明,而不是引用單一的 precision 數字。
安裝下一個 MCP server 之前,你該做什麼?
假設每一個 MCP server 都是一個會在你腳下改變的供應鏈相依套件,因為 postmark-mcp 證明了它會。鎖定版本,但別把鎖版當成防護,因為你升級的理由本來就是要拿修補。在安裝前掃行為、在 runtime 監控行為,因為「先乾淨後下毒」的版本更新,對以檔案雜湊為基礎的工具而言,本質上就是隱形的。安裝指令是 npm install -g @panguard-ai/panguard && pga up,然後在你把寄信憑證交給一個新 server 之前,先跑 pga scan <target>。
FAQ
postmark-mcp 一開始就是惡意的嗎?
不是。它大部分發佈生命週期裡都是乾淨的,然後某次版本更新才加上隱藏的 BCC。正是那段乾淨歷史,讓被下毒的版本繼承了信任、躲過了以信譽為基礎的掃描器。
為什麼防毒抓不到?
防毒是拿成品去比對已知的壞特徵碼,而一個血緣乾淨、剛被下毒的版本什麼都比對不到。它因早期誠實發佈而來的好信譽,反而幫了攻擊者。
這對應到哪些 OWASP Agentic Top 10 類別?
ASI04 Agentic Supply Chain Vulnerabilities(受信任的相依套件在更新裡變得有敵意)與 ASI03 Identity and Privilege Abuse(server 濫用了被正當授予的寄信權限)。
ATR 把一個新攻擊變成檢查有多快?
大約一小時。AI 理解一次攻擊後,把它 crystallize 成一條確定性規則,這條規則接著以毫秒等級為每一個安裝執行。
在下一個你即將安裝的 MCP server 或 skill 拿到你的憑證之前,先對它跑 pga scan <target>。如果你想讀支撐這個檢查的那些規則,ATR 標準是開放且 MIT 授權的。