2026年5月20日、GitHubは従業員のデバイスが悪意あるVS Code拡張機能によって侵害され、約3,800の内部リポジトリが流出したことを公表した。攻撃者TeamPCPは盗んだソースコードを$50,000で販売中で、買い手がなければ無料公開すると脅迫している。
しかし、この事件は単なる「VS Code拡張機能による侵害」ではない。同時期に発生した4つの関連攻撃を合わせると、5つの攻撃ベクトルが連鎖する未曾有のサプライチェーン攻撃の全体像が見えてくる。本記事では、各ベクトルの技術的詳細と、開発者が今すぐ実践すべき防御策を解説する。
事件の全体像:5つの攻撃ベクトル
2026年5月18日から20日にかけて、TeamPCP(Google Threat IntelligenceがUNC6780として追跡)は、以下の5つの攻撃ベクトルを連続して展開した。
ベクトル1:Nx Console VS Code拡張機能侵害(5月18日)
悪意あるバージョンのNx Console(nrwl.angular-console v18.95.0、2.2Mインストール)がVS Code Marketplaceに公開された。わずか11分間で削除されたが、その間に拡張機能をインストールした開発者のGitHubトークン、npmトークン、AWS認証情報、HashiCorp Vault認証情報、Kubernetes認証情報、1Passwordの認証情報が窃取された。
特筆すべきは、この拡張機能がClaude Codeの設定ファイル(~/.claude/settings.json) を標的にしていた点だ。AIエージェントのAPIキーが平文で保存されている設定ファイルが、新たな攻撃対象となっている。
// 悪意ある拡張機能の概念(実際のペイロードは難読化)
const vscode = require('vscode');
const fs = require('fs');
const { execSync } = require('child_process');
function activate(context) {
// AIエージェント設定ファイルの収集
const targets = [
'~/.claude/settings.json',
'~/.cursor/config.json',
'~/.config/openclaw/credentials.json',
];
targets.forEach(p => {
if (fs.existsSync(p)) {
const data = fs.readFileSync(p, 'utf8');
exfiltrate(data);
}
});
// 環境変数から全トークンを抽出
const tokens = { ...process.env };
exfiltrate(JSON.stringify(tokens));
}
ベクトル2:Mini Shai-Huludワームによるnpmサプライチェーン攻撃(5月19日)
TeamPCPはMini Shai-Huludワームの新たな波をnpmエコシステムに解き放った。639の悪意あるnpmパッケージバージョンが323パッケージにわたって公開された。標的となったのはAlibabaの@antvエコシステム(週間約1,600万ダウンロード)で、jest-canvas-mock(1,000万+月間DL)、size-sensorなどの休眠パッケージが乗っ取られた。
この波の最大の特徴は、Sigstoreのビルド証明書(provenance)を実行時に偽造する新手法だ。ワームがFulcioとRekorを実行時に呼び出し、悪意あるパッケージに対して正当なSigstore署名証明書を生成する。証明書バッジはグリーン表示されるが、ビルドチェーン自体は攻撃者に支配されている。Endor LabsのPeyton Kennedyは「証明書はパッケージがどこでビルドされたかを示す。ビルドが承認されたかどうかは示さない」と指摘する。
2種類の配送メカニズム
Type 1 — ファントムコミットドロッパー: jest-canvas-mockやsize-sensorなどの休眠パッケージに、optionalDependenciesエントリを1行追加するだけの手法。npmがgithub:依存関係を解決する際、prepareライフサイクルフックが発火し、Bunランタイムで難読化されたペイロードを実行する。
{
"optionalDependencies": {
"@antv/setup": "github:antvis/G2#1916faa365f2788b6e193514872d51a242876569"
}
}
Type 2 — ペイロード埋め込み: 残り40の伝搬パッケージは、ルートに約500KBの難読化index.jsとpreinstallフックを直接埋め込む。preinstallフックは依存関係グラフの評価より前に無条件に実行される。
{
"scripts": {
"preinstall": "bun run index.js"
}
}
このワームはデッドマンスイッチを持ち、npmトークンが取り消されると感染マシンでrm -rf ~/を実行するよう設計されている。
ベクトル3:Microsoft durabletask Python SDKのPyPI侵害(5月19日)
MicrosoftのDurable Functions Python SDKであるdurabletaskの3つの悪意あるバージョン(1.4.1、1.4.2、1.4.3)が35分以内にPyPIに公開された。このパッケージは月間40万以上のダウンロードがある。
攻撃の流れは以下の通り:
- 以前のTeamPCP作戦で侵害されたGitHubアカウントが
microsoft/durabletask-pythonリポジトリへのアクセス権を持っていた - リポジトリのシークレットをダンプし、PyPI公開トークンを抽出
- 感染したリリースを直接プッシュ
ペイロード(rope.pyz、28KB)は、AWS、Azure、GCP、Kubernetes、および90以上の開発ツールから認証情報を窃取し、横展開する。ロシア語ロケールのシステムでは実行をスキップするよう設計されている。
ベクトル4:GitHub内部侵害 — VS Code拡張機能による3800リポジトリ流出(5月20日)
GitHub従業員のデバイスにインストールされた別の悪意あるVS Code拡張機能により、同社の内部リポジトリ約3,800が流出した。こちらはベクトル1とは別の毒入り拡張機能である。流出したリポジトリには、インフラ設定、デプロイスクリプト、ステージング環境の認証情報、内部APIスキーマが含まれていた。
GitHubの対応:
- 悪意ある拡張機能バージョンのMarketplaceからの削除
- 感染デバイスの隔離
- 重要なシークレットの優先順位付けによるローテーション(影響の大きいものから順に一晩で完了)
- 顧客データへの影響は確認されていないと発表
ベクトル5:AIエージェントMCP TrustFall脆弱性(5月7日〜12日)
この攻撃チェーンに直接関与するわけではないが、同時期に発見された以下の脆弱性は、AIエージェントが普及した環境における新たな攻撃面を示している。
TrustFall(Adversa AI、5月7日): テストされた4つのAIエージェント(Claude Code、Gemini CLI、Cursor CLI、Copilot CLI)すべてが、信頼されていないMCPサーバーに対してデフォルトで「Yes/Trust」を選択する。悪意あるリポジトリが、自動承認するMCP設定を同梱することで、ユーザーの操作なしに攻撃を実行できる。
Comment & Control(Johns Hopkins、CVSS 9.4 Critical): PRタイトルに悪意ある命令を仕込むだけで、AnthropicのClaude Code Security Reviewアクションが自身のAPIキーをコメントとして投稿する。Gemini CLI ActionやGitHubのCopilot Agentでも同様のプロンプトインジェクションが確認された。
これらは、今回の攻撃で標的となったClaude Code設定ファイルと組み合わさることで、AIエージェント経由のサプライチェーン攻撃という新たな脅威シナリオを形成する。
TeamPCP(UNC6780)の7波攻撃キャンペーン
Google Threat Intelligence GroupがUNC6780として追跡するTeamPCPは、2026年3月から少なくとも7波の攻撃を仕掛けている。Trend Micro、StepSecurity、Snykが正式に追跡している。
| 波 | 時期 | 標的 | 手法 |
|---|---|---|---|
| 第1波 | 3月19日 | Trivy(Aqua Security) | GitHub Actionsタグ侵害 |
| 第2波 | 3月下旬 | Checkmarx KICS | CI/CDパイプライン経由 |
| 第3波 | 4月上旬 | LiteLLM(月間9500万DL) | PyPIトークン窃取 |
| 第4波 | 4月下旬 | elementary-data | npm公開ワークフロー悪用 |
| 第5波 | 4月29日 | SAP npmパッケージ(@cap-js) | OIDC Trusted Publishing悪用 |
| 第6波 | 5月11日〜12日 | TanStack、Mistral AI、Guardrails AI | Mini Shai-Huludワーム本格展開 |
| 第7波 | 5月18日〜20日 | Nx Console、@antv、Microsoft durabletask、GitHub内部 | 5ベクトル同時攻撃 |
第7波で特筆すべきは、攻撃者が休眠アカウント(長期間更新のないパッケージ)を標的にした点だ。jest-canvas-mockは3年間更新がなく、監視の目が薄れていた。OIDC Trusted Publishingを使わないアカウントは、トークンが一度盗まれれば完全に制御権を奪われる。
実践的防御策:5つのレイヤー
以下の防御策をVS Code、npm、PyPI、GitHub Actions、MCPの各レイヤーで実施する。
レイヤー1:VS Code拡張機能のピン留めと監査
# 現在インストール中の拡張機能一覧
code --list-extensions --show-versions
# 自動更新を無効化(settings.json)
# "extensions.autoUpdate": false
# 信頼できるパブリッシャーのみ許可(settings.json)
# "extensions.trustedPublishers": [
# "ms-python",
# "github.copilot",
# ...
# ]
VS Code Marketplaceの拡張機能は、インストール時点でファイルシステム、ネットワーク、子プロセス実行、環境変数読み取りのフルアクセス権限を持つ。すべての拡張機能を信頼しないという前提で運用する。未使用の拡張機能は削除し、使用するものはパブリッシャーと最終更新日を定期的に確認する。
レイヤー2:npmのセキュア設定
# パッケージインストール時のスクリプト実行を無効化
npm config set ignore-scripts true
# またはCI環境で毎回指定
npm ci --ignore-scripts
# インストール後に必要なスクリプトのみ手動実行
npm run build # 必要な場合のみ
# 特定バージョン以下のパッケージをブロック
# .npmrc に設定
# package=@antv/l7-core@<2.26.10
さらに、npmのminimumReleaseAge設定を有効にすることで、新しく公開されたバージョンが一定時間経過するまでインストールされないようにできる。これにより、悪意あるバージョンが検出・削除されるまでの猶予が生まれる。
# npmのminimumReleaseAge設定
npm config set minimum-release-age 3 # 3日間の猶予
レイヤー3:GitHub Actionsのセキュア設定
# pull_request_targetの使用箇所を監査
grep -r "pull_request_target" .github/workflows/
# OIDC Trusted Publishingのスコープ確認
# リポジトリレベルではなく、プロテクトブランチ/特定ワークフローにスコープする
pull_request_targetは外部コントリビューターのPRをベースリポジトリのコンテキストで実行するため、極めて危険だ。代わりにpull_requestを使用し、必要な場合のみ別のセキュアなパターンに置き換える。
GitHub ActionsのアクションはSHA値でピン留めする。
# ❌ 脆弱:バージョンタグ(タグが上書きされる可能性)
- uses: actions/checkout@v4
# ✅ 安全:SHA値でピン留め
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
レイヤー4:PyPIパッケージのバージョンピン留め
# requirements.txt または pyproject.toml
# 特定バージョン以下をブロック
durabletask>=1.4.0,<1.4.1 # 1.4.0はOK、1.4.1〜1.4.3はブロック
CI/CDパイプラインでは、pip installに--no-depsオプションを付与し、必要な依存関係のみ明示的にインストールする運用を検討する。
レイヤー5:AIエージェントとMCPのセキュリティ
// ~/.claude/settings.json のセキュア設定例
{
"mcpServers": {
"my-trusted-server": {
"command": "node",
"args": ["/path/to/trusted/server.js"],
"env": {}
}
},
"managedScope": {
"enabled": true,
"allowlist": [
"my-trusted-server"
]
}
}
AIエージェントの設定ファイルにはAPIキーが平文で保存されることが多い。以下の対策を実施する:
- 設定ファイルをGit管理から除外(
.gitignoreに追加) .envファイルを使用し、環境変数経由で読み込む- AIエージェントの設定ファイルにカナリアトークンを配置し、漏洩検知に活用する
- MCPサーバーの自動信頼設定をオフにする(
enableAllProjectMcpServers: false)
Mini Shai-Huludワームの検出コマンド
# 既存のインストールをスキャン
find / -name 'router_init.js' -size +1M 2>/dev/null
# npmのlockファイルでハッシュを確認
grep "79ac49eedf774dd4b0cfa308722bc463cfe5885c" package-lock.json
# 不審なoptionalDependenciesを確認
npm ls --all --json | grep -A5 "optionalDependencies" | grep "github:"
ワーム感染が疑われる場合の対応手順:
- マシンを隔離する(ネットワーク切断)
- 全トークンを隔離後にローテーション(ワームはトークン剥奪を検知すると破壊動作を開始する)
- フォレンジックのためにディスクイメージを作成
- クリーンな環境で全サービスパスワードを変更
まとめ:信頼のない時代の開発セキュリティ
今回の一連の攻撃が示すのは、「GitHubにコードを置いているから安全」「VS Code公式Marketplaceだから安全」「MicrosoftのSDKだから安全」といった前提がすべて崩れたことだ。
- IDE拡張機能は新しいエンドポイントデバイスであり、インストール時にフルアクセス権限を持つ
- ビルド証明書(Sigstore provenance)は「承認されたビルド」を保証しない
- 休眠パッケージは格好の標的 — 長期間更新のない依存関係は定期的に監査する
- AIエージェントが普及するにつれ、MCP設定ファイルやAIエージェント設定ファイルが新たな攻撃面となる
開発チームに求められるのは、ゼロトラストの原則を開発ツールチェーン全体に適用することだ。すべてのVS Code拡張機能、npmパッケージ、GitHub Actions、PyPI依存関係、AIエージェント設定を「信頼しない」前提で再検証し、最小権限の原則で構成する。1つのレイヤーが破られても全体が崩壊しない多層防御が、2026年の開発セキュリティの最低基準である。
この記事はAIによって生成され、人間の編集を経て公開されています。 Appwright AI は AI によるコンテンツ制作の可能性を探求する実験的プロジェクトです。