2026年5月14日、Node.jsのプロセス間通信ライブラリnode-ipcのnpmページに、3つの悪意あるバージョンが同時公開された。週間ダウンロード数82万を超える広く普及したパッケージへの混入であり、Aikido Securityは公開から数分以内に検出したと報告している。悪性バージョン(9.1.6、9.2.3、12.0.1)はnpmレジストリからすでに削除済みだが、バージョンを固定せずにインストールしていた環境、あるいはnpm installを2026年5月14日に実行したCI/CD環境では感染コードを踏んでいる可能性がある。
npmサプライチェーン全体のリスク像と防御策の俯瞰はサプライチェーンセキュリティ完全ガイド2026|攻撃手法・防御ツール・実践チェックリストをご覧ください。
対象読者
- ・`node-ipc`を直接またはトランジティブ依存として使うNode.jsプロジェクト開発者。
- ・vue-cli、electron-builder等`node-ipc`を内部利用するツールの利用者。
- ・2026年5月14日前後に`npm install`を実行したCI/CD環境の管理者。
1. 何が起きたか——node-ipc 3バージョン汚染のタイムライン
2026年5月14日、npmのアカウントatiertant(メールアドレス: [email protected])が、node-ipcパッケージに3つのバージョンを同時公開した。このアカウントはそれ以前のnode-ipcリリースには一切関与していない第三者のものだ。
| 日時(UTC) | 出来事 |
|---|---|
| 2024-08-12 | 正規メンテナriaevangelistが12.0.0を公開(攻撃前の最終正常版) |
| 2026-05-14 | アカウントatiertantが9.1.6・9.2.3・12.0.1を同時公開 |
| 2026-05-14 | Aikido Securityが公開から数分以内に検出 |
| 2026-05-14 | Socket・StepSecurityが詳細技術レポートを公開 |
| 2026-05-15 | 3バージョンともnpmレジストリから削除済み |
公開された3バージョンのうち、12.0.1はlatestタグに設定されていた点が特に深刻だ。npm install node-ipcとバージョンを指定せずに実行した場合、npmはデフォルトでlatestを取得するため、このバージョンを明示的に避ける設定がなければ感染コードをインストールしてしまう。
安全なバージョンは9.1.5(9系の直前リリース)または12.0.0(攻撃前のlatest)だ。
node-ipcとは
- ・Brandon Nozaki Miller(@RIAEvangelist)が開発したNode.js向けIPC(プロセス間通信)ライブラリ。
- ・ローカルおよびリモートプロセス間のソケット通信、Neural Networkingをサポート。
- ・週間ダウンロード数は82万以上で、vue-cli-service、electron-builder等多数のツールが内部依存している。
- ・2022年にも「peacenotwar」インシデントで一度悪用されており、本記事§7でその違いを詳述する。
2. 攻撃ベクタ——期限切れドメインを悪用したnpmアカウント乗っ取り
今回の攻撃の入口は、atiertantアカウントのメールドメインatlantis-software.netが有効期限切れになっていた点だ。攻撃者はこのドメインを取得し、npmの「パスワードリセット」機能を悪用して当該アカウントのパスワードを変更。正規のメンテナのインフラや認証情報に一切触れることなく、node-ipcへのpublish権限を手に入れた。
この手法は「ドメイン乗っ取り経由のnpmアカウント侵害」と呼ばれ、npmのアクセス制御設計の盲点を突くものだ。npm公式は二要素認証(2FA)の必須化を段階的に進めているが、atiertantアカウントは高権限パッケージへのアクセスを持ちながら2FAが設定されていなかったか、あるいは2FAをバイパスできる状態だったと見られている。
StepSecurityの分析によると、atiertantアカウントはCIパイプラインへの侵入やトークン窃取といった高度な手法ではなく、こうした「基盤的なアカウント管理の不備」を突く、比較的単純だが確実性の高い経路を使っている。攻撃者がCI/CDやOIDCトラステッドパブリッシャーに一切触れずに公開できた点は、TanStack Mini Shai-Huludワームとは異なるアプローチだ。あちらはGitHub Actions OIDC経由の正規パブリッシュ経路を乗っ取ったが、今回は単純なアカウント乗っ取りだけで同等の結果を得ている。
なお、正規メンテナのriaevangelistアカウントや本家リポジトリRIAEvangelist/node-ipcは侵害されていない。公開されたコード、issueトラッカー、タグのいずれにも改ざんは確認されていない。
3. ペイロードの動作——CJSバンドル埋め込みとDNSトンネリング窃取
悪意あるコードはnode-ipc.cjs(CommonJSバンドル)の1271行目以降に80KBの難読化JavaScriptが追加される形で混入されている。ESMエントリポイントは改ざんされていない。
uname -a / platform / hostname等"] E --> F["ファイルシステムをスキャン
113〜127パターンのクレデンシャル収集"] F --> G["収集ファイルを ~/nt-PID/ に圧縮
gzip tar.gz アーカイブ化"] G --> H["sh.azurestaticprovider.net:443
へのBootstrapクエリ"] H --> I["DNS TXT クエリで分割送信
xh/xd/xf プレフィックス
XORエンコード + base64置換"] I --> J["bt.node.js ゾーンへ
データ到達、攻撃者が回収"] style A fill:#c0392b,color:#fff style J fill:#c0392b,color:#fff
require('node-ipc')が呼ばれる瞬間にIIFEがロードされ、setImmediate()によって次のイベントループ以降に実行が始まる。本体コードはさらにchild_process.fork()で__ntw=1という環境変数を持つ子プロセスを生成する。この環境変数は「すでに悪意ある子プロセスとして動いている」フラグで、再帰的な二重起動を防ぐための仕組みだ。
子プロセスはstdio: 'ignore'とdetached: trueで起動するため、親プロセス(アプリケーション本体)が終了しても独立して動き続ける。ターミナルでnpm startを実行していた場合、Ctrl+Cで止めてもバックグラウンドで盗み続けている可能性がある。
難読化の4層構造として、StepSecurityは443エントリの文字列配列シャッフル、制御フロー平坦化、デッドコード注入、nibbleを逆順にしたカスタムbase-16エンコーディング(0123456789GHJKMPアルファベット使用)の組み合わせを確認している。デコンパイルして読むだけでもかなりの工数が必要な難読化レベルだ。
データ流出にはDNS TXTレコードを使う点が今回の大きな特徴だ。通常のHTTPS通信ではなくDNSクエリで送出するため、HTTP/HTTPSフィルタリングをすり抜ける。Bootstrap用のDNSレゾルバとしてsh.azurestaticprovider.net:443(IPアドレス: 37.16.75.69)が使われ、攻撃者が管理するDNSサーバを経由してbt.node.jsゾーンにデータが届く。
データはXORエンコード後にbase64変換で分割され、それぞれxh(ヘッダ)、xd(データ本体)、xf(フッタ)プレフィックスを持つTXTレコードとしてクエリされる。500KBの圧縮アーカイブを送り出すのに約29,400回のDNSクエリが必要になるが、Cloudflare DNS(1.1.1.1)とGoogle DNS(8.8.8.8)を経由するため通常のDNSトラフィックと区別しにくい。
4. 盗まれるデータ——node-ipcが標的にするクレデンシャル113パターン
悪意あるペイロードは実行環境のプラットフォームに応じて113〜127のファイルパスパターンを対象にクレデンシャルを収集する。4MiB超のファイルはスキップされ、node_modulesと.gitディレクトリは再帰スキャンから除外されている。
| カテゴリ | 対象ファイル例 |
|---|---|
| AWSクレデンシャル | ~/.aws/credentials、~/.aws/config、AWS SSOキャッシュ |
| Azure | ~/.azure/accessTokens.json、Azure CLI設定 |
| GCP | ~/.config/gcloud/application_default_credentials.json |
| SSH鍵 | ~/.ssh/id_rsa、~/.ssh/id_ed25519、~/.ssh/id_ecdsa等 |
| Kubernetes | ~/.kube/config、サービスアカウントトークン |
| npm・パッケージ管理 | ~/.npmrc、~/.yarnrc、~/.netrc |
| GitHub・Git | ~/.gitconfig、GitHub CLI認証設定、PAT |
| Terraform | クレデンシャルファイル、.tfvars、stateファイル |
| データベース | 接続文字列、~/.my.cnf、シェル履歴(.bash_history等) |
| Docker | ~/.docker/config.json(レジストリ認証情報) |
| AIツール設定 | .claude.json、.claude/mcp.json、.kiro/settings/mcp.json |
| .envファイル | 各種.env、.env.local、.env.production等 |
| macOS固有 | Keychainデータベース、Firefoxキーデータベース |
| システム | /etc/hosts |
特筆すべきはAIツールの設定ファイルが標的に含まれている点だ。.claude.jsonはClaude Codeの認証情報や設定を含み、.claude/mcp.jsonはMCPサーバの接続情報を保持する。AIエージェントを使った開発環境が広まるにつれ、こうした設定ファイルがサプライチェーン攻撃の新たな標的になっている傾向が見て取れる。
収集されたファイルは~/nt-{PID}/という一時ディレクトリにアーカイブされ、HMAC-SHA256(ハードコードされたキーqZ8pL3vNxR9wKmTyHbVcFgDsJaEoUiを使用)で署名された上でDNSトンネリングに送出される。攻撃が完了するとこの一時ディレクトリは削除されるため、事後に検出するのは難しい。
5. 自分のプロジェクトが影響を受けたか確認する手順
まず確認すべきはロックファイルだ。package.jsonがバージョンを固定していても、ロックファイルが悪意あるバージョンを参照している場合は感染している。
# package-lock.json(npm)
grep "node-ipc" package-lock.json | grep -E "9\.1\.6|9\.2\.3|12\.0\.1"
# pnpm-lock.yaml
grep "node-ipc" pnpm-lock.yaml | grep -E "9\.1\.6|9\.2\.3|12\.0\.1"
# yarn.lock
grep -A2 "^node-ipc@" yarn.lock | grep -E "9\.1\.6|9\.2\.3|12\.0\.1"
ヒットした場合、汚染版を踏んでいる可能性が高い。次にトランジティブ依存を含む全依存ツリーを確認する。
# node-ipcがどこから引っ張られているか確認
npm ls node-ipc
バックグラウンドで子プロセスが動き続けている可能性がある場合は、__ntw=1環境変数を持つNode.jsプロセスを探す。
# Linux/macOS: __ntw=1を持つプロセスを確認
ps aux | grep node
# さらに詳しく(Linux)
cat /proc/*/environ 2>/dev/null | tr '\0' '\n' | grep __ntw
一時ディレクトリが残っていないかも確認する。攻撃完了後は自動削除されるが、実行中であれば確認できる。
ls -la ~/nt-*/ 2>/dev/null || echo "一時ディレクトリは見つかりません"
ネットワーク側からは、sh.azurestaticprovider.netへの通信履歴を確認する。
# macOS: DNS クエリログ(syslogから)
log show --predicate 'eventMessage contains "azurestaticprovider"' --last 1d
# Linux: systemd-resolved の場合
journalctl -u systemd-resolved | grep "azurestaticprovider"
ペイロードのSHA-256ハッシュ(IOC)
- ・ペイロード本体:
96097e0612d9575cb133021017fb1a5c68a03b60f9f3d24ebdc0e628d9034144 - ・悪意あるバージョン: [email protected]、[email protected]、[email protected]
- ・C2 Bootstrap:
sh.azurestaticprovider.net:443(IP: 37.16.75.69) - ・DNS流出ゾーン:
bt.node.js - ・プロセス識別子: 環境変数
__ntw=1
6. 即座に取るべき対処——バージョン固定とクレデンシャルローテーション
ステップ1:安全バージョンへのダウングレードとロックファイル更新
# 安全版を明示的にインストール
npm install [email protected]
# またはpackage.jsonのoverridesで汚染バージョンを除外
package.jsonのoverridesに以下を追加して汚染バージョンへの到達を防ぐ。
{
"overrides": {
"node-ipc": "12.0.0"
}
}
ロックファイルを更新し、node_modulesを完全に削除してからnpm ciで再インストールする。CIのキャッシュ(actions/cache等)も無効化してクリーンビルドを行う。
ステップ2:クレデンシャルローテーションの優先順位
感染の可能性があると判断した場合は、以下の順でクレデンシャルをローテーションする。
| 優先度 | 対象 | 理由 |
|---|---|---|
| 最優先 | AWS IAMキー・セッショントークン | 実害が最も大きい。不正アクセスされると広範なクラウドリソースが危険 |
| 高 | SSH秘密鍵 | サーバへのアクセス権に直結。authorized_keysも確認が必要 |
| 高 | GitHub PAT・npm publish token | リポジトリへの書き込み権限、追加のサプライチェーン攻撃の踏み台になりうる |
| 高 | Kubernetesサービスアカウントトークン | クラスタ全体への権限昇格につながる |
| 中 | クラウドサービスアカウントキー(GCP・Azure) | IAMロールによるが、クラウドリソース操作の権限を持つ |
| 中 | DBパスワード・接続文字列 | データ漏洩・改ざんのリスク |
| 中 | Terraform credentials | インフラ変更権限 |
| 低〜中 | .envファイル内のAPIキー | サービス依存だが、Stripe・OpenAI等高額請求につながるものは優先 |
ステップ3:CIパイプラインの確認
2026年5月14日にnpm installを含むCIが動いていた場合、そのランナーが持っていたすべてのシークレットが漏洩している前提で動く。GitHub ActionsのSecretsは即座にローテーションし、古いシークレットを参照していたワークフローはすべて再実行する。
自動依存更新ツールを運用している場合は、Renovate・Dependabotの自動PRがマルウェアを運ぶ:開発者が今すぐ確認すべきことで説明している
minimumReleaseAge(最低リリース経過日数)の設定も見直してほしい。公開直後の版を自動的に取り込まない設定が今回のような攻撃にも有効だ。
7. 2022年のpeacenotwar事件との比較——npmサプライチェーン攻撃の進化
node-ipcは2022年3月にも大きなセキュリティインシデントに巻き込まれた。当時の正規メンテナriaevangelist自身がロシア・ベラルーシIPからアクセスしているユーザーのファイルをハートの絵文字で上書きする「protestware」コードを意図的に仕込んだ事件で、CVE-2022-23812として登録されている。
今回の2026年5月の攻撃は、同じパッケージで起きた別系統の攻撃だ。両者を比較すると、npmサプライチェーン攻撃がどのように「進化」したかが見えてくる。
| 比較項目 | 2022年 peacenotwar | 2026年5月 本件 |
|---|---|---|
| 攻撃者 | 正規メンテナ本人 | 期限切れドメイン経由でアカウント乗っ取った第三者 |
| 動機 | 地政学的抗議(破壊型) | 金銭目的(窃取型) |
| CVE | CVE-2022-23812 | (調査時点で未採番) |
| ペイロード | ハートファイルで上書き(破壊・分かりやすい) | 80KB難読化IIFE(窃取・検出困難) |
| 流出データ | なし(ファイル破壊) | 100種超のクレデンシャル |
| 流出経路 | なし | DNSトンネリング(ファイアウォール回避) |
| 検出のしやすさ | 高(ファイルが消える) | 低(ログに何も残らない) |
| 影響範囲 | ロシア・ベラルーシIPのみ | 全実行環境 |
| 対応の緊急度 | 高(即座にロールバック必要) | 極高(クレデンシャル流出済みの前提が必要) |
| プロセス持続性 | なし | デタッチ子プロセスが残存 |
| ESM/CJS | 両方汚染 | CJSのみ(ESM untouched) |
2022年の事件は「意図的な破壊」で、被害が一目瞭然だった。ファイルがハートに変われば誰でも気づく。2026年の攻撃は正反対の設計思想を持つ。被害者が気づかないことを最優先に設計された窃取型マルウェアだ。プロセスはバックグラウンドで動き、通信はDNSに紛れ込み、一時ファイルは自動削除される。気づいたときにはすでにクレデンシャルが攻撃者の手元にある。
同種の認証情報窃取に特化した攻撃については偽TanStackパッケージが.env窃取|npmブランドスクワット攻撃の全容と緊急対策でも解説している。スクワット型攻撃と今回のような正規パッケージへの混入型は手口が異なるが、クレデンシャルを狙う点は共通している。
8. Vue CLIは大丈夫?——2022年の教訓が今回開発者を守った
Vue CLI(@vue/cli)は今回の事件で影響を受けていない。これは2022年のpeacenotwar事件後にVueチームが取った判断が功を奏した結果だ。
当時、Vue CLIはnode-ipcに直接依存していた。peacenotwarインシデント発生後、Vueチームは依存先を正規のコミュニティフォーク@achrinza/node-ipcに切り替えている。同フォークは悪意あるコードが除去され、上流の正規パッケージとは別系統でメンテナンスされており、今回乗っ取られたriaevangelistのnpmアカウントとは無関係だ。
現行の@vue/cli 5.0.9を確認すると、直接依存ツリーにnode-ipcは含まれていない。@vue/cli-shared-utilsおよび@vue/cli-uiもそれぞれ@achrinza/node-ipcを参照しており、今回流出したriaevangelist/node-ipc系のパッケージは一切経由していない。
# Vue CLIプロジェクトで確認
npm ls node-ipc
npm ls @achrinza/node-ipc
npm ls node-ipcが「empty」と出れば影響なし、@achrinza/node-ipcが表示されればフォーク版を経由しているため今回の汚染対象外だ。
なぜVue CLIだけ守られたのか
- ・2022年のpeacenotwar事件後、Vueチームが上流ではなくフォーク(
@achrinza/node-ipc)へ移行済み - ・「protestware混入の前科」を依存判断のシグナルとして恒久的に扱った
- ・今回のアカウント乗っ取りでも、上流が汚染されてもフォークには波及しない構造になっていた
過去の事件を「もう収束した古い話」として処理するか、「今後の依存判断の材料」として残すか。3年前の判断が3年後の被害範囲を分けた、再現性のある教訓だ。node-ipcに直接依存しているプロジェクトを抱えている場合は、Vue CLIと同様にフォークへの移行か、後述のlockfile・スキャナ運用の整備を検討する価値がある。
9. 組織レベルの恒久対策
個別マシンやリポジトリのクリーンアップは前述のとおりだ。ここでは「今後同じ攻撃を受けないための恒久対策」に絞って整理する。
短期(24時間以内):インストールスクリプトの無効化とlockfile検査
npmのインストールライフサイクルスクリプト(preinstall・postinstall・prepare)は、依存パッケージが任意コードをホスト上で実行できる経路だ。本件の悪意あるコードはこれらを使っていないが(IIFEはrequire時に起動)、一般的なサプライチェーン攻撃では頻繁に使われる。.npmrcに以下を追加しておくことを推奨する。
# .npmrc
ignore-scripts=true
これで壊れる依存(esbuild・sharp等バイナリを含むもの)はnpm rebuild <pkg>で個別に許可するか、CIのDockerイメージ内でプリビルドする運用に切り替える。
lockfileの整合性チェックも自動化できる。
# npm: lockfileが更新されているか検出(CI用)
npm ci --ignore-scripts
npm ciはlockfileを信頼の源として扱い、package.jsonとの不一致があれば失敗する。lockfile自体のハッシュをgit hooksで保護するとさらに強固になる。
中期(1週間以内):依存スキャンの自動化とrelease age制御
SocketやStepSecurityのようなサプライチェーンスキャナをCIに組み込み、悪意あるパターンを検出できる体制を整える。Renovateを使っている場合はminimumReleaseAgeを設定することで、公開直後(今回のように数時間以内)のバージョンを自動的に取り込まない設定が可能だ。
{
"packageRules": [
{
"matchPackagePatterns": ["*"],
"minimumReleaseAge": "3 days"
}
]
}
npmのパッケージ管理者権限を持つアカウントすべてに2FAを強制する。npmjs.comの管理コンソールから確認・強制設定が可能だ。特にpublish権限を持つアカウントのメールドメインが有効期限内であることを定期的に確認する仕組みを作る。
長期(1か月以内):EDR検知ルールとドメイン監視
今回の攻撃で使われたsh.azurestaticprovider.netは攻撃者が管理するドメインで、Azureインフラになりすましたものだ。企業のEDR(CrowdStrike・SentinelOneなど)に以下の検知ルールを追加する。
- ・`sh.azurestaticprovider.net`への通信
- ・`bt.node.js`ドメインへのDNS TXTクエリ
- ・`__ntw=1`環境変数を持つデタッチドNode.jsプロセス
- ・`~/nt-*/`パターンの一時ディレクトリ作成
npmのメンテナとして自社パッケージを管理している場合は、自分のパッケージへの予期しないコントリビューターの追加をnpm Auditメールで監視する設定が有効だ。npmjs.com上のアカウントのメールアドレスに使っているドメインが有効期限切れにならないよう、DNSドメイン管理の棚卸しも行う。期限切れドメインを起点とした今回と同じ手口を防ぐ根本的な対策だ。
まとめ
- ・2026年5月14日、`node-ipc`の3バージョン(9.1.6・9.2.3・12.0.1)に悪意あるコードが混入した。`latest`タグ(12.0.1)を踏んでいた環境は全て影響を受ける。
- ・攻撃経路は期限切れメールドメイン→npmアカウントパスワードリセット→publish権限取得という、シンプルだが見逃しやすい手法だ。
- ・CJSバンドル(`node-ipc.cjs`)の末尾に80KBのIIFEが追加され、`require()`一発で起動。DNSトンネリングで100種超のクレデンシャルを流出させる。
- ・安全版は9.1.5または12.0.0。即座にlockfileを更新し、2026年5月14日に`npm install`を実行した環境はクレデンシャルローテーションを実施する。
- ・2022年のpeacenotwar事件と同じパッケージで再発したが、今回は窃取型で検出が格段に難しい。しかし対策は既知の方法で実施可能だ。
5月14日以降にnpm installを走らせたNode.js環境を持つ開発者は、まずロックファイルを確認することから始めてほしい。
参照ソース
- Popular node-ipc npm Package Infected with Credential Stealer — Socket Security — ペイロードの詳細技術解析、DNS流出の仕組み、IOCリスト。
- Active Supply Chain Attack: Malicious node-ipc Versions Published to npm — StepSecurity — 攻撃タイムライン、4層難読化の解析、推奨対応手順。
- Compromised node-ipc on npm: Credential Stealer via DNS Exfiltration — SafeDep — DNSトンネリングの詳細メカニズム、HMAC署名フォーマット、検出方法。
- Not Your IPC, but node-ipc: npm Hit Again with Supply Chain Attack — Semgrep — 2022年との比較分析、攻撃の差分解説。
- Embedded Malicious Code in node-ipc — CVE-2022-23812(GitHub Advisory Database) — 2022年peacenotwarインシデントの公式アドバイザリ。
- AikidoSecurity (@AikidoSecurity) on X, 2026-05-14 — 初期検出報告ツイート(公開から数分以内)。