【続報】TeamPCP が GitHub 内部リポジトリ3,800件を流出 - 汚染 VS Code 拡張と npm staged publishing

【続報】TeamPCP が GitHub 内部リポジトリ3,800件を流出 - 汚染 VS Code 拡張と npm staged publishing

作成日:
更新日:

はじめに: あの TanStack 事件の「続き」です

先日、2026年5月11日の TanStack npm サプライチェーン攻撃 を整理しました。あの攻撃は、攻撃グループ TeamPCP による2026年5月のキャンペーンの「入口」に過ぎませんでした。

その約1週間後、同じ TeamPCP が汚染した VS Code 拡張を経由して GitHub 従業員の端末を侵害し、GitHub の内部リポジトリ約3,800件を流出させるという事態に発展しました。npm パッケージを汚染する攻撃が、ついにプラットフォーム本体(GitHub)にまで届いたわけです。

この記事は TanStack 記事の続報として、攻撃チェーンの後半と、それを受けて npm が投入した防御機構「staged publishing」までを整理します。

事件の概要(早見表)

項目内容
攻撃グループTeamPCP(Google Threat Intelligence は UNC6780 として追跡。別名 PCPcat ほか)
汚染された拡張Nx Console(nrwl.angular-console
悪意あるバージョン18.95.0(直前の正常版 18.94.0 / 修正版 18.100.0
公開時刻2026年5月18日 12:36 UTC
削除時刻同日 12:47 UTC(公開から約11分)
拡張のインストール規模約220万インストール
配布元VS Code Marketplace
流出範囲GitHub 内部リポジトリ 約3,800件(TeamPCP は約4,000件と主張)
GitHub の見解「内部リポジトリの外に保存された顧客情報への影響を示す証拠は現時点でない」
身代金要求最低 5万ドル
関連する前段2026年5月11日の TanStack 攻撃(84バージョン汚染)
npm の対応staged publishing(2FA 承認ゲート)を5月22日に一般提供

注意したいのは、GitHub が「内部リポジトリの外に保存された顧客情報への影響を示す証拠は現時点でない」と表明している点です。これは「本番サービスや顧客データが盗まれた」事件ではなく、「内部のソースコードが流出した」事件です。とはいえ、内部リポジトリには設計上の機微情報が含まれ得るため、軽視できる話ではありません。

TanStack から GitHub までの攻撃チェーン

公開されている各社の分析を時系列で整理すると、次のような連鎖になります。

日付(2026年)出来事
5月11日TeamPCP が TanStack npm パッケージ群を汚染(42パッケージ・84バージョン)。CI/CD から OIDC トークンを窃取
5月18日 12:36 UTC汚染版 Nx Console(18.95.0)が VS Code Marketplace に公開される
5月18日 12:47 UTC約11分後に削除。短時間ながら多数の開発者環境へ到達
5月18〜19日汚染拡張をインストールした GitHub 従業員の端末が侵害される
5月19〜20日TeamPCP が GitHub 内部リポジトリ約3,800件をクローン・流出。最低5万ドルを要求
5月22日npm(GitHub)が staged publishing を一般提供

ひとつ補足しておくと、TanStack で盗まれた OIDC トークンが「そのまま」GitHub 従業員端末の侵害に使われた、という直接の証拠が公開されているわけではありません。各社の分析が示しているのは「同一の攻撃グループによる一連のキャンペーン」という運用上のつながりです。ここは誇張せず、事実として「同じアクターの連続攻撃」と捉えるのが正確です。

攻撃の解剖

なぜ VS Code 拡張が狙われたのか

Nx Console は、Nx モノレポを扱う開発者に広く使われている拡張で、インストール規模は約220万。開発者がほぼ無条件に信頼し、IDE の権限で動く——つまり、開発者の「信頼の面(trust surface)」そのものが攻撃対象になりました。

npm パッケージの postinstall と同じ発想です。「正規の人気ツールのアップデート」という皮をかぶせれば、レビューを通り抜けて多数の開発環境へ一気に展開できる。axios 事件React2Shell の被害事例 と地続きの手口が、配布チャネルを VS Code Marketplace に変えて再現された形です。

ペイロードが何をしたか

汚染版に注入されたコードは、複数の窃取クラスを並列に動かしていたと報告されています。

  • Vault トークン、npm 認証情報、AWS メタデータ、GitHub トークン、ファイルシステム上の秘密、1Password の保管庫——これらを並列に収集
  • GitHub Actions の Runner.Worker プロセスのメモリを走査し、isSecret:true でマスクされた値(=CI 上のシークレット)を抽出
  • npm の Trusted Publishing フローを通じて OIDC トークンを交換し、下流パッケージの公開に悪用
  • ~/.local/share/kitty/cat.py に Python 製の C2 バックドアを設置し、GitHub Search API を1時間ごとにポーリングして指令を受信

TanStack 事件で見られた「正規ランナー内の OIDC トークン抽出」という発想が、今回は IDE 拡張という別経路から再び使われている点が重要です。

信頼の連鎖が壊れる仕組み

この攻撃が厄介なのは、各ステップが「正規の仕組み」を悪用している点です。拡張は正規の Marketplace から、OIDC トークンは正規の Trusted Publishing フローから、コミットは正規の認証情報から。署名や provenance は「正しく」機能しているのに、その内側で攻撃者のコードが走っている——TanStack 記事で書いた「配送伝票は本物だが倉庫の中で中身がすり替わっている」構図が、より上流で繰り返されています。

GitHub の対応: npm staged publishing

この一連の攻撃で繰り返し悪用されたのが「盗んだ CI/CD トークン(OIDC トークン)で、人間の承認を介さずに npm へ公開できる」という穴でした。GitHub は2026年5月22日、これを塞ぐために staged publishing を一般提供しました。

仕組み: 公開とダウンロード可能化の間に 2FA を挟む

staged publishing は、npm publish の「公開」と「実際にインストール可能になる」瞬間の間に、必須の 2FA チェックポイントを挿入します。

  1. 公開側は npm stage publish を実行し、tarball をステージング待ち行列にアップロードする
  2. メンテナーが 2FA で認証し、npm stage approve(または Web UI)で承認する

この2段階目が完了するまで、利用者はそのバージョンをインストールできません。

なぜ盗難 OIDC トークンを止められるのか

肝は、承認操作が自動化資格情報・OIDC トークン・非対話な経路では完了できない点です。承認を満たせるのは「生きた 2FA チャレンジ」だけ。つまり、CI/CD トークンを盗んだだけの攻撃者は、ステージングまではできても「公開」できません。TeamPCP が多用した攻撃ベクタを、設計レベルで遮断する狙いです。

移行で必要なこと

staged publishing への移行イメージ
# npm CLI を 11.15.0 以上へ更新
npm install -g npm@latest
 
# CI/CD の publish を stage publish に置き換える
# 旧: npm publish
npm stage publish
 
# 承認は人間が 2FA で(自動化からは不可)
npm stage approve

GitHub は、Trusted Publishing を「stage-only」に構成し、自動化はステージングまで・公開は人間の 2FA で、という運用を推奨しています。npm publish をそのまま CI に残している場合は、npm stage publish への置き換えが必要になります。

[!WARNING] staged publishing は OIDC トークン窃取のベクタを塞ぎますが、万能ではありません。メンテナー自身の端末が侵害され、2FA セッションごと乗っ取られれば突破され得ます。今回のように IDE 拡張で端末そのものを獲られるケースには、端末側の防御(拡張の精査・最小権限)が別途必要です。

開発者が今すぐやること

今回の事件は「自分が公開側でなくても」関係があります。汚染拡張をインストールしていた可能性があるためです。

  • VS Code / Cursor の Nx Console(nrwl.angular-console)のバージョンを確認し、18.95.0 を使っていないか点検する。該当する場合は修正版 18.100.0 以上へ更新し、端末上の各種トークン(GitHub・npm・AWS・1Password 等)をローテーションする
  • ~/.local/share/kitty/cat.py のような見覚えのないファイルや、不審な常駐プロセス・通信がないか確認する
  • CI/CD の npm 公開を staged publishing(stage-only Trusted Publishing)へ移行する
  • 拡張機能の自動更新を見直す。人気拡張でも「直近に公開されたばかりのバージョン」には数時間〜1日のクーリング期間を置く運用を検討する
  • 普段から、axiosTanStack 事件で整理した lockfile 監査・最小権限・新規バージョンの様子見を徹底する

まとめ

  • TanStack 事件(5月11日)と同じ TeamPCP(UNC6780)が、汚染 VS Code 拡張 Nx Console(18.95.0、約11分公開)を経由して GitHub 従業員端末を侵害
  • GitHub 内部リポジトリ約3,800件が流出。ただし GitHub は内部リポジトリ外の顧客情報への影響は確認されていないとしている
  • 攻撃は「正規の拡張・正規の OIDC・正規の署名」を悪用する信頼面への攻撃。署名や provenance は機能していても内側が汚染される
  • npm は5月22日に staged publishing を一般提供。公開とダウンロード可能化の間に「人間の 2FA 承認」を必須化し、盗難 OIDC トークン単体での公開を遮断
  • 公開側でなくても、汚染拡張のインストール有無の点検とトークンのローテーションは必須

npm パッケージを汚染する攻撃が、その npm を運営する GitHub の内部にまで到達した——というのが、この事件の不気味さです。「依存を入れる」「拡張を入れる」という日常動作が、そのまま攻撃面になっていることを改めて突きつけられました。

参考リンク