Microsoftの悪性npmパッケージ警告を解説:dependency confusionの影響範囲と確認ポイント

Microsoftが公開した「Malicious npm packages abuse dependency confusion to profile developer environments」は、Microsoft製品の機能変更や通常の更新プログラムではなく、npmのdependency confusionを悪用したサプライチェーン攻撃に関する公式脅威情報です。結論から言うと、npmを使う組織は、影響スコープの依存関係、.npmrcのレジストリ設定、postinstallなどのインストール時スクリプト、CI/CDや開発端末に保存されたシークレットを優先的に確認する必要があります。

特に注意すべき点は、今回の攻撃が「アプリ実行時」ではなく、npm installのタイミングで動くことです。開発者がコードを読み込まなくても、悪意あるパッケージがインストールされるだけで偵察用ペイロードが実行される可能性があります。Microsoftは、攻撃者が実在企業の内部名前空間に似せたnpmパッケージを公開し、開発者端末やビルド環境からホスト名、環境変数、開発環境の情報を収集していたと説明しています。(Microsoft)

目次

Microsoftの公式情報で示された「変更点」は何か

今回の情報を、Microsoft 365やWindowsのような製品アップデートとして捉えると誤解しやすくなります。実際に変わるのは、ユーザー向け機能ではなく、管理者と開発チームが確認すべきセキュリティ運用の優先順位です。

Microsoftの公式ブログでは、攻撃者が3つのnpmメンテナー名義を使い、複数の組織スコープにまたがって悪意あるパッケージを公開したと説明されています。パッケージは、GitHub Enterprise、Jira、社内ドキュメントポータルのように見えるメタデータをpackage.jsonに設定し、正規の社内パッケージに見えるよう偽装していました。(Microsoft)

管理者や開発者にとっての実務上の変更点は、次の3つです。

確認すべき変化実務での意味優先度
npmの依存関係確認が必要package.jsonだけでなく、package-lock.jsonyarn.lockpnpm-lock.yamlまで確認する
.npmrcのスコープ設定が重要社内スコープが公開npmレジストリへ解決されないようにする
インストール時スクリプトの扱いを見直すpostinstallで任意コードが動く前提で、CI/CDや端末の権限を絞る
Defender XDRやプロキシログでの検出C2通信、Node.jsプロセス、tmp/cache配下の不審ファイルを探す中〜高
シークレットのローテーション影響端末・ビルド環境に置かれていたnpmトークン、クラウド資格情報、CI/CDシークレットを再発行する

この情報は、単に「悪性npmパッケージが削除されたか」を見るだけでは不十分です。過去にインストール済みの端末、ビルドキャッシュ、生成済みアーティファクト、CI/CDログまで確認する必要があります。

dependency confusionとは何か

dependency confusionは、社内向けに使っているパッケージ名やスコープに似せた、または同じ名前のパッケージを公開レジストリに置き、設定ミスや解決順序の問題を悪用してインストールさせる攻撃です。

たとえば、社内で@mycompany/internal-authという非公開パッケージを使っているとします。本来は社内レジストリから取得すべきですが、.npmrcの設定が不十分だったり、ビルド環境が公開npmレジストリへフォールバックしたりすると、攻撃者が公開npm上に用意した同名・類似名のパッケージを取得してしまう可能性があります。

npmではスコープを特定のレジストリに関連付けられます。公式ドキュメントでも、npm config set @myco:registry http://reg.example.comのようにスコープとレジストリを関連付けると、そのスコープのパッケージインストールは指定レジストリへ向かうと説明されています。 (npm ドキュメント)

つまり、今回のような攻撃への基本対策は、「社内っぽい名前のパッケージを信用しない」だけではありません。社内スコープが必ず社内レジストリに解決される設定になっているかを確認することが重要です。

今回の攻撃チェーン

Microsoftが説明する攻撃チェーンは、npmを使う開発現場にとって非常に現実的です。攻撃は、被害者がアプリを起動したタイミングではなく、依存関係をインストールするタイミングで成立します。

段階攻撃内容確認ポイント
パッケージ公開攻撃者が実在企業の内部名前空間に似たスコープでnpmパッケージを公開自社スコープと似た公開パッケージがないか
信頼させる偽装repositoryhomepagebugsなどを社内GitHub、Jira、Docs風に設定package.jsonのメタデータが実在するか
自動実行postinstallフックでnode scripts/postinstall.jsを実行install時スクリプトを許可していないか
ペイロード取得C2サーバーからOS別のペイロードを取得外向き通信ログを確認
端末偵察ホスト名、環境変数、開発者コンテキストなどを収集環境変数に秘密情報を置いていないか
追跡回避cacheディレクトリやrun-onceマーカーで繰り返し実行を抑制~/.cacheやtmp配下の不審ファイルを探す

Microsoftによると、実行の流れはnpm installからpostinstall、難読化されたpostinstall.js、C2へのHTTPS GET、tmpディレクトリへの書き込み、バックグラウンドプロセス起動へ進みます。さらに、ペイロードはWindows、macOS、Linux向けに分岐していました。(Microsoft)

重要なのは、攻撃が「偵察のみ」に見える点です。Microsoftは、今回のキャンペーンで*_RECON_ONLY=1が使われ、環境情報の収集を主目的としていた一方、設計上は後続攻撃で認証情報の窃取やバックドア設置へ進める余地があると説明しています。(Microsoft)

影響範囲:Microsoft利用者全員ではなく、npmを使う開発・ビルド環境が中心

この情報はMicrosoft Security Blogで公開されていますが、影響を受ける可能性が高いのは、Microsoft製品の一般利用者ではありません。主な対象は、npmを利用する開発者、フロントエンド開発チーム、Node.jsを含むビルドパイプライン、CI/CD環境です。

特に、次の条件に当てはまる組織は優先して確認してください。

確認対象該当するケースリスク
開発者端末ローカルでnpm installnpm ciを実行している端末上の環境変数やトークンが露出する可能性
CI/CD runnerGitHub Actions、Azure Pipelines、Jenkinsなどでnpm installを実行しているビルド用シークレットやクラウド資格情報が狙われる可能性
社内npmレジストリ利用環境private registry、proxy registry、artifact feedを使っている公開npmへのフォールバック設定があるとdependency confusionが成立しやすい
lockfileを自動更新する運用Renovate、Dependabot、手動更新などで依存関係を頻繁に更新する高いバージョン番号の悪性パッケージを取り込む可能性
環境変数にシークレットを置く運用NPM_TOKEN、クラウドキー、CI/CDトークンを環境変数で渡している偵察ペイロードから見える可能性

Microsoftは、影響確認の対象として、9つのスコープを挙げています。確認時は、直接依存だけでなく推移的依存、lockfile、ビルドログも対象にします。(Microsoft)

@cloudplatform-single-spa
@wb-track
@data-science
@ce-rwb
@payments-widget
@travel-autotests
@t-in-one
@capibar.chat
@sber-ecom-core

なお、要約では「33個の悪意あるnpmパッケージ」と表現されることがありますが、Microsoftの本文では5月28日の26件と7件に加え、5月29日のt-in-one関連の波も説明されています。実務では件数だけで判断せず、上記スコープ全体を検索対象にしてください。(Microsoft)

管理者が最初に確認すべきこと

まずは、影響を受けた可能性のあるリポジトリ、端末、CI/CD実行環境を洗い出します。いきなり全シークレットをローテーションする前に、どこで該当スコープが参照されたかを確認すると、対応範囲を絞りやすくなります。

リポジトリとlockfileを検索する

Git管理下のリポジトリでは、package.jsonだけでなくlockfileも検索します。lockfileには、開発者が意識していない推移的依存や、実際に解決されたバージョンが残っている場合があります。

rg '@cloudplatform-single-spa/|@wb-track/|@data-science/|@ce-rwb/|@payments-widget/|@travel-autotests/|@t-in-one/|@capibar\.chat/|@sber-ecom-core/' \
  package.json package-lock.json yarn.lock pnpm-lock.yaml .npmrc

Windows PowerShellで確認する場合は、次のように検索できます。

Get-ChildItem -Recurse -Include package.json,package-lock.json,yarn.lock,pnpm-lock.yaml,.npmrc |
  Select-String -Pattern '@cloudplatform-single-spa/|@wb-track/|@data-science/|@ce-rwb/|@payments-widget/|@travel-autotests/|@t-in-one/|@capibar\.chat/|@sber-ecom-core/'

該当が見つかった場合は、単に削除するだけでなく、次の情報を記録します。

記録する情報理由
リポジトリ名・ブランチ影響範囲を特定するため
該当ファイル直接依存か、lockfileだけかを切り分けるため
バージョンMicrosoftが示す悪性バージョンと照合するため
install実行日時2026年5月28日以降の実行有無を確認するため
実行環境開発端末かCI/CDかで対応が変わるため

Microsoftは、2026年5月28日以降に該当パッケージをインストールまたはビルドしたシステムを特定するよう推奨しています。また、@capibar.chat/ui-kit@sber-ecom-core/sberpay-widgetについては、2026年5月4日の事前公開版にも注意が必要としています。(Microsoft)

npmの依存ツリーを確認する

該当リポジトリで、依存ツリーに含まれているかを確認します。

npm ls --all | grep -E '@cloudplatform-single-spa|@wb-track|@data-science|@ce-rwb|@payments-widget|@travel-autotests|@t-in-one|@capibar.chat|@sber-ecom-core'

PowerShellでは次のように確認できます。

npm ls --all | Select-String -Pattern '@cloudplatform-single-spa|@wb-track|@data-science|@ce-rwb|@payments-widget|@travel-autotests|@t-in-one|@capibar.chat|@sber-ecom-core'

ただし、npm lsは現在のnode_modulesに依存します。過去にCI/CDで一度だけインストールされたケースや、コンテナイメージ内に残っているケースは見落としやすいため、lockfile、ビルドログ、アーティファクトの確認も併用してください。

.npmrcで確認すべき設定

dependency confusion対策の要は、社内スコープを公開npmへ解決させないことです。npm公式ドキュメントでは、.npmrcはプロジェクト、ユーザー、グローバル、組み込み設定の順に扱われ、プロジェクトルートの.npmrcでプロジェクト固有の設定を行えると説明されています。(npm ドキュメント)

自社の内部パッケージスコープがある場合は、プロジェクト直下の.npmrcに明示的なレジストリ設定を置くのが基本です。

@your-org:registry=https://registry.example.com/npm/
//registry.example.com/npm/:_authToken=${NPM_TOKEN}

悪い例は、社内スコープを明示せず、デフォルトレジストリだけに依存している設定です。

registry=https://registry.npmjs.org/

この状態では、社内向けに見えるスコープでも、設定や環境によって公開npmへ解決される余地があります。特に複数のレジストリを使う組織では、ローカル端末、CI/CD、Dockerfile、開発コンテナ、社内テンプレートの.npmrcが一致しているかを確認してください。

.npmrcのチェックポイント

チェック項目OKの状態注意が必要な状態
社内スコープのregistry指定@your-org:registry=...があるデフォルトregistryだけ
認証トークンのスコープレジストリURLに紐付いている_authToken=...が単独で書かれている
CI/CDの設定パイプライン内でも同じ.npmrcを使用ローカルだけ安全でCI/CDは別設定
Dockerビルドbuild stageに必要最小限のトークンだけ渡すトークンをイメージレイヤーに残す
lockfileのresolved想定する社内レジストリを指す社内スコープなのにregistry.npmjs.orgを指す

npm公式ドキュメントでも、認証関連の設定は特定レジストリにスコープする必要があり、そうすることで誤ったホストへ資格情報を送らないようにすると説明されています。(npm ドキュメント)

postinstallを前提にした安全な展開方法

今回の攻撃で特に危険なのは、postinstallによる自動実行です。Microsoftは、すべてのパッケージがpackage.jsonpostinstallフックを宣言し、被害者がnpm installを実行した時点で悪意あるコードが実行されると説明しています。(Microsoft)

npmには、package.json内のスクリプト実行を抑止するignore-scripts設定があります。npm公式ドキュメントでは、ignore-scriptsがtrueの場合、package.jsonに指定されたスクリプトを実行しないと説明されています。ただし、npm startnpm testなど、特定スクリプトの実行を明示するコマンドは対象スクリプト自体を実行します。(npm ドキュメント)

実務では、すべての環境でいきなりignore-scripts=trueにすると、ネイティブモジュールやビルド後生成物に依存するパッケージが壊れることがあります。そのため、次のように段階導入するのが現実的です。

導入段階実施内容目的
監査フェーズCIでnpm ci --ignore-scriptsを試すどのパッケージがinstall scriptに依存しているか把握する
例外整理必要なパッケージだけ理由付きで許可する「何となくpostinstallを許可」を避ける
本番導入新規・外部由来の依存更新時は--ignore-scriptsを標準にする未検証パッケージの自動実行を防ぐ
継続運用lockfile差分とpackage.jsonscripts差分をレビュー対象にする依存更新時の見落としを減らす

一時的に個別コマンドで抑止するなら、次のように実行できます。

npm ci --ignore-scripts

ユーザーまたはCI/CD環境全体で既定値にする場合は、影響を検証したうえで設定します。

npm config set ignore-scripts true
npm config get ignore-scripts

注意点は、ignore-scriptsを有効にしただけで安全が完成するわけではないことです。信頼済みとして例外許可したパッケージのpostinstallが侵害されれば、同じリスクが戻ります。例外はリスト化し、なぜ必要なのか、誰が承認したのか、いつ見直すのかを決めておくべきです。

Microsoft Defenderで確認すべき検出ポイント

Microsoftは、Microsoft Defender Antivirusが難読化されたpostinstallステージャーや偵察ペイロードを検出・ブロックすること、Microsoft Defender for Endpointがnpm lifecycle script abuseやDetached child processの挙動検出を提供することを説明しています。(Microsoft)

Defender XDRを利用している場合は、次の観点でハンティングすると実務に落とし込みやすくなります。

観点探すもの意味
プロセスnode.exenpm.exenpx.exeからのpostinstall実行インストール時スクリプト悪用の可能性
ネットワークoob.moika[.]techや関連ルアードメインへの通信C2または偽装インフラへの接続可能性
ファイル._*_init.js~/.cache/._t-in-one_init/などペイロードや実行済みマーカーの可能性
ヘッダーX-Secretの固定値キャンペーン固有の高精度IOC
環境変数*_RECON_ONLY*_PKG*_VER*_SECRET偵察ペイロードの実行痕跡

Microsoftが示すIOCには、C2サーバーoob.moika[.]tech、OS別ペイロードURL、scripts/postinstall.js._cloudplatform-single-spa_init.js._wb-track_init.js._t-in-one_init.js~/.cache/._t-in-one_init/、固定のX-Secretヘッダー値などが含まれます。(Microsoft)

Defender XDRの簡易ハンティング例

まずはネットワーク通信を確認します。

DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has_any ("oob.moika.tech", "npm.t-in-one.io", "docs.t-in-one.io", "jira.t-in-one.io")
| project Timestamp, DeviceName, RemoteUrl, RemoteIP, RemotePort,
          InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName

次に、npmやNode.jsのプロセスから不審なインストール時スクリプトが動いていないかを確認します。

DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("node.exe", "npm.cmd", "npm.exe", "npx.cmd", "npx.exe")
| where ProcessCommandLine has_any ("preinstall", "postinstall", "install")
| where ProcessCommandLine has_any (
    "@cloudplatform-single-spa", "@wb-track", "@data-science",
    "@ce-rwb", "@payments-widget", "@travel-autotests",
    "@t-in-one", "@capibar.chat", "@sber-ecom-core")
| project Timestamp, DeviceName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName

tmpやcache配下のファイル作成も確認します。

DeviceFileEvents
| where Timestamp > ago(30d)
| where FileName matches regex @"^\._.*_init\.js$"
   or FolderPath has_any (
        ".cache/._cloudplatform-single-spa_init",
        ".cache/._wb-track_init",
        ".cache/._t-in-one_init")
| project Timestamp, DeviceName, FolderPath, FileName, ActionType,
          InitiatingProcessFileName, InitiatingProcessCommandLine

Microsoftのサンプルでは7日間の検索例が示されていますが、過去のビルドや開発端末を広く確認する場合は、ログ保持期間に応じて30日程度まで広げると見落としを減らせます。(Microsoft)

シークレットとトークンのローテーション判断

今回のペイロードは偵察目的と説明されていますが、環境変数や開発者コンテキストを収集する設計である以上、影響環境に置かれていたシークレットは「見られた可能性がある」と考えて扱うべきです。

特に、次の情報は優先的にローテーションします。

対象対応
npmトークンNPM_TOKEN、publish token再発行し、古いトークンを失効
CI/CDシークレットGitHub Actions Secrets、Azure Pipelines変数、Jenkins credentials影響ジョブで使われたものから優先
クラウド資格情報AWS、Azure、GCPのアクセスキーやサービスプリンシパル権限範囲を確認し、必要に応じて再発行
Git関連トークンGitHub PAT、GitLab tokenなど最終使用履歴を確認してローテーション
社内APIキーステージング、本番APIキー環境ごとに影響を切り分ける

ローテーション時に失敗しやすいのは、「該当パッケージを消したから大丈夫」と判断してしまうことです。攻撃者が収集した情報は、パッケージ削除後も悪用される可能性があります。該当環境でnpm installが実行された日時、保存されていた環境変数、CI/CDで使用された権限をセットで確認してください。

CI/CDで見落としやすい注意点

今回の攻撃では、CI環境を検出して実行を回避する処理も説明されています。Microsoftによると、ステージャーはCI環境変数やスコープ固有の変数を確認し、検出時に静かに終了することで、監視が強いCI/CD上での発見を避ける狙いがありました。(Microsoft)

そのため、「CIログに怪しい通信がない」だけでは安全とは言い切れません。次のように確認範囲を広げる必要があります。

見落としやすい場所確認内容
開発者端末ローカルでnpm installを実行していないか
一時的な検証環境PoCや検証ブランチで依存更新を試していないか
コンテナビルドDocker build中にトークンが渡されていないか
キャッシュnpm cache、CI cache、Docker layerに悪性パッケージが残っていないか
フォーク・ブランチmain以外のブランチでlockfileが更新されていないか

CI/CDでは、ビルド成功だけを見ず、依存解決のログ、外向き通信、使用されたシークレットの範囲まで確認します。とくに本番デプロイ権限を持つrunnerでnpm installを行っている場合は、影響調査を優先してください。

開発チームに展開する際の実務ポイント

セキュリティ担当者が一方的に「npm installを禁止」と伝えるだけでは、現場の開発が止まり、迂回運用が生まれます。展開時は、禁止ではなくルール化が重要です。

依存関係更新のレビュー基準を決める

依存関係の更新PRでは、次の差分をレビュー対象にします。

レビュー対象見るべきポイント
新規スコープ自社・取引先・有名サービスに似た名前ではないか
バージョン番号不自然に高いバージョンになっていないか
scriptspreinstallinstallpostinstallが追加されていないか
resolvedlockfileが想定レジストリを指しているか
メンテナー情報急に変わっていないか、公開直後ではないか
READMEやURL社内風URLを装っていないか、実在確認できるか

Microsoftは、攻撃者が100.100.100のような不自然に高いバージョン番号を使い、依存解決で正規の内部パッケージより優先されることを狙ったと説明しています。(Microsoft)

開発者に伝えるべき判断基準

開発者向けには、次のように具体的に伝えると行動につながります。

開発者が見るもの危険なサイン
パッケージ名自社・取引先・金融・認証・token・secretを連想させる名前
バージョン99.0.7100.100.100のような極端に高い番号
install scriptpostinstallで外部通信や難読化JSを実行
メタデータGitHub Enterprise、Jira、Docs風だが実在確認できないURL
公開日直近に公開されたばかりで利用実績が少ない

ポイントは、「有名そうに見える」「社内ツールっぽい」ことを信用材料にしないことです。今回の攻撃では、まさにその心理が狙われています。

すぐ実施したい対応チェックリスト

最後に、管理者と開発者がすぐ使えるチェックリストに整理します。

対応担当完了条件
影響スコープを全リポジトリで検索開発・SREpackage/lockfile/.npmrcの検索結果を記録
CI/CDログを確認SRE・DevOps2026年5月28日以降のnpm install履歴を確認
.npmrcを棚卸し開発基盤チーム社内スコープが社内レジストリへ固定されている
外向き通信ログを確認セキュリティ運用C2・ルアードメインへの通信有無を確認
tmp/cache配下を確認情シス・SOC._*_init.jsやrun-once markerの有無を確認
シークレットをローテーション各システム管理者影響環境のトークン・クラウド資格情報を再発行
ignore-scripts導入を検証開発基盤チーム壊れるパッケージと例外許可をリスト化
依存更新レビューを強化開発チーム新規スコープ、install script、resolved先をレビュー項目化

今回の「Malicious npm packages abuse dependency confusion to profile developer environments」は、Microsoft製品の設定変更というより、npmを使う開発組織に向けた強い警告です。最初にやるべきことは、影響スコープの検索、.npmrcのスコープ固定、CI/CDと開発端末のログ確認です。そのうえで、該当環境に置かれていたシークレットをローテーションし、postinstallを無条件に許可しない運用へ移行してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次