iT邦幫忙

0

下載 dataset 的那一刻,你其實已經在執行第三方程式

  • 分享至 

  • xImage
  •  

檔名叫 dataset,不代表進到系統裡的只有資料。

很多 AI 團隊的資料流程看起來很單純:下載檔案、解壓縮、套用 template、做前處理,最後寫進內部儲存空間。因為這條流程被歸類成 ETL,負責執行的 worker 往往拿得到物件儲存、套件 registry、雲端帳號,甚至 Kubernetes 叢集的憑證。

問題就在這裡。只要其中有 loader、template engine、preprocessor、converter 或套件安裝 hook 能執行程式,這就不是單純的資料搬運。它是一條第三方程式執行管線,只是大家沒有用這個名字看它。

Hugging Face 在 2026 年 7 月揭露的資安事件,把這個落差攤得很清楚。攻擊者透過惡意 dataset,利用 remote-code dataset loader 與 dataset 設定裡的 template injection,在 processing worker 上執行程式。後續才是取得更高權限、收集雲端與叢集憑證,再橫向移動到其他內部叢集。

團隊真正該追的是:攻擊一開始為什麼能從「處理資料」一路走到「拿走基礎設施身分」?

先盤點哪幾步其實會跑程式

做 threat model 時,我會先把「dataset」這個籠統名詞拿掉,直接攤開 ingestion pipeline:

外部來源
  -> loader
  -> template / config 解析
  -> 解壓縮與格式轉換
  -> preprocessor
  -> schema / content validation
  -> artifact promotion
  -> 可信任儲存區

接著對每一步問四個問題:

  1. 這段程式是誰提供的?
  2. 它跑在哪一個 worker?
  3. 它可以讀到哪些檔案與身分?
  4. 它可以連到哪些網路目的地?

如果答案是「第三方提供的 loader,跑在共用 worker,可以讀取環境變數,也可以任意連外」,那條邊界其實已經很明確。此時再討論 dataset 本身是不是 Parquet、JSONL 或圖片,只是在看容器,沒有看真正會動的部分。

也不是每個 dataset 都會執行程式。危險的是 ingestion 過程裡那些帶有執行能力、會載入外部模組或解譯 template 的元件。名稱看起來像資料處理,不會讓它們自動變安全。

Ingestion worker 應該是用完即丟的隔離區

一個 generic preprocessing worker 不該同時是內部基礎設施的通行證。

我會從 disposable worker 開始:每個 ingestion job 使用唯讀 base image,只掛載這次工作需要的目錄,不提供 host socket,也不給 cluster-admin identity。Job 結束後,worker 和暫存空間一起丟棄。

這些設定各自切斷不同的路。唯讀 image 降低攻擊者留下持久修改的空間;窄化 mount 避免它順手讀到其他 dataset 或主機檔案;拿掉 host socket,則是不讓容器裡的程式直接接管容器執行環境。

「有 sandbox」不是完成條件。團隊要能說出 sandbox 具體隔離了檔案系統、process、網路還是身分,以及哪些例外仍然存在。否則 sandbox 很容易只剩架構圖上的一個方框。

網路預設不通,例外才需要理由

資料處理 worker 常被允許任意連外,理由通常是它要下載來源檔案或套件。這個方便,也同時提供了下載第二階段 payload、連回控制端和把憑證送出去的路徑。

更穩妥的做法是預設 deny egress,再依 job 開放特定目的地。例如只允許連到指定 dataset host 與內部 artifact store,而且把 DNS、IP、port 和協定限制清楚。若流程需要安裝套件,應該優先走內部鏡像或事先建好的 image,而不是讓 runtime 自由存取整個網際網路。

GitHub 最近把 Copilot code review 放在預設防火牆後面,並把 review agent 與 cloud coding agent 的 runner 設定拆開。這個設計值得參考的地方,是不同工作不再共用同一個寬鬆執行環境。不過 self-hosted review runner 並不會自動拿到 GitHub 的 managed firewall。控制是否真的存在,還是得回頭看 job 最後跑在哪裡。

把憑證藏起來,沒有縮小它的權限

只要 worker 裡的程式能讀到憑證,攻擊者拿到執行權後就會去找。把 secret 換一個環境變數名稱,或把它藏進另一個設定檔,沒有改變這件事。

應該改的是憑證的權限、範圍與壽命。

每個 ingestion job 使用短效、job-scoped identity,只能讀取指定來源、寫入隔離的暫存區。Generic worker 不需要 production database、cloud control plane、container registry push 或跨 namespace 的權限。真的需要例外時,也要讓例外綁定特定 job,而不是把權限長期留在共用 service account。

事故後輪替憑證當然必要,但 rotation 是清理手段,不是日常安全邊界。如果一組長效憑證能讓 processing worker 走遍整個叢集,換一組新的只是在等待下一次被拿走。

產物要跨過另一道邊界才能進 production

Ingestion worker 的輸出不該直接成為 production 可用的 artifact。

我會把流程拆成兩個信任區。第一區負責處理不可信任輸入,只能把結果寫進 quarantine。第二個低權限步驟再檢查 schema、格式、檔案數量、大小、內容規則與來源資訊,通過後才把 artifact promote 到可信任儲存區。

這個 promotion step 不需要重新執行外部 loader,也不該沿用 ingestion worker 的 runtime。它的工作很無聊:驗證一份已經產生的結果,然後做一次受控搬移。正因為無聊,權限才容易收得乾淨。

如果同一個 worker 可以下載未知內容、執行轉換、修改驗證規則,再把結果直接發布進 production,那就不是真的驗證,只是流程圖多了一個名稱。

惡意內容的事故分析也要留在邊界內

Hugging Face 表示,他們分析了超過 17,000 筆攻擊者行動紀錄。部分託管模型 API 會拒絕含有攻擊 payload 的內容,因此團隊改用內部託管的 open-weight model 協助分析。這也避免把攻擊資料和其中提到的憑證送到外部服務。

每家公司都為了 incident response 自架模型並不實際。先問一個更貼近日常的問題:當 log 裡含有 exploit、C2 位址、secret 或個資時,現有分析工具能不能在允許的信任邊界內工作?

如果答案是不行,事件發生後才找替代方案通常太慢。至少先準備一條能在內部完成搜尋、聚類、時間線整理與人工複核的路徑。工具可以不同,資料邊界要先說清楚。

上線前,我會問這五個問題

  1. Ingestion pipeline 裡有哪些 loader、template、preprocessor 或 hook 會執行程式?
  2. Worker 預設能不能任意連外?目前開放的目的地真的是 job 必要條件嗎?
  3. Worker 拿到哪些身分與 secret?它們能不能縮成短效、單一工作的權限?
  4. 處理後的 artifact 如何從 quarantine 進入可信任儲存區?中間是否有獨立驗證?
  5. 發生事故時,惡意 payload 與憑證會在哪裡被分析?資料會不會為了除錯又被送出組織?

這五題答不出來,先別急著加一個 scanner。Scanner 只能檢查它認得的東西,執行邊界卻決定了漏網內容可以走多遠。

Dataset pipeline 的第一個安全決定,是承認它是一條程式執行供應鏈。承認之後,隔離、網路、身分與 artifact promotion 才有地方可以落下來。

Source notes


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言