// 威脅簡報

無 CVE 編號

PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖

CVSS
—
CISA KEV
未列入
弱點類型
CWE-506
主題
供應鏈

PlainCVE 團隊 · 發布 2026-09-30 · AI 輔助 · 媒體簡報 ↓

AI 審稿 2026-09-30(未經人工)指令測試:未提供漏洞重現:未進行驗證紀錄 ↓

攻擊者利用 PostHog 設定不當的 GitHub 工作流程偷到 npm 發布權杖,發布了會在安裝時竊取憑證並自我擴散的蠕蟲版 SDK。

誰會中從 2025-11-24 04:04 UTC 起到惡意版本被刪除前(PostHog 說 09:30 UTC,部分套件在 npm 上的最後修改時間更晚),安裝了 posthog-node 4.18.1/5.11.3/5.13.3、posthog-js 1.297.3 或其他 PostHog 套件惡意版本(OSV 列出至少 56 個套件)的開發機或 CI 環境,前提是安裝腳本有執行。PlainCVE 的判斷:之後透過 lockfile、本機快取或內部鏡像重新裝到這些版本的也應視為受影響(PostHog 建議清除快取,但來源沒有直接說明這種情況)。
後果安裝當下就會執行惡意程式,不需要真的 import 套件。PostHog 表示它會用 TruffleHog 搜尋各種憑證、公開貼到新建的 GitHub 程式庫,並用偷來的 npm 權杖感染其他套件。依 Datadog、StepSecurity 與 Wiz 的研究,它也會蒐集 AWS/GCP/Azure 雲端憑證並留下遠端控制後門;依 Aikido 與 Datadog,偷不到憑證也無法擴散時會清空家目錄。
現在該做什麼檢查 lockfile 是否含有惡意版本;若有,把該機器視為完全被入侵,在另一台乾淨的電腦上輪替所有憑證,刪除 node_modules 與套件快取,並改用 PostHog 公布的安全版本(例如 posthog-node 5.14.0、posthog-js 1.298.0)。
受影響版本OSV 列出 56 個 PostHog 套件的惡意版本(完整清單見「影響範圍」),主要包括 posthog-node 4.18.1、5.11.3、5.13.3;posthog-js 1.297.3;posthog-react-native 4.11.1、4.12.5;posthog-docusaurus 2.0.6;posthog-react-native-session-replay 1.2.2;@posthog/core 1.5.6;@posthog/agent 1.24.1;@posthog/ai 7.1.2;@posthog/cli 0.5.15;@posthog/wizard 1.18.1;@posthog/nuxt 1.2.9;posthog-plugin-hello-world 1.0.1
修好的版本PostHog 公布的安全版本:posthog-js 1.298.0、posthog-node 5.14.0、posthog-react-native 4.13.0、posthog-react-native-session-replay 1.2.3、@posthog/agent 1.24.2、@posthog/ai 7.2.0、@posthog/cli 0.5.16、@posthog/wizard 1.18.2、posthog-plugin-hello-world 1.0.0。其餘套件(包括 posthog-docusaurus 與 @posthog/core)沒有逐一指名的安全版本;PostHog 檢討報告表示,發現攻擊後發布的最新版本都是已知安全的版本。
時間點
  • 漏洞出現 2025-11-24 · PostHog 檢討報告寫惡意版本於 04:11 UTC 發布;npm registry 紀錄 posthog-node 5.11.3 於 04:04 UTC 發布 來源
  • 首次公開 2025-11-24
  • 開始被攻擊 2025-11-24 · 惡意版本自 04:04 UTC(npm registry;PostHog 寫 04:11)起在 npm 上可被安裝執行;PostHog 表示 09:30 UTC 前已刪除,但 npm registry 上部分套件的最後修改時間更晚;PlainCVE 判斷之後仍可能從 lockfile 與快取裝回(來源沒有直接說明這種情況) 來源

藍隊應對手冊

確認、修補 / 緩解、應變、強化。版本符合受影響條件不等於已被入侵;檢查沒有結果也不等於安全,每一項都有能證明與不能證明的範圍。標記的步驟對應下方攻擊流程裡可以擋下攻擊的那一步。

DETECT確認我受影響嗎?有沒有入侵跡象?
  1. 01檢查專案是否裝過惡意版本

    列出專案相依樹裡所有名稱含 posthog 的套件與版本,再和「影響範圍」的表格與 OSV 清單比對;lockfile 也要一起查,因為之後重新安裝時會照它裝。

    唯讀查詢
    npm ls --all 2>/dev/null | grep -i posthog
  2. 02搜尋研究報告公布的檔名

    PostHog 與 Wiz 列出的檔名:setup_bun.js、bun_environment.js、cloud.json、contents.json、environment.json、truffleSecrets.json。另留意安裝時新出現的 ~/.bun/bin/bun。

    唯讀查詢
    find . ~ \( -name setup_bun.js -o -name bun_environment.js -o -name truffleSecrets.json -o -name cloud.json -o -name contents.json -o -name environment.json \) 2>/dev/null
  3. 03搜尋 npm 紀錄

    PostHog 建議在 npm 紀錄中找含有「shai」或「preinstall」的項目。

    唯讀查詢
    grep -rniE 'shai|preinstall' ~/.npm/_logs/
  4. 04檢查 GitHub 帳號與組織的後門痕跡

    依 StepSecurity 與 Datadog,後門工作流程 .github/workflows/discussion.yaml 與名為 SHA1HULUD 的自架 runner 是掛在蠕蟲用你的權杖新建立的程式庫上,不在你原有的專案裡,所以要檢查的是 GitHub 帳號本身。列出帳號的程式庫(需要已登入的 GitHub CLI,組織帳號也可以換成組織名稱),找近期突然出現、你不認得的公開程式庫:Datadog 指出這類程式庫名稱是 18 個小寫英數字元的亂碼,描述為「Sha1-Hulud: The Second Coming.」。

    唯讀查詢
    gh repo list YOUR_ACCOUNT --limit 100 --json name,description,createdAt,visibility
MITIGATE修補 / 緩解先修補;還不能修補時先擋住
  1. 01改用 PostHog 公布的安全版本並鎖定

    例如 posthog-js 1.298.0、posthog-node 5.14.0。PostHog 檢討報告表示,發現攻擊後發布的最新版本都是已知安全(known-good)的版本。

    唯讀查詢
    npm view posthog-node versions --json
  2. 02刪除 node_modules 並清除套件快取

    GitHub 對 @posthog/core 的公告建議移除套件,並從另一台電腦輪替所有密鑰;PostHog 的 issue 建議刪除 node_modules,用 pnpm 的話執行 pnpm cache delete;PostHog 檢討報告與 GitLab 對 posthog-js 的公告另外建議清除 npm 快取。PlainCVE 認為這也能避免之後從快取或舊的 lockfile 重新裝回惡意版本。

  3. 03在 CI 關閉安裝腳本

    惡意程式靠 preinstall 腳本啟動;不執行安裝腳本就不會觸發。

    唯讀查詢
    npm config get ignore-scripts
RESPOND應變發現入侵跡象時
  1. 01把機器視為完全被入侵,從乾淨電腦輪替憑證

    輪替該機器能接觸到的所有密鑰:GitHub PAT、npm 權杖、SSH 金鑰、雲端金鑰與 CI 密鑰。只移除套件不夠,攻擊者可能已取得完整權限。

  2. 02清除攻擊者留下的程式庫、runner 與工作流程

    刪除攻擊者建立的程式庫,移除可疑的自架 runner 與工作流程,並檢視 GitHub 安全紀錄(StepSecurity 建議)。

  3. 03檢查你維護的套件是否被重新發布

    蠕蟲會用偷到的 npm 權杖感染受害者維護的套件,維護者應檢查自己套件近期是否出現非預期的新版本。

    唯讀查詢
    npm view YOUR_PACKAGE time --json
HARDEN強化長期避免同類問題
  1. 01不要在 pull_request_target 執行 PR 的程式

    改用 pull_request,或拆成無特權的 pull_request 加上特權的 workflow_run;不要依賴標籤閘門。工作流程變更要經安全審查。

    唯讀查詢
    grep -rn 'pull_request_target' .github/workflows/
  2. 02改用 trusted publishing

    不在 CI 保存長效 npm 權杖,權杖外洩的傷害就小得多。PostHog 事後已改用此方式。

  3. 03設定新版本冷卻期

    PostHog 建議 minimumReleaseAge 至少 3 天;StepSecurity 建議 2 天。這次依 PostHog 的說法,惡意版本約 5 小時就被刪除。

  4. 04使用防釣魚的多因素驗證

    Wiz 建議;GitHub 的 npm 計畫也要求本機發布須 2FA,並以 FIDO 金鑰取代一次性密碼。

完整修復步驟與說明
  1. 先確認有沒有裝到。 在 lockfile 與 node_modules 比對上表與表格下方清單的版本(包括下架之後才從 lockfile 或快取重新安裝的情況);搜尋 setup_bun.js、bun_environment.js、cloud.json、contents.json、environment.json、truffleSecrets.json;在 npm 紀錄中找「shai」或「preinstall」。也檢查 GitHub 帳號與組織有沒有突然多出、你不認得的程式庫:依 StepSecurity 與 Datadog,名為 SHA1HULUD 的 runner 與 discussion.yaml 後門工作流程就掛在這些蠕蟲新建的程式庫上。
  2. 若裝到了,視為完全被入侵。 在另一台乾淨的電腦上,輪替這台機器能接觸到的所有密鑰:GitHub PAT、npm 權杖、SSH 金鑰、雲端金鑰與 CI 密鑰。只移除套件不夠,攻擊者可能已經拿到完整權限。
  3. 清除。 移除套件、刪除 node_modules、清除 npm 或 pnpm 快取;刪除攻擊者建立的程式庫,移除可疑的 runner 與工作流程,檢視 GitHub 安全紀錄。如果你維護 npm 套件,也要檢查是否被發布了非預期的新版本。
  4. 改用安全版本並鎖定。 例如 posthog-node 5.14.0、posthog-js 1.298.0(完整清單見上表)。注意 GitHub 與 GitLab 公告寫「沒有修補版本」,這是惡意套件公告的慣例寫法;PostHog 自己則公布了安全版本。
  5. 長期強化。
    • 設定新版本「冷卻期」:PostHog 建議 minimumReleaseAge 至少 3 天,StepSecurity 建議 2 天。
    • 在 CI 停用或限制安裝腳本。
    • 使用防釣魚的多因素驗證。
    • 套件維護者:改用 trusted publishing;絕不在 pull_request_target 下執行 PR 程式;工作流程變更須經安全審查。

PostHog 在事件發生前(2025 年 7 月)就已聘請專職資安人員;PostHog 表示,這次 11 月的事件應變與事後分析,都仰賴他先前建立的工具與流程。事件之後的改變包括:改用 trusted publishing、工作流程變更由資安團隊審查、升級到 pnpm 10、重新設計 GitHub 密鑰管理。

攻擊流程

從左到右是攻擊發生的順序。藍色盾牌代表這一步可以被擋下,越早擋下越好。點圖示可看細節。

由上到下是攻擊發生的順序。藍色盾牌代表這一步可以被擋下,越早擋下越好。點圖示可看細節。

PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖: 1. 攻擊者對 PostHog 的程式庫開一個惡意 pull request → 2. 攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的 GitHub 權杖 → 3. 攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖 → 4. 攻擊者把植入蠕蟲的版本發布到 npm → 5. 使用者安裝時,preinstall 腳本自動執行惡意程式 → 6. 蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖攻擊者你的系統外部攻擊者對 PostHog 的程式庫開一個惡意 pull request — PostHog 在 2025-09-11 合併的工作流程使用 pull_request_target 觸發,卻又執行了來自 PR 本身的程式(指派審查者的腳本)。 1攻擊者對 PostHog 的程式庫開一個惡意 pullrequest攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的 GitHub 權杖 — pull_request_target 帶有主程式庫的密鑰與寫入權限,所以 PR 裡的程式也拿到了同樣的權限。GitHub Security Lab 稱這種模式為「pwn request」。 2攻擊者的程式在受信任的CI 環境執行,偷走機器人帳號的 GitHub 權杖攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖 — 2025-11-23 攻擊者先測試權杖,再以一個分離的 commit 修改 Lint PR 工作流程,讓它把所有 GitHub 密鑰送出去。 3攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖攻擊者把植入蠕蟲的版本發布到 npm — PostHog 檢討報告寫 2025-11-24 04:11(UTC)發布;npm registry 紀錄 posthog-node 5.11.3 於 04:04、5.13.3 於 04:09、4.18.1 於 04:13 發布。PostHog 表示 09:30 前已找出並刪除惡意套件、撤銷權杖。 4攻擊者把植入蠕蟲的版本發布到 npm使用者安裝時,preinstall 腳本自動執行惡意程式 — 依 PostHog,它用 TruffleHog 搜尋各種憑證,並用受害者權杖建立公開程式庫貼出資料。依 Datadog 與 StepSecurity,它先安裝 Bun 執行環境再執行混淆過的主程式,也會蒐集 AWS、GCP、Azure 雲端憑證,並註冊名為 SHA1HULUD 的自架 runner 當後門。 5使用者安裝時,preinstall 腳本自動執行惡意程式蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件 — 依 Aikido,每位受害者最多感染 100 個套件(第一波上限為 20)。依 Aikido 與 Datadog,若偷不到憑證也無法擴散,會嘗試清空家目錄。 6蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件攻擊路徑可在此擋下PlainCVE · plaincve.date/vulns/mal-2025-190925-posthog-npm-shai-hulud-2 · CC BY 4.0
PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖: 1. 攻擊者對 PostHog 的程式庫開一個惡意 pull request → 2. 攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的 GitHub 權杖 → 3. 攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖 → 4. 攻擊者把植入蠕蟲的版本發布到 npm → 5. 使用者安裝時,preinstall 腳本自動執行惡意程式 → 6. 蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件PostHog 官方 npm 套件遭植入 Shai-Hulud2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖攻擊者對 PostHog 的程式庫開一個惡意 pull request — PostHog 在 2025-09-11 合併的工作流程使用 pull_request_target 觸發,卻又執行了來自 PR 本身的程式(指派審查者的腳本)。 1攻擊者攻擊者對 PostHog 的程式庫開一個惡意 pull request攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的 GitHub 權杖 — pull_request_target 帶有主程式庫的密鑰與寫入權限,所以 PR 裡的程式也拿到了同樣的權限。GitHub Security Lab 稱這種模式為「pwn request」。 2你的系統攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的GitHub 權杖攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖 — 2025-11-23 攻擊者先測試權杖,再以一個分離的 commit 修改 Lint PR 工作流程,讓它把所有 GitHub 密鑰送出去。 3攻擊者攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖攻擊者把植入蠕蟲的版本發布到 npm — PostHog 檢討報告寫 2025-11-24 04:11(UTC)發布;npm registry 紀錄 posthog-node 5.11.3 於 04:04、5.13.3 於 04:09、4.18.1 於 04:13 發布。PostHog 表示 09:30 前已找出並刪除惡意套件、撤銷權杖。 4攻擊者攻擊者把植入蠕蟲的版本發布到npm使用者安裝時,preinstall 腳本自動執行惡意程式 — 依 PostHog,它用 TruffleHog 搜尋各種憑證,並用受害者權杖建立公開程式庫貼出資料。依 Datadog 與 StepSecurity,它先安裝 Bun 執行環境再執行混淆過的主程式,也會蒐集 AWS、GCP、Azure 雲端憑證,並註冊名為 SHA1HULUD 的自架 runner 當後門。 5你的系統使用者安裝時,preinstall 腳本自動執行惡意程式蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件 — 依 Aikido,每位受害者最多感染 100 個套件(第一波上限為 20)。依 Aikido 與 Datadog,若偷不到憑證也無法擴散,會嘗試清空家目錄。 6外部蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件攻擊路徑可在此擋下PlainCVE · CC BY 4.0plaincve.date/vulns/mal-2025-190925-posthog-npm-shai-hulud-2
圖片可自由用於報導與教學,採 CC BY 4.0,圖上已附出處。
  1. 攻擊者

    攻擊者對 PostHog 的程式庫開一個惡意 pull request

    PostHog 在 2025-09-11 合併的工作流程使用 pull_request_target 觸發,卻又執行了來自 PR 本身的程式(指派審查者的腳本)。

    防禦: 不要在 pull_request_target 底下執行外部 PR 的程式;不受信任的程式改用一般的 pull_request 觸發。

  2. 你的系統

    攻擊者的程式在受信任的 CI 環境執行,偷走機器人帳號的 GitHub 權杖

    pull_request_target 帶有主程式庫的密鑰與寫入權限,所以 PR 裡的程式也拿到了同樣的權限。GitHub Security Lab 稱這種模式為「pwn request」。

    防禦: 把工作拆成兩段:無特權的 pull_request 工作,加上只處理其結果的 workflow_run 特權工作;機器人權杖只給最小權限。

  3. 攻擊者

    攻擊者用偷來的權杖修改工作流程,倒出所有密鑰,包括 npm 發布權杖

    2025-11-23 攻擊者先測試權杖,再以一個分離的 commit 修改 Lint PR 工作流程,讓它把所有 GitHub 密鑰送出去。

    防禦: 工作流程變更須經安全審查;改用 trusted publishing,不在 CI 存放長效 npm 權杖。

  4. 攻擊者

    攻擊者把植入蠕蟲的版本發布到 npm

    PostHog 檢討報告寫 2025-11-24 04:11(UTC)發布;npm registry 紀錄 posthog-node 5.11.3 於 04:04、5.13.3 於 04:09、4.18.1 於 04:13 發布。PostHog 表示 09:30 前已找出並刪除惡意套件、撤銷權杖。

    防禦: 設定套件「冷卻期」(例如 pnpm 的 minimumReleaseAge),新版本發布數天後才採用。

  5. 你的系統

    使用者安裝時,preinstall 腳本自動執行惡意程式

    依 PostHog,它用 TruffleHog 搜尋各種憑證,並用受害者權杖建立公開程式庫貼出資料。依 Datadog 與 StepSecurity,它先安裝 Bun 執行環境再執行混淆過的主程式,也會蒐集 AWS、GCP、Azure 雲端憑證,並註冊名為 SHA1HULUD 的自架 runner 當後門。

    防禦: 在 CI 停用或限制安裝腳本(例如 pnpm 10 預設不執行相依套件的安裝腳本)。

  6. 外部

    蠕蟲用偷到的 npm 權杖感染受害者維護的其他套件

    依 Aikido,每位受害者最多感染 100 個套件(第一波上限為 20)。依 Aikido 與 Datadog,若偷不到憑證也無法擴散,會嘗試清空家目錄。

    防禦: 從另一台乾淨電腦輪替所有權杖;維護者改用 trusted publishing 與防釣魚的多因素驗證。

這不是一般的軟體漏洞,而是惡意套件事件:沒有 CVE 編號,也不在 NVD 或 CISA KEV 清單中。本頁使用的是 OSV 的惡意套件編號 MAL-2025-190925。

影響範圍

惡意程式在安裝時就會執行,不需要你的程式 import 或呼叫這些套件。只要開發機或 CI 執行了 npm install(或類似指令)、裝到下表或下方清單的版本、而且允許安裝腳本執行,就應視為受影響。最可能的時段是 2025-11-24 04:04 UTC 起到惡意版本被刪除前(PostHog 說 09:30 UTC 前已刪除);PlainCVE 的判斷是:如果 lockfile 已經寫進惡意版本,或本機快取、公司內部的套件鏡像留有副本,之後重新安裝仍可能裝回來,所以也應一併檢查。來源沒有直接說明這種情況,但 PostHog 的檢討報告與 issue 都建議刪除快取的相依套件。

套件惡意版本PostHog 公布的安全版本OSV 編號 / 備註
posthog-node4.18.1、5.11.3、5.13.35.14.0MAL-2025-190925(本頁主編號)
posthog-js1.297.31.298.0MAL-2025-191402;GitLab GMS-2025-554
posthog-react-native4.11.1、4.12.54.13.0MAL-2025-190926;PostHog 只列 4.11.1,4.12.5 見於 OSV 與 npm registry(04:09 UTC 發布,已刪除)
posthog-react-native-session-replay1.2.21.2.3MAL-2025-190649
posthog-docusaurus2.0.6未指名MAL-2025-190924
@posthog/agent1.24.11.24.2MAL-2025-190748
@posthog/ai7.1.27.2.0MAL-2025-190644
@posthog/cli0.5.150.5.16MAL-2025-190671
@posthog/wizard1.18.11.18.2MAL-2025-190900;PostHog 的 issue 有列,檢討報告沒有
@posthog/core1.5.6未指名MAL-2025-190645、GHSA-3f6v-43gc-g8fr;PostHog 沒有列
posthog-plugin-hello-world1.0.11.0.0MAL-2025-190778、GHSA-9mwj-fr6x-j3hg;PostHog 的 issue 只列 1.0.0 為安全版本

PostHog 檢討報告只列出「最相關」的套件。OSV 另外把以下 PostHog 套件列為惡意(本頁 2026-09-28 查詢 OSV 整理,每個套件都有自己的 MAL 編號,可在 osv.dev 以套件名稱搜尋;PostHog 沒有逐一指名安全版本):

  • @posthog/clickhouse 1.7.1、@posthog/hedgehog-mode 0.0.42、@posthog/icons 0.36.1、@posthog/lemon-ui 0.0.1、@posthog/nextjs-config 1.5.1、@posthog/nuxt 1.2.9、@posthog/piscina 3.2.1、@posthog/plugin-contrib 0.0.6、@posthog/plugin-server 1.10.8、@posthog/rrweb 0.0.31、@posthog/rrweb-player 0.0.31、@posthog/rrweb-record 0.0.31、@posthog/rrweb-replay 0.0.19、@posthog/siphash 1.1.2、@posthog/web-dev-server 1.0.5
  • 以下 30 個外掛套件的 0.0.8 版:@posthog/automatic-cohorts-plugin、@posthog/bitbucket-release-tracker、@posthog/currency-normalization-plugin、@posthog/customerio-plugin、@posthog/databricks-plugin、@posthog/drop-events-on-property-plugin、@posthog/event-sequence-timer-plugin、@posthog/filter-out-plugin、@posthog/first-time-event-tracker、@posthog/geoip-plugin、@posthog/github-release-tracking-plugin、@posthog/gitub-star-sync-plugin、@posthog/heartbeat-plugin、@posthog/ingestion-alert-plugin、@posthog/intercom-plugin、@posthog/kinesis-plugin、@posthog/laudspeaker-plugin、@posthog/migrator3000-plugin、@posthog/netdata-event-processing、@posthog/pagerduty-plugin、@posthog/plugin-unduplicates、@posthog/postgres-plugin、@posthog/sendgrid-plugin、@posthog/snowflake-export-plugin、@posthog/taxonomy-plugin、@posthog/twilio-plugin、@posthog/twitter-followers-plugin、@posthog/url-normalizer-plugin、@posthog/variance-plugin、@posthog/zendesk-plugin

上述 56 個套件的惡意版本,npm registry 記錄的發布時間都在 2025-11-24 04:04 至 04:13 UTC 之間,目前都已不在 npm 的版本清單中。本頁的查詢是以 npm 上名稱含 posthog 的套件為範圍,不保證完整。

其他要點:

  • PostHog 檢討報告表示,發現攻擊後發布的最新版本都是已知安全(known-good)的版本;惡意版本已從 npm 刪除並由新版取代。安全版本清單見上表。
  • 刪除時間:PostHog 說 09:30 UTC 前已找出並刪除惡意套件;不過 npm registry 記錄 posthog-docusaurus 最後修改於 09:57 UTC、posthog-plugin-hello-world 最後修改於 14:11 UTC。registry 沒有直接記錄刪除時間,所以不能確定每個套件都在 09:30 前下架。
  • 惡意版本的發布時間:PostHog 檢討報告寫 04:11 UTC;npm registry 的紀錄顯示 posthog-node 5.11.3 在 04:04 UTC、5.13.3 在 04:09 UTC、4.18.1 在 04:13 UTC 發布。本頁以 04:04 作為可能受影響時段的起點。
  • PostHog 表示不知道有客戶正式環境用到惡意版本。
  • 安裝時不執行生命週期腳本的環境(例如 pnpm 10 預設不跑相依套件的安裝腳本)暴露程度較低。
  • Wiz 在它掃描的環境中,有 25% 用了 posthog-node、15% 用了 posthog-js。這代表套件普及程度,不是實際感染數。

原理

這起事件有兩層:PostHog 自己怎麼被攻破,以及惡意套件對安裝者做了什麼。

第一層:一個「pwn request」讓攻擊者拿到發布權杖

GitHub Actions 的 pull_request_target 觸發方式,會用主程式庫的身分執行,帶著密鑰與寫入權限。它原本的用意是讓工作流程的「定義」來自受信任的主分支。問題在於,如果工作流程接著又去取出並執行外部 PR 裡的程式,那段陌生程式就拿到了同樣的權限。GitHub Security Lab 把這種錯誤稱為「pwn request」。

PostHog 在 2025-09-11 合併的工作流程就是這樣:它用 pull_request_target,同時執行 PR 裡的一支指派審查者腳本。PostHog 在檢討報告中承認,開發者誤以為 pull_request_target 會保護被執行的程式;實際上它只決定工作流程定義從哪裡讀取。

事件經過(概念說明):

  1. 攻擊者開了一個惡意 PR,程式在受信任的 CI 環境中執行。
  2. 這段程式偷走一個機器人帳號的 GitHub 個人存取權杖(PAT)。
  3. 攻擊者用它修改工作流程,把程式庫所有密鑰倒出來,其中包括 npm 發布權杖。
  4. 攻擊者用 npm 權杖發布了植入蠕蟲的套件版本。

有問題的模式(概念示意,不是 PostHog 的原始設定):

展開程式碼範例(yaml)
on: pull_request_target        # 以主程式庫權限與密鑰執行
jobs:
  assign:
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}  # 取出外部 PR 的程式
      - run: node scripts/assign-reviewers.js            # 執行 PR 裡的程式 → 拿到密鑰

較安全的模式:

展開程式碼範例(yaml)
on: pull_request               # 外部 PR 在無密鑰、唯讀權限下執行
permissions:
  contents: read
jobs:
  check:
    steps:
      - uses: actions/checkout@v4
      - run: node scripts/check.js
# 需要寫入權限的後續動作,放到另一個由 workflow_run 觸發、只處理結果、不執行 PR 程式的工作流程

第二層:Shai-Hulud 2.0 蠕蟲做了什麼

以下整理自各研究報告,本頁沒有開啟任何套件檔或惡意程式:

  • 安裝時啟動:preinstall 腳本(setup_bun.js)先安裝 Bun 這個 JavaScript 執行環境,再執行大型混淆程式 bun_environment.js。Datadog 指出改用 Bun 有助於躲開只監控 Node.js 的工具。
  • 竊取憑證:PostHog 表示它用開源工具 TruffleHog 搜尋執行環境中的各種憑證。依 Datadog 與 StepSecurity,它還會蒐集 GitHub 權杖、npm 權杖、環境變數,以及 AWS、GCP、Azure 的雲端憑證與密鑰管理服務內容;Wiz 統計整波攻擊外洩的憑證中有數百組雲端憑證。
  • 公開貼出:用受害者自己的權杖建立新的公開 GitHub 程式庫,把偷到的資料貼上去。Wiz 還看到某位受害者的密鑰被貼在無關使用者的帳號下。
  • 留下後門:註冊名為 SHA1HULUD 的自架 GitHub Actions runner,並加入 .github/workflows/discussion.yaml。這個工作流程會監聽新建立的 GitHub Discussion,攻擊者只要在受害程式庫開一則新的 Discussion、把指令寫在內文裡,就能讓指令在這台被註冊為 runner 的機器上執行。
  • 自我擴散:拿到 npm 權杖後,感染受害者維護的最多 100 個套件(依 Aikido,第一波上限是 20 個)。
  • 破壞:依 Aikido 與 Datadog,若既偷不到憑證也無法擴散,會嘗試清空使用者家目錄;StepSecurity 也描述了在 Linux 上覆寫檔案以抹除痕跡的行為。
  • 其他:在 CI 中立刻執行,在開發機上則在背景執行;也會嘗試透過特權掛載逃出 Docker 容器。

這對應 CWE-506(嵌入惡意程式碼)。

時間軸

時間(UTC)事件
2025-09-11PostHog 合併有問題的工作流程變更
2025-09-14 或 09-16第一波 Shai-Hulud 蠕蟲(GitHub 記為 14 日,Aikido 記為 16 日)
2025-11-18 下午 5:40(檢討報告未註明時區,同段截圖為 UTC+2,不一定是 UTC)攻擊者帳號開出惡意 PR,機器人 PAT 被偷
2025-11-23 15:28攻擊者刪除一筆工作流程執行紀錄,測試權杖是否可用
2025-11-23 15:43–15:45攻擊者以分離 commit 修改 Lint PR 工作流程,所有 GitHub 密鑰(含 npm 權杖)被送出
2025-11-24 約 03:16第二波「Sha1-Hulud: The Second Coming」開始,AsyncAPI 最先中招(Aikido)
2025-11-24 04:04–04:13PostHog 惡意版本發布到 npm(npm registry:posthog-node 5.11.3 於 04:04、5.13.3 於 04:09、4.18.1 於 04:13,其他 PostHog 套件大多在 04:08–04:10;PostHog 檢討報告寫 04:11)
2025-11-24 09:30PostHog 表示此時已找出並刪除惡意套件、撤銷權杖
2025-11-24 09:57、14:11npm registry 記錄 posthog-docusaurus 與 posthog-plugin-hello-world 的最後修改時間(registry 未直接記錄刪除時間)
2025-11-24PostHog 在 GitHub 開 issue #2633 公告;GitHub 發布 @posthog/core 公告;16:31 OSV 發布 posthog-node 紀錄 MAL-2025-190925
2025-11-25OSV 發布 posthog-js 紀錄;GitLab 發布 GMS-2025-554
2025-11-26PostHog 發表事後檢討報告
CVE / KEV無,不適用

延伸閱讀

  • 評分:本事件沒有 CVE,也沒有 NVD 評分。GitHub 對 @posthog/core 的公告不給 CVSS 分數,只標示為 Critical (Malware);GitLab 對 posthog-js 給出 CVSS 3.1 8.6(AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H)。由於這是另一個套件的評分,本頁的嚴重度欄位留空。
  • 來源不一致之處:
    • 受影響套件的範圍:PostHog 檢討報告只列「最相關」的 8 個套件(共 10 個版本),issue 另列 @posthog/wizard,合計 9 個;OSV 列出 56 個 PostHog 套件,包括 @posthog/core、posthog-react-native 4.12.5、posthog-plugin-hello-world 等。
    • 刪除時間:PostHog 說 09:30 UTC 前,npm registry 上 posthog-docusaurus 與 posthog-plugin-hello-world 的最後修改時間分別是 09:57 與 14:11 UTC。
    • 惡意版本的發布時間:PostHog 檢討報告寫 04:11 UTC,npm registry 紀錄 posthog-node 5.11.3 早在 04:04 UTC 就已發布。
    • 整波攻擊的規模:Aikido 算 492 個套件;Datadog 算 796 個(並稱是下限);Wiz 估約 700 至 800 個,另統計外洩了 775 個 GitHub 權杖以及 373 組 AWS、300 組 GCP、115 組 Azure 憑證;StepSecurity 早期算超過 70 個;PostHog 的 issue 寫「超過 300 個」。
    • 攻擊者程式庫的描述字樣:StepSecurity 與 Aikido 記為「Sha1-Hulud: The Second Coming」。Wiz 另外記錄,11/25 22:45 UTC 觀察到一個可能的第二階段(用第一階段偷到的憑證,把單一受害者的私有程式庫公開),這個階段用的描述是「Sha1-Hulud: The Continued Coming」。
    • Wiz 認為第二波沿用第一波的名稱與手法,但幕後可能是不同的人。
  • PostHog 在這波攻擊中的位置:PostHog 是因為自己的 CI 設定錯誤而被攻破,不是因為維護者裝到感染的套件。Datadog 認為這是攻擊者多種入侵途徑之一。一旦惡意版本發布,PostHog 的套件就成了感染其他維護者的媒介。
  • npm 的背景:這波攻擊發生在 npm 預定 2025-12-09 撤銷傳統權杖之前不久。GitHub 在 2025 年 9 月公布的計畫包括:淘汰傳統權杖、細粒度權杖最多有效 7 天、推行 trusted publishing、本機發布強制 2FA 並以 FIDO 金鑰取代一次性密碼。
  • AI 相關性:雖然有兩個受影響套件名稱是 @posthog/ai 與 @posthog/agent,但沒有來源顯示這次攻擊本身與 AI 有關,本頁不做此推論。
  • 未能確認:GitHub 是否有 posthog-node 與 posthog-js 的 GHSA 公告;惡意版本上架期間被下載了幾次;CISA 關於第一波 Shai-Hulud 的警示內容(該頁面無法讀取,本頁未使用)。

驗證紀錄 AI 依審稿規則逐項核對來源,全部通過;未經人工審稿,也尚未在我們的環境重現

AI 審稿2026-09-30 · 審稿規則

驗證紀錄只寫環境與結果,不公開重現步驟或可攻擊他人系統的程式。詳見 政策.

來源

  1. 廠商說明Shai-Hulud 2.0 Supply Chain Attack Post-Mortem · PostHog, 2025-11-26 · 查閱 2026-09-28
  2. 其他posthog-node package metadata (npm registry) · npm · 查閱 2026-09-28
    time 欄位:5.11.3 於 2025-11-24T04:04:24Z、5.13.3 於 04:09:08Z、4.18.1 於 04:13:22Z 發布
  3. 安全公告posthog-js and other packages were temporarily compromised - November 24th - SHA1 HULUD (issue #2633) · PostHog (GitHub), 2025-11-24 · 查閱 2026-09-28
  4. 安全公告MAL-2025-190925: Malicious code in posthog-node (npm) · OSV, 2025-11-24 · 查閱 2026-09-23
  5. 安全公告MAL-2025-190926: Malicious code in posthog-react-native (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
    惡意版本 4.12.5、4.11.1
  6. 安全公告MAL-2025-190900: Malicious code in @posthog/wizard (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  7. 安全公告MAL-2025-190924: Malicious code in posthog-docusaurus (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  8. 安全公告MAL-2025-190778: Malicious code in posthog-plugin-hello-world (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  9. 安全公告Malware in posthog-plugin-hello-world (GHSA-9mwj-fr6x-j3hg) · GitHub Advisory Database, 2025-11-24 · 查閱 2026-09-28
  10. 安全公告MAL-2025-190753: Malicious code in @posthog/siphash (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  11. 安全公告MAL-2025-191292: Malicious code in @posthog/icons (npm) · OSV, 2025-11-25 · 查閱 2026-09-28
  12. 安全公告MAL-2025-190887: Malicious code in @posthog/nextjs-config (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  13. 安全公告MAL-2025-190749: Malicious code in @posthog/nuxt (npm) · OSV, 2025-11-24 · 查閱 2026-09-28
  14. 安全公告OSV search results for npm packages matching posthog · OSV · 查閱 2026-09-28
    本頁 2026-09-28 以 OSV API 逐一查詢 npm 上名稱含 posthog 的套件,整理出 56 個 PostHog 套件的 MAL 紀錄
  15. 其他posthog-docusaurus package metadata (npm registry) · npm · 查閱 2026-09-28
    time 欄位:2.0.6 於 2025-11-24T04:08:49Z 發布,modified 為 2025-11-24T09:57:58Z;2.0.6 已不在版本清單中
  16. 其他posthog-react-native package metadata (npm registry) · npm · 查閱 2026-09-28
    time 欄位:4.12.5 於 2025-11-24T04:09:10Z、4.11.1 於 04:10:52Z 發布;兩者都已不在版本清單中
  17. 其他posthog-plugin-hello-world package metadata (npm registry) · npm · 查閱 2026-09-28
    time 欄位:1.0.1 於 2025-11-24T04:08:55Z 發布,modified 為 2025-11-24T14:11:50Z;1.0.1 已不在版本清單中
  18. 安全公告MAL-2025-191402: Malicious code in posthog-js (npm) · OSV, 2025-11-25 · 查閱 2026-09-23
  19. 安全公告MAL-2025-190645: Malicious code in @posthog/core (npm) · OSV, 2025-11-24 · 查閱 2026-09-23
  20. 安全公告Malware in @posthog/core (GHSA-3f6v-43gc-g8fr) · GitHub Advisory Database, 2025-11-24 · 查閱 2026-09-28
  21. 安全公告Advisories for Npm/Posthog-Js package · GitLab Advisory Database · 查閱 2026-09-23
  22. 安全公告posthog-js contains malware after npm account takeover (GMS-2025-554) · GitLab Advisory Database, 2025-11-25 · 查閱 2026-09-28
  23. 研究文章Shai-Hulud 2.0: Ongoing Supply Chain Attack · Wiz, 2025-11-24 · 查閱 2026-09-28
  24. 研究文章Sha1-Hulud: The Second Coming – Zapier, ENS Domains, and Other Prominent NPM Packages Compromised · StepSecurity, 2025-11-23 · 查閱 2026-09-28
  25. 研究文章Shai-Hulud 2.0 npm worm analysis · Datadog Security Labs, 2025-11-25 · 查閱 2026-09-28
  26. 研究文章Shai Hulud strikes again, hitting Zapier & ENSDomains · Aikido Security, 2025-11-24 · 查閱 2026-09-23
  27. 研究文章Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests · GitHub Security Lab, 2021-08-03 · 查閱 2026-09-23
  28. 廠商說明Our plan for a more secure npm supply chain · GitHub Blog, 2025-09-22 · 查閱 2026-09-23

媒體簡報

一句話

2025 年 11 月 24 日,產品分析公司 PostHog 的官方 JavaScript 套件在 npm 上被換成惡意版本,裡面藏著名為「Sha1-Hulud: The Second Coming」(Shai-Hulud 2.0)的自我擴散蠕蟲。攻擊者先利用 PostHog 一個設定不當的 GitHub 自動化流程偷到發布權杖,再發布會在安裝時竊取開發者憑證的版本。PostHog 表示惡意版本約五小時後已被刪除,也表示不知道有客戶的正式環境用到它們。這是一波波及數百個 npm 套件的大規模攻擊的一部分。

關鍵數字

惡意版本發布時間
2025-11-24 04:11 UTC(PostHog 檢討報告);npm registry 紀錄 posthog-node 5.11.3 於 04:04 UTC、5.13.3 於 04:09 UTC 發布;PostHog 表示 09:30 UTC 前已刪除 posthog.com
OSV 列為惡意的 PostHog 套件
56 個(本頁 2026-09-28 查詢 OSV 的結果,可能不完整) osv.dev
本頁事件編號
MAL-2025-190925(posthog-node 4.18.1、5.11.3、5.13.3) osv.dev
安全版本
posthog-node 5.14.0、posthog-js 1.298.0 等 github.com
分類
GitHub 對 @posthog/core 的公告 GHSA-3f6v-43gc-g8fr 列 CWE-506 嵌入惡意程式碼,評為 Critical (Malware);GitLab 對 posthog-js 的 GMS-2025-554 也列 CWE-506 github.com
評分
無 CVE、無 NVD 評分;GitLab 對 posthog-js 給 CVSS 3.1 8.6 advisories.gitlab.com

已確認

  • PostHog 多個官方 npm 套件在 2025-11-24 被發布成內含 Shai-Hulud 2.0 蠕蟲的版本。
  • 入侵起點是 PostHog 一個使用 pull_request_target、卻執行 PR 程式的 GitHub Actions 工作流程。
  • 惡意程式在安裝時透過 preinstall 腳本執行,會竊取憑證並試圖感染更多套件。
  • PostHog 表示不知道有客戶正式環境使用了惡意版本。

尚未確認 / 說法不一

  • PostHog 沒有公布完整的受影響套件清單:檢討報告只列「最相關」的 8 個套件(共 10 個版本),issue 另加上 @posthog/wizard,合計 9 個;OSV 則把 56 個 PostHog 套件列為惡意(本頁依 2026-09-28 的查詢整理,可能仍不完整)。
  • 下架後是否還會從 lockfile、本機快取或內部鏡像重新裝回惡意版本:PostHog 與 GitLab 建議清除快取,但來源沒有直接說明這種情況,本頁把它視為受影響是 PlainCVE 的判斷。
  • 各套件實際從 npm 刪除的時間:PostHog 說 09:30 UTC 前,但 npm registry 記錄 posthog-docusaurus 最後修改於 09:57 UTC、posthog-plugin-hello-world 於 14:11 UTC,registry 沒有直接記錄刪除時間。
  • 整波攻擊規模各家說法不一:從約 490 到約 800 個套件不等。
  • 惡意 PostHog 版本在上架期間被下載了多少次,沒有來源提供。
  • posthog-docusaurus、@posthog/core 等大多數套件沒有官方逐一指名的安全版本。

可引用的一句話

這次被攻破的不是 PostHog 的產品,而是替它發布產品的那條自動化流水線。

圖片

下載分享圖(PNG) · 攻擊流程圖(可下載)

引用時請標示「PlainCVE」並附上本頁連結。 完整引用格式見下方「如何引用本頁」。有事實錯誤請回報.

如何引用本頁

本文採 CC BY 4.0,轉載請保留署名與連結。

PlainCVE 團隊(2026)。《PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖》。PlainCVE。https://plaincve.date/vulns/mal-2025-190925-posthog-npm-shai-hulud-2(查閱日期:YYYY-MM-DD)
BibTeX
@misc{mal2025190925posthognpmshaihulud22026,
  title  = {PostHog 官方 npm 套件遭植入 Shai-Hulud 2.0 蠕蟲:一個設定不當的 GitHub 工作流程,讓攻擊者拿到發布權杖},
  author = {PlainCVE 團隊},
  year   = {2026},
  howpublished = {PlainCVE},
  url    = {https://plaincve.date/vulns/mal-2025-190925-posthog-npm-shai-hulud-2},
  note   = {更新於 2026-09-30}
}