2026年5月18日 14:36 CEST、2200万インストールを誇るVS Code拡張機能「Nx Console」のバージョン18.95.0が悪性コードを含んだ状態でVS Code Marketplaceに公開された。発見から削除まで約11分間の露出で、Microsoftが当初報告した28件のインストール数はNx側の内部アナリティクスにより6000件超と大幅に上方修正された。本マルウェアはGitHub・npm・AWS・HashiCorp Vault・Kubernetes・1Password・そしてClaude Codeの設定ファイルまで含む20種類超の認証情報を自動収集し、macOSにはPythonベースの永続化バックドアを設置する多段階脅威だった。
npmサプライチェーン攻撃の防御フレームワーク全般についてはサプライチェーンセキュリティ完全ガイド2026|攻撃手法・防御ツール・実践チェックリストをご覧ください。
- ・2026年5月18日 14:36〜14:47 CESの11分間にNx Console 18.95.0に悪性コードが混入し公開された。
- ・侵入口はコントリビューターのGitHub Personal Access Tokenの漏洩で、無承認コミットからVSCE_PATを使いMarketplaceに公開。
- ・498KB難読化JSがバックグラウンドプロセスとして起動し、20種類超の認証情報をHTTPS・GitHub API・DNSトンネリングで外部送信。
- ・AI coding assistantのClaude Code設定ファイル(~/.claude/settings.json)を標的にした世界初の既知攻撃。
- ・macOSではGitHub Search APIをC2チャネルに悪用する永続化Pythonバックドアが設置された。
- ・Sigstore統合により窃取したnpm OIDCトークンで正規署名付き悪性パッケージが生成可能。
1. 事件概要:11分間の露出と6000件の感染推定
Nx ConsoleはAngular・React・Vue等のフロントエンドプロジェクトをモノレポ形式で管理するNxビルドシステムのVS Code公式拡張機能だ。2022年代後半から急速に普及し、VS Code Marketplaceにおけるインストール数は2200万件を超える大規模拡張機能である。
今回のインシデントのタイムラインは以下の通りだ(時刻はすべてUTC)。
| 日時(UTC) | 出来事 |
|---|---|
| 2026-05-18 12:30 | 悪性バージョン18.95.0がVS Code Marketplaceにアップロード |
| 2026-05-18 12:33 | OpenVSXがセキュリティスキャン完了後に自動公開 |
| 2026-05-18 12:36 | Nxメンテナへ侵害通知が届く |
| 2026-05-18 12:47 | VS Code Marketplaceから非公開化(露出時間:約11分) |
| 2026-05-18 13:09 | OpenVSXからも非公開化(露出時間:約36分) |
| 2026-05-18 当日 | MicrosoftがVS Code Marketplaceの28件インストールを報告 |
| 2026-05-18 当日 | OpenVSXが41件インストールを報告 |
| 2026-05-20 | Nxの内部アナリティクスで6000件超の拡張機能アクティベーションを確認 |
| 2026-05-20 | Jeff Cross(CEO)がX上で6000件超の可能性を公式発表 |
| 2026-05-21 | 修正版18.100.0以降への即時更新を推奨(公式アドバイザリ更新) |
Microsoftと各プラットフォームが報告した「インストール数(28件・41件)」と、Nx側の「アクティベーション数(6000件超)」の乖離が際立つ。この差はVS Code拡張機能の特性によるものだ。VS Codeはバックグラウンドで拡張機能の自動同期・更新を行うため、Marketplaceのダウンロードカウントが更新される前にすでに多数のVS Codeインスタンスが拡張機能を取得していた可能性がある。
Jeff Crossは2026年5月20日のXへの投稿で次のように述べた:「MicrosoftはMarketplace上の28件のインストールを報告してくれました。しかし私たちの内部アナリティクスでは、悪性バージョンを受け取ったユーザー数が大幅に多い可能性があり、おそらく6000件超かもしれません。実際の影響と露出を引き続き調査していきます」。
OpenVSXでの露出時間がVS Code Marketplaceより長かった(36分対11分)のは、VS Code Marketplaceではメンテナへのリアルタイム通知が機能していたのに対し、OpenVSXは自動セキュリティスキャン後に機械的に公開された後、手動での削除が遅れたためだ。
2. 侵入経路:GitHub認証情報の漏洩とゼロ承認公開
今回の根本原因はシンプルかつ古典的な認証情報の漏洩だ。コントリビューターの1人が過去のセキュリティインシデントでGitHub Personal Access Token(PAT)を漏洩していた。攻撃者はこのPATを使ってnrwl/nxリポジトリへ「孤立した未署名コミット」をプッシュし、そのコミットに含まれるVS Code Marketplace公開トークン(VSCE_PAT)を使って悪性バージョンを公開した。
ここで構造的な問題が浮き彫りになる。1人のコントリビューターが単独で本番リリースを承認なしに実行できたという点だ。Nxチームは今回のインシデントを受けて、「すべてのNx Consoleリリースに2名の管理者承認が必須」となるよう直ちにリリースプロセスを変更した。
悪性コードが拡張機能内でどのように動作したかを簡略化すると次のようになる。
// 拡張機能の activate() エントリポイントに挿入された悪性コード(簡略版)
export async function activate(context: vscode.ExtensionContext) {
// 正規の初期化処理(見た目は通常どおり)
// ...
// 悪性コード:globalState で二重実行を防ぐフラグを確認
const alreadyRan = context.globalState.get('_nx_init_done');
if (!alreadyRan) {
context.globalState.update('_nx_init_done', true);
// VS Code task として難読化コマンドを実行
// npx -y github:nrwl/nx#<dangling_sha> として起動
// ユーザーへの確認なし、バックグラウンドで実行
_launchDetachedPayload();
}
}
この実装の巧妙さは「globalState を使った二重実行防止」にある。VS Codeを再起動しても一度しか動作しないように設計されており、ユーザーが「何か変なことが起きた」と気づきにくい。またnpx -y github:nrwl/nx#<dangling_sha>という形式は、GitHubの特定コミットから直接コードをフェッチするため、Marketplaceのスキャン時点ではペイロードが存在せず検出が困難だった。
3. 悪性ペイロードの技術的詳細
ペイロードは498KBの難読化JavaScriptファイルだ。起動するとまず複数の環境チェックを実行する:
- CPU数の確認(サンドボックス環境を排除)
- 環境変数の検証(CI/CD環境であることを確認または排除)
- ジオロケーションフィルタリング(特定地域を除外)
- ロックファイルの分析(実際の開発環境かを判断)
これらのチェックを通過すると、Bunランタイムをインストールして高速なJavaScript実行環境を確保し、__DAEMONIZED=1環境変数を設定したデタッチドプロセスとして自分自身を再起動する。これにより元のVS Codeタスクが終了しても認証情報収集プロセスはバックグラウンドで継続実行される。
収集されたデータはHTTPS・GitHub API・DNSトンネリングの3系統で暗号化圧縮して外部送信される。このような冗長な外部通信経路の実装は、単一チャネルがブロックされても確実にデータを送出するための高度な設計だ。
攻撃フローを図示すると以下のようになる。
悪性コミットをプッシュ] B --> C[VSCE_PATで
18.95.0を公開] C --> D{ユーザーが
インストール} D --> E[activate関数で
悪性コード実行] E --> F[環境チェック
CPU数/geo/lock確認] F --> G[Bunランタイム
インストール] G --> H[498KB難読化JS
デタッチドプロセス起動] H --> I[20種超の
認証情報を収集] I --> J[HTTPS送信] I --> K[GitHub API送信] I --> L[DNSトンネリング] H --> M[macOSに
cat.py設置] M --> N[LaunchAgent登録
毎時コールバック] N --> O[GitHub Search API
をC2に悪用]
4. 標的となった認証情報の種類と窃取手法
本マルウェアが標的とした認証情報は20種類以上に上る。以下に主要なものを列挙する。
| カテゴリ | 具体的な標的 | 窃取手法 |
|---|---|---|
| バージョン管理 | GitHub PAT、Actions Secrets | ~/.gitconfig、環境変数、~/.ssh/のスキャン |
| パッケージ管理 | npm token、npm OIDC token | ~/.npmrcのスキャン |
| クラウド | AWS access key/secret、GCP credentials | ~/.aws/credentials、IMDSエンドポイント(169.254.169.254)のスキャン |
| シークレット管理 | HashiCorp Vault token | ローカルサービス(127.0.0.1:8200)へのアクセス |
| コンテナ | Kubernetes context、Docker credentials | ~/.kube/config、~/.docker/config.json |
| パスワードマネージャ | 1Password vault内容 | 1Password CLIを通じてvaultをダンプ |
| AI開発ツール | Claude Code設定 | ~/.claude/settings.jsonをスキャン |
| 秘密鍵 | SSH private keys | ~/.ssh/配下の全鍵ファイル |
| 接続文字列 | データベース接続文字列 | 環境変数・設定ファイルをスキャン |
特に注目すべきはClaude Code設定ファイル(~/.claude/settings.json)を標的に含めていることだ。GBHackers等のセキュリティ研究者はこれを「AI coding assistantを意図的に標的にした世界初の既知攻撃」と位置づけている。AI支援開発ツールの普及に伴い、これらのツールの設定ファイルや認証情報がサプライチェーン攻撃の新たな標的になりつつある。
また、マルウェアは/procメモリのスキャンも実行する。これは実行中のプロセスのメモリ空間から認証情報を直接読み取る手法で、ディスク上のファイルに認証情報を保存していない場合も被害を受ける可能性がある。
5. macOSにおける永続化バックドア
macOS環境では、JavaScriptステージの実行後にPythonバックドアが設置される。このバックドアには「kitty」というコードネームが付けられており、以下のファイルとプロセスが生成される。
# macOSでの感染確認コマンド
# バックドアファイルの存在確認
ls -la ~/Library/LaunchAgents/com.user.kitty-monitor.plist 2>/dev/null && echo "感染の可能性あり"
ls -la ~/.local/share/kitty/cat.py 2>/dev/null && echo "感染の可能性あり"
# バックドアプロセスの確認
ps aux | grep -E "cat\.py|__DAEMONIZED" | grep -v grep
# Bun経由で実行されているプロセスの確認
ps aux | grep -E "bun|\.bun" | grep -v grep
# 一時ファイルの確認
ls /var/tmp/.gh_update_state 2>/dev/null && echo "感染の可能性あり"
ls /tmp/kitty-* 2>/dev/null && echo "感染の可能性あり"
LaunchAgentとして登録されたバックドアは毎時1回、GitHub Search APIにクエリを送信する。このクエリの形式はapi.github.com/search/commits?q=firedalazerで、特定のコミットメッセージを検索することでC2コマンドを受信する「デッドドロップリゾルバ」として機能する。
このC2通信は4096ビットRSA署名で保護されたコミットメッセージを使用する。GitHubのAPIはHTTPS経由でアクセスされるため、通常のネットワーク監視では怪しいC2通信として検知されにくい。攻撃者は事前に公開コミットに署名済みコマンドを埋め込んでおき、バックドアがポーリングして取得する仕組みだ。
Linux環境ではsudoersへのインジェクションが試みられることも確認されている。これにより管理者権限を取得し、より深い侵害に繋げようとする意図が読み取れる。
6. Sigstore悪用:正規署名付き悪性パッケージの生成
本マルウェアの最も危険な機能の一つがSigstoreのフル統合だ。マルウェアは窃取したnpm OIDCトークンを使って以下を実行できる。
- Fulcio証明書の発行(サプライチェーン署名用CA)
- Rekor透明性ログへの記録
- SLSA provenanceアテステーションの生成
- in-toto attestationの生成
これらを組み合わせることで、攻撃者は偽の悪性npmパッケージに対して暗号学的に正当な署名を付与できる。セキュリティスキャナーやCI/CDパイプラインが「Sigstoreで署名された信頼できるビルド」と誤認識する可能性がある。
感染環境からnpmパッケージを公開していた開発者は、即座にnpm publish logを監査し、見覚えのないバージョンが公開されていないかを確認する必要がある。
7. 以前のNxエコシステム攻撃との比較
セキュリティ研究者はこれを「Nxエコシステムで1年以内に発生した2度目の標的型攻撃」と指摘している。2025年8月には「s1ngularity」と呼ばれるキャンペーンで複数のnpmパッケージが認証情報窃取マルウェアに感染した事例があった。
今回の攻撃とこれまでの主要なサプライチェーン攻撃を比較すると以下の通りだ。
| 攻撃 | 日時 | 侵入経路 | 露出時間 | 推定感染数 | 主要標的 | 特記事項 |
|---|---|---|---|---|---|---|
| Nx Console 18.95.0 | 2026-05-18 | GitHub PAT漏洩 | 11〜36分 | 6000件超 | 20種超の認証情報 + Claude Code設定 | macOSバックドア・Sigstore悪用 |
| @antv Mini Shai-Hulud | 2026-05-19 | atoolアカウント乗っ取り | 22分(連続公開) | 数万件以上 | AWS・GitHub・K8s等20種超 | 323パッケージ同時汚染・ワーム化 |
| Grafana/TanStack攻撃 | 2026-05 | GitHub Actions OIDC悪用 | 数分 | 数千件 | CI/CDシークレット | PR targetワークフロー悪用 |
| Nx s1ngularity | 2025-08 | 不明 | 不明 | 不明 | npmパッケージ経由 | 最初のNxエコシステム標的攻撃 |
今回の攻撃が特に際立つのは「AI coding assistant設定ファイルの標的化」と「Sigstoreを使った署名偽造機能」の2点だ。前者はAIツールが開発者エコシステムに深く統合されたことを悪用した新しい手口であり、後者は「署名があれば安全」というトラストモデルの根幹を揺るがす。
Grafana Labs GitHubへの不正アクセス全容:TanStack npmサプライチェーン攻撃が侵入経路と公式確認も参照すると、GitHubエコシステム全体でCI/CD認証情報を狙った攻撃が系統的に続いていることがわかる。
8. 自分の環境が感染しているか確認する5ステップ
VS Code拡張機能経由の感染確認は通常のnpmパッケージより複雑だ。以下の手順で確認せよ。
ステップ1:インストールバージョンの確認
# VS Codeのコマンドラインツール経由で確認
code --list-extensions --show-versions | grep -i "angular-console\|nx-console"
# 過去のバージョン履歴はVS Code内の Extensions > Nx Console > Changelog でも確認可能
バージョン18.95.0が表示された場合、または表示されない場合(すでに自動更新された)でも18.95.0が公開されていた期間(2026-05-18 12:36〜12:47 UTC)にVS Codeを使用していた場合は感染の可能性がある。
ステップ2:悪性ファイル・プロセスの確認(macOS)
#!/bin/bash
# Nx Console 18.95.0 感染確認スクリプト(macOS)
echo "=== 悪性ファイルの確認 ==="
for f in \
"$HOME/Library/LaunchAgents/com.user.kitty-monitor.plist" \
"$HOME/.local/share/kitty/cat.py" \
"/var/tmp/.gh_update_state"; do
[ -f "$f" ] && echo "FOUND: $f" || echo "NOT FOUND: $f"
done
# /tmp以下のkittyファイル
ls /tmp/kitty-* 2>/dev/null && echo "FOUND: /tmp/kitty-* files" || echo "NOT FOUND: /tmp/kitty-* files"
echo ""
echo "=== 悪性プロセスの確認 ==="
ps aux | grep -E "(cat\.py|__DAEMONIZED=1)" | grep -v grep | head -5
echo ""
echo "=== ファイルハッシュ確認(VSIXキャッシュ) ==="
# VS Code拡張機能キャッシュ
find "$HOME/.vscode/extensions" -name "*.vsix" 2>/dev/null | while read f; do
sha256sum "$f" 2>/dev/null | grep -i "1a4afce34918bdc" && echo "MALICIOUS VSIX FOUND: $f"
done
ステップ3:ネットワーク通信の確認
/var/log/や~/.local/share/に保存されたDNSログ、または会社のプロキシログで以下のドメインへの通信を確認する。
fulcio.sigstore.dev・rekor.sigstore.dev(Sigstore悪用)bun.sh(Bunランタイムインストール)api.github.com/search/commits?q=firedalazer(C2ポーリング)
9. 緊急対処手順
感染が確認された、または疑われる場合の対処手順を重要度順に示す。
フェーズ1:認証情報の即時ローテーション(最優先)
ネットワークを切断する前に認証情報をローテーションすることが重要だ。ネットワーク切断後は既存トークンの失効操作自体ができなくなる可能性がある。
- GitHub PAT・SSH鍵の全失効と再発行
- npm access tokenの失効と再発行
- AWS access key/secret keyの無効化
- HashiCorp Vault tokenの失効
- Kubernetes configの再発行
- 1Password Emergency Kit(緊急ローテーション)の実行
- Claude Code APIキーの無効化(
~/.claude/settings.jsonが読み取られている可能性) - CI/CDシークレット(GitHub Actions Secrets等)の全更新
フェーズ2:マルウェアの除去
- Nx Consoleを18.100.0以降に更新
- macOSのLaunchAgentを停止・削除
- cat.pyと関連ファイルを削除
- Bunランタイムのアンインストール(不要な場合)
フェーズ3:被害範囲の調査
- GitHubアクセスログの過去48時間分監査(Settings > Security log)
- AWSアクセスログ(CloudTrail)の監査
- npmパブリッシュログの確認(見覚えのないバージョンが公開されていないか)
- CI/CDパイプラインのジョブログの確認
10. Nxチームの対応と再発防止策
Nxチーム・CEO Jeff Crossは今回のインシデントに対して迅速かつ透明性の高い対応を行った。攻撃発覚から数時間以内にGitHubセキュリティアドバイザリ(GHSA-c9j4-9m59-847w)を公開し、その後もXで継続的な調査状況を報告している。
再発防止策として即座に実施された主な変更は:
- 2名管理者承認の義務化:Nx Console全リリースに2名の管理者承認が必須に
- コントリビューター権限の再審査:リリース権限を持つアカウントの最小権限化
- リリースパイプラインの監査:VSCE_PATのアクセス範囲を限定
- 継続的な調査:Microsoft・GitHubと連携して実際の影響範囲を引き続き調査
Renovate・Dependabotの自動PRがマルウェアを運ぶ:開発者が今すぐ確認すべきことで解説しているように、自動化されたリリースパイプラインとOAuthトークンの管理は今や開発チームにとって最重要セキュリティ課題の一つだ。
11. 開発者・組織が取るべき恒久的な対策
今回のインシデントが示す根本的な教訓は「VSCode拡張機能もnpmパッケージと同等のサプライチェーンリスクを持つ」という点だ。以下の対策を組織として実施すべきだ。
拡張機能ガバナンスの確立
業務環境でのVS Code拡張機能の使用は、承認リスト(approved extension list)を作成して管理することが望ましい。特に高い権限(ファイルシステム全体へのアクセス)を要求する拡張機能は個別のリスク評価が必要だ。
シークレット管理のベストプラクティス
~/.claude/settings.jsonや~/.aws/credentials等の設定ファイルにAPIキーや認証情報を平文で保存しないことが重要だ。これらは環境変数またはシステムのキーチェーン(macOS Keychain、AWS Secrets Manager等)経由で管理することで、仮にファイルが読み取られても影響を最小化できる。
CI/CDシークレットの分離
開発マシン上のローカルシークレットとCI/CD環境のシークレットを完全に分離することも有効だ。開発者の個人トークンをCI/CDで使用するという運用は、開発者マシンが侵害された場合にCI/CDが連鎖侵害される直接的なリスクになる。
12. Indicators of Compromise(侵害の痕跡)
公式アドバイザリに記載されているIOCを以下にまとめる。
ファイルシステム(macOS)
~/Library/LaunchAgents/com.user.kitty-monitor.plist~/.local/share/kitty/cat.py/var/tmp/.gh_update_state/tmp/kitty-*
プロセス
pythonでcat.pyを実行しているプロセス- 環境変数に
__DAEMONIZED=1を持つプロセス
ファイルハッシュ(SHA-256)
- 悪性VSIX:
1a4afce34918bdc74ae3f31edaffffaa0ee074d83618f53edfd88137927340b8 - 悪性main.js:
b0cefb66b953e5184b6adb3035e9e267335ac5eabfe1848e07834777b9397b74 - 難読化ペイロード:
e7347d90653efc565f03733a95e9209d78f9cfa81e31ff2b2dd9d48d75a4b8b1 - 正規版18.94.0(参照用):
228a2cf081d4cbea9b91cde14a8f9c4a4d003e7f32431496953fd6bac266f5a3 - 修正版18.100.0(確認用):
cb86f4f223daa54467c7782a0d8607e9c84e2bb633e6f0e51d9a19579e200990
ネットワーク通信
api.github.com/search/commits?q=firedalazer(C2デッドドロップポーリング)fulcio.sigstore.dev(Sigstore証明書発行)rekor.sigstore.dev(透明性ログ)bun.sh/install(ランタイム設置)
まとめ
Nx Console 18.95.0のサプライチェーン攻撃は、わずか11〜36分の露出で6000件超の開発者環境への感染が疑われる高度な攻撃だ。GitHub認証情報の漏洩という「古典的な侵入経路」から始まりながら、498KB難読化JS・macOSバックドア・Sigstore署名偽造・Claude Code設定ファイルの標的化と、現時点で最も高度なサプライチェーン攻撃の一つとして記録されている。
対応の優先順位は明確だ:①認証情報の即時ローテーション、②マルウェアの除去、③被害範囲の調査の順で実施せよ。「28件だから自分は大丈夫」という楽観は禁物だ。Nxの内部アナリティクスが示す6000件超という数字は、今後さらに更新される可能性がある。
VS Code拡張機能は今や最も多くの開発者のマシンにインストールされているサードパーティコードであり、npmパッケージと同等のサプライチェーンリスクとして扱う必要がある。@antv npmに不正コード混入|Mini Shai-HuludがAnt Design可視化323パッケージを22分で汚染の事例と合わせ、2026年5月のサプライチェーン攻撃の波は開発者エコシステム全体への継続的な脅威として認識されるべきだ。
参照ソース
- Compromised Nx Console version 18.95.0 — GitHub Security Advisory GHSA-c9j4-9m59-847w
- Compromised Nx Console 18.95.0 Targeted VS Code Developers with Credential Stealer — The Hacker News
- Compromised Nx Console VS Code Extension Steals Developer and Cloud Secrets — GBHackers
- Jeff Cross (@jeffbcross) X投稿 — 2026-05-20