UrsaKit 驗證 AI 編碼助理建議套件的指南封面

請 AI 助理寫一個小工具,它常會給出一個很有自信的 import 與安裝指令。有時那個套件根本不存在。這不是隨機雜訊:同樣的虛構名稱會在重複提示中一再出現,而這正是攻擊者搶先註冊一個名稱並等待所需的特性。

這種攻擊叫 slopsquatting,而防禦方式不是「別再用 AI 助理」,而是在名稱進入套件管理器前先驗證,並讓安裝更難被武器化。

01slopsquatting 實際上是什麼

這個模式有三個部分。模型產生一個看似合理的套件名稱;這個名稱在用戶與多次執行之間足夠穩定、可被預測;套件庫允許任何人搶下未使用的名稱。

針對程式生成模型的研究顯示,在所有建議套件中,大約每五個就有一個是幻覺。重複名稱的 typosquatting 利用的是人類打錯已知套件;slopsquatting 利用的是機器自信地虛構出一個套件。因為模型陳述建議的語氣與陳述真實函數庫時一模一樣,這個錯誤很容易被複製進終端機,而不會多想一秒。

存在不等於合法

攻擊者可以在一個名稱出現在模型輸出後才搶先註冊。npm 找得到它,只證明有人佔用了這個名稱——不代表程式碼安全,也不代表它就是模型想指的東西。

02為什麼幻覺名稱可被預測

模型產生名稱的方式,就跟產生任何其他 token 一樣:延續最可能的模式。對日期函數庫來說,就是把 date 與常見字尾接起來;對 CLI 小工具來說,就是 @scope/tool-name。輸出不是真正的套件,但看起來完全像一個。

因為解碼每次都由相同統計引導,同一個提示往往產生同一個虛構名稱。這種可預測性就是漏洞。它也意味著解法不可能是「用更好的提示」——不存在永不幻覺名稱的模型,所以驗證必須落在你的流程裡。

03安裝前先驗證名稱

把這件事變成反射動作,整類攻擊就會困難許多。

  1. 直接問套件庫。 404 就結束了。
npm view left-pad version repository.url maintainers time.created
# version = '1.3.0'
# repository.url = 'git+ssh://git@github.com/stevemao/left-pad.git'

npm view left-paad version
# npm error 404 Not Found - GET https://registry.npmjs.org/left-paad - Not found
python3 -m pip index versions requests
# requests (2.32.5)
# Available versions: 2.32.5, 2.32.4, 2.32.3, ...
  1. 把套件對上你預期的項目。 讀 repository.url 與維護者清單。有原始碼項目、有 changelog、有多年發布紀錄的函數庫,看起來就和上週才註冊、沒有首頁的名稱不同。
  2. 檢查發布歷史的形狀。 整個版本清單在同一天出現是警訊;看起來像為了顯得成熟而挑的怪版本號(例如 99.0.0)也是。
  3. 把建議與生態系實際使用的東西比對。 若助理提議某個知名函數庫的包裝套件,先確認該函數庫是否早已原生提供這個功能。幻覺常常是為了填補一個不存在的空缺。

04Lockfile、安裝腳本與執行陷阱

安裝套件不是唯讀動作。生命週期腳本會在安裝時執行,惡意套件能在你的測試跑起來之前就用它們執行程式碼。

  • 提交並審查 lockfile。 npm ci 只安裝 lockfile 固定的內容,所以被審查過的 lockfile 就是一種控制。未經審查的 npm install <typo> 會改寫它。
  • 第一次接觸時跳過腳本。 用 npm install --ignore-scripts 加入相依套件,檢查後再視信任程度正常安裝。
  • Python 使用雜湊固定安裝。 pip install --require-hashes -r requirements.txt 會拒絕位元組與記錄雜湊不符的套件。
  • 保留安裝時審查步驟。 程式碼審查中的 lockfile 差異,是最便宜、最容易發現不該出現名稱的地方之一。
npm ci --ignore-scripts
npm ls --all | head -40
git diff -- package.json package-lock.json

要 diff lockfile,不只 diff package.json

一個新的頂層相依套件常會拖進十幾個間接套件。lockfile 差異會顯示全部,而那個你從未批准的名稱就藏在其中。

05強化整個流程,而不只是當下

個別檢查能抓到個別錯誤,幾個結構性控制則能抓到整類問題。

控制擋掉什麼
具允許清單的私有套件庫代理未知名稱到不了開發者手上
強制審查 lockfile偷渡進來的間接相依套件
CI 停用生命週期腳本安裝時執行程式碼
CI 相依套件掃描已知惡意套件與 CVE
內部套件命名規則內外部 scope 的混淆
出處/證明檢查沒有真實建置流程的 typosquat

套件庫代理的槓桿最大:若某個套件尚未被鏡像或列入允許清單,安裝就會失敗,由人類決定。這把無聲的供應鏈風險變成例行審查。

06如果你已經裝錯套件

把它當成資安事件,而不是打錯字。移除相依套件後,檢查安裝實際做了什麼:檢視 node_modules/<name> 裡的 postinstall 與 preinstall 腳本、尋找新的對外網絡請求、輪替安裝環境中出現過的任何憑證,並確認 lockfile 是否已提交並推送。在共享倉庫中,被汙染的 lockfile 才是會擴散的部分。

07常見錯誤與修正

錯誤為何失效修正
直接照聊天回答安裝完全沒有查核套件庫先跑 npm view 或 pip index versions
因為套件存在就信任攻擊者會註冊幻覺名稱檢查發布者、項目與發布歷史
只看 package.json間接套件藏在那裡審查 lockfile 差異
讓 CI 執行安裝腳本惡意程式碼在建置期間執行使用 --ignore-scripts 或沙箱化安裝
假設 scoped 名稱是內部的公開 scope 也能看起來像內部強制使用明確的內部 scope

真正重要的習慣很小:別讓模型的建議在沒有一次套件庫查詢的情況下變成相依套件。其餘強化措施,是為了那些你疲累、趕時間、準備好相信輸出的時刻。

常見問題

什麼是 slopsquatting?

slopsquatting 是指搶先註冊 AI 模型虛構出來的套件名稱,讓下一個照著模型建議複製指令的開發者,安裝到攻擊者的程式碼而不是什麼都沒裝。

AI 助理真的會虛構套件名稱嗎?

會。針對程式生成模型的研究發現,大約每五個建議套件就有一個不存在於套件庫,而且同樣的虛構名稱會在重複提示中一再出現。

套件在 npm 上真的存在就安全嗎?

存在是必要條件,但不足夠。名稱可能存在,是因為攻擊者看到它被幻覺出來後搶先註冊,所以還要檢查發布者、項目連結、出現時間與下載模式。

檢查套件最快的方法是什麼?

安裝前直接問套件庫。npm 用 `npm view <name>`;Python 用 `python -m pip index versions <name>`。404 就是停止訊號。

我該停用安裝腳本嗎?

對不可信或新加入的相依套件,應該。`npm install --ignore-scripts` 會跳過生命週期腳本,那正是惡意套件常見的執行路徑;等相依套件審查過後再正常安裝。

返回文章列表

相關文章

相關工具