Back to all posts
Cybersecurity

11分間の悪夢:Nx Console VS Code拡張機能の侵害の裏側

もしあなたが、ローカルのコーディング環境は安全なサンドボックスだと思っているなら、信じられないほど悪い知らせがあります。2026年5月18日、開発者コミュニティは残酷なセキュリティの衝撃で目を覚ましました。Nx Console(220万以上のインストールを誇るVisual Studio Codeの拡張機能)が、洗練されたサプライチェーン攻撃でハイジャックされました。

TeamPCP として追跡されている脅威グループは、Visual Studio MarketplaceとOpen VSX Registryの両方に、汚染されたアップデート(v18.95.0)を正常に公開しました。Nxのメンテナーは並外れたスピードで行動し、VS Marketplaceでは 11分以内 、Open VSXでは 36分以内 に拡張機能をパージ(削除)してパッチを当てましたが、被害はすでに発生していました。あるGitHubエンジニアのワークステーションが自動的に不良アップデートを取得し、それによって攻撃者が約3,800の内部GitHubリポジトリに侵入し、データを流出させる足場が作られました。

私は過去2日間、エクスプロイトのベクトルを分析しました。これがどのように起こったのかを分解し、「Orphan Commit(孤児コミット)」ローダーを再構築し、なぜローカルのAI開発者キーが新たな価値の高いターゲットになっているのかを検証し、ローカルのセットアップをロックダウンするための私の推奨する具体的な戦略について議論しましょう。


侵害チェーンの解体

現実を直視しましょう。これは単純なタイポスクワッティング(スペルミスを狙った攻撃)や依存関係の混乱攻撃ではありませんでした。悪意のあるアクターは、公式のリリースのパイプラインそのものを侵害しました。

最初の侵害はNxのリポジトリで始まったのではありません。そうではなく、連鎖的なものでした。TeamPCPは以前、TanStack エコシステムの貢献者を侵害していました。その入り口を通じて、公式の nrwl/nx リポジトリに対する書き込み権限を持つ開発者のGitHub CLI OAuthトークンを流出させました。

TeamPCPは、目立つプルリクエストを開いたり、main に直接プッシュしたり(ブランチ保護のアラームをトリガーする)する代わりに、見事でステルス性の高いベクトルを使用しました:Orphan Commit(孤児コミット) です。

                           [ TanStackエコシステムの侵害 ]
                                        │
                         (GitHub OAuthトークンの流出)
                                        │
                                        ▼
                   [ nrwl/nx リポジトリへの書き込みアクセスの悪用 ]
                                        │
              (Gitツリーに直接作成されたステルスOrphan Commit)
                                        │
                                        ▼
           [ 悪意のあるNx Console VS Code拡張機能 (v18.95.0) ]
             (Orphan Commitを取得する静的URLを含めて事前コンパイル済み)
                                        │
                                        ▼
             [ Visual Studio Marketplace / Open VSX で公開 ]
                                        │
                                        ▼
                 [ 開発者マシンの自動アップデート / 実行 ]

Orphan Commit(孤児コミット)とは何か?

Orphan Commitとは、名前付きブランチ、タグ、またはアクティブな参照ツリーのいずれにもアタッチされていない、リポジトリのオブジェクトストアに直接プッシュされたコミットのことです。

Gitはコンテンツアドレス可能であるため、低レベルの配管(plumbing)コマンドを使用してコミットを作成およびプッシュできます。main ブランチのコミット履歴やアクティブなブランチリストには表示されませんが、コミットはリポジトリのオブジェクトストアに生き残っています。正確なコミットSHAを知っている人なら誰でも、コードにアクセスしたり、GitHubのraw CDNから直接コードを取得したりできます。

# Gitでルーズオブジェクト(loose objects)を照会する:コミットが孤立していても、
# それは保存されており、GitHub rawから直接照会したり取得したりできます。
git cat-file -p <orphan_commit_sha>

TeamPCPは、シンプルなローダーで悪意のある拡張機能を構築しました。インストールされると、公式の nrwl/nx リポジトリにアクセスし、この隠されたOrphan Commitから二次ペイロードを取得しました。静的分析ツールやファイアウォールから見ると、このネットワークリクエストは完全に無害に見えました:公式で検証済みのリポジトリからコードを取得している、公式のMicrosoft VS Code拡張機能。

メモリにロードされると、二次ペイロードが実行され、即座にローカルの認証情報収集プログラム(ハーベスター)が起動しました。


AI API シークレットをロックダウンする

従来、開発者の認証情報を盗む者は、標準的な環境変数を探します:AWSアクセスキー、NPM公開トークン、SSHキー、およびデータベースの認証情報を含む .env 設定などです。

しかし、私がTeamPCPのv18.95.0ペイロードをセキュリティ分析したところ、明確で現代的な方向転換が明らかになりました:AI開発者アシスタントの認証情報の自動収集 です。

このマルウェアは、ローカルの設定パスで、アクティブなターミナルベースおよびIDEベースのAIエージェントを明確に検索しました。これには以下が含まれます。

  • ~/.config/claude-code/config.json (APIキーとセッショントークンを含むClaude Codeの設定ファイル)
  • ~/.config/github-copilot/
  • ~/.gemini/ APIの設定とキー
  • VS Code Copilotトークンを含むIDEの安全なストレージフォルダ

なぜAIキーが新たなプレミアムターゲットなのか

理由はこうです。ソフトウェアエンジニアリングがエージェント型(agentic)環境を採用するにつれて、開発者はターミナルセッション内で直接Claude Codeのような特権の高いAIユーティリティを日常的に実行するようになっています。これらのツールには、多くの場合、ファイルの書き込み、テストの実行、ターミナルコマンドの実行権限が付与されています。

もし攻撃者がAWSキーを盗んだ場合、彼らはクラウドのコンピューティングアクセスを取得します。もし攻撃者があなたのアクティブな Claude Code セッションキー を盗んだ場合、彼らはあなたのリポジトリに対するインタラクティブでエージェント型のコンソールを取得します。エージェントは、あなたのプライベートコードベース全体を読み取り、論理的な欠陥を特定し、サイレントなバックドアを記述し、プルリクエストを送信し、あなたの名前で変更をコミットするように指示される可能性があります。

脅威アクターにとって、アクティブなAI開発者トークンは究極のピボットキー(侵入の拠点となるキー)なのです。


安全な防御的ワークスペースを構築する

現代の開発ワークスペースを保護するには、IDEが安全なサンドボックスであるという仮定から脱却する必要があります。以下は、あなたのマシンを保護するための私の実用的なプレイブックです。

ワークスペースのDev Containersを強制する:

開発者は、自分のローカルマシンを信頼できない環境として扱うべきです。ホストマシンの環境変数にフルアクセスできるIDEを実行するのではなく、Dev Containers またはコンテナ化された実行ループを使用してください。

環境を devcontainer.json の設定でラップすることで、実際のシークレットキーを分離します。

// devcontainer.json (私の標準的な安全なコンテナのセットアップ)
{
  "name": "Secure Node Workspace",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/common-utils:2": {}
  },
  "containerEnv": {
    "AWS_ACCESS_KEY_ID": "${localEnv:AWS_ACCESS_KEY_ID}" // ローカルの認証情報をマスクしたままにする
  },
  "customizations": {
    "vscode": {
      "settings": {
        "extensions.autoUpdate": false // 拡張機能が私の知らない間に自動更新されるのを防ぐ
      }
    }
  }
}

プロのヒント:ビヨンセの法則を有効にしておく

開発者の認証情報に関するビヨンセの法則がここに適用されます:もしそれが気に入っていたなら、鍵をかけておくべきだった。 自動化されたシステムに、一般的な個人アクセストークン (PAT) を絶対に使用しないでください。パッケージのメタデータに対する読み取り専用の権限を持ち、特定のリポジトリに制限されたきめ細かいトークン(fine-grained tokens)を実装してください。


結論(ボトムライン)

コード生成は公式に解決された問題となり、実際のエンジニアリングの戦場は今や 認証情報のオーケストレーションと封じ込め(containment) に移っています。IDE拡張機能に盲目的に自動更新させるのをやめ、ワークスペースをコンテナに分離し、ローカルのAI設定を保護してください。


参考文献および公式情報源