2026年3月31日、JavaScript 界隈が一斉にざわつきました。
週間1億ダウンロードを超える HTTP クライアント axios の npm パッケージが乗っ取られ、マルウェア入りのバージョンが公式レジストリに公開されました。しかも犯行時間はわずか約3時間。その短い窓の間に npm install を実行した環境には、クロスプラットフォーム対応の RAT(遠隔操作ツール)が仕込まれていました。
この記事では、何が起きたのか、自分が影響を受けているかの確認方法、そして今後どう守るかを整理します。
何が起きたか
攻撃者は axios のリードメンテナーの npm アカウントを乗っ取り、2つの不正バージョンを公開しました。
axios@1.14.1(latestタグ)axios@0.30.4(legacyタグ)
公開時刻は UTC 2026-03-31 00:21 頃。日本時間だと 3月31日の午前9時21分頃にあたります。npm 側が削除したのが UTC 03:15~03:30 頃なので、悪意あるバージョンがレジストリ上に存在していたのはおよそ3時間弱です。
手口はこうです。axios のソースコード自体は一切変更していません。代わりに package.json の依存関係に plain-crypto-js@4.2.1 という見慣れないパッケージをこっそり追加しています。このパッケージの postinstall フックが setup.js を実行し、OS を判別して Windows / macOS / Linux それぞれに対応した RAT をダウンロード・実行する仕組みでした。
厄介なのは、マルウェアが実行後に自分自身を削除し、package.json も正常な状態に書き戻すこと。事後に node_modules/plain-crypto-js/ を覗いても、きれいな状態しか残っていません。npm audit でも検出できません。証拠隠滅まで自動化されています。
Google の脅威インテリジェンスチーム(GTIG)は、この攻撃を北朝鮮系の脅威アクター UNC1069 によるものと公表しています。
影響を受けるバージョン
影響があるのは以下の2バージョンだけです。
| バージョン | タグ | 備考 |
|---|---|---|
1.14.1 | latest | 正規リリースに GitHub タグなし |
0.30.4 | legacy | 同上 |
安全なバージョンは 1.14.0(1.x 系)と 0.30.3(0.x 系)。現在は npm 上から不正バージョンは削除済みで、latest タグは 1.14.0 に戻っています。
自分が影響を受けているか確認する
ここからが実戦パートです。
1. lockfile を grep する
まずは自分のプロジェクトの package-lock.json か yarn.lock を確認します。
# package-lock.json の場合
grep -E '"axios".*"(1\.14\.1|0\.30\.4)"' package-lock.json
grep 'plain-crypto-js' package-lock.json
# yarn.lock の場合
grep -E 'axios@.*(1\.14\.1|0\.30\.4)' yarn.lock
grep 'plain-crypto-js' yarn.lock
ここで何もヒットしなければ、そのプロジェクトは問題ありません。
2. node_modules の中を直接見る
lockfile だけでは不安な場合、インストール済みの axios のバージョンを直接確認します。
cat node_modules/axios/package.json | grep '"version"'
1.14.1 や 0.30.4 が出てきたら要対応です。
もう少し広く調べたいなら、マシン上のすべての node_modules を走査します。
find / -path "*/node_modules/axios/package.json" 2>/dev/null | while read f; do
version=$(grep '"version"' "$f" | head -1)
echo "$f -> $version"
done
3. 正規の axios の依存関係を知っておく
正規の axios が持つ依存パッケージは3つだけです。
follow-redirectsform-dataproxy-from-env
ここに plain-crypto-js が混ざっていたら、不正バージョンがインストールされた痕跡です。
cat node_modules/axios/package.json | grep -A 10 '"dependencies"'
lockfile と npm ci を使っていれば被害を回避できた
今回の攻撃でもっとも分かれ目になったのは、lockfile の運用です。
package.json に "axios": "^1.14.0" と書いてあっても、攻撃前に生成された lockfile がコミットされていて、デプロイ時に npm ci を使っていた環境は影響を受けていません。
理由は単純で、npm ci は lockfile に記載されたバージョンを厳密にインストールするからです。lockfile に 1.14.0 と書いてあれば、レジストリに 1.14.1 が出ていようが無視します。
一方、npm install は lockfile が存在していても、package.json のセマンティックバージョニング範囲内で新しいバージョンがあれば lockfile を更新してしまうケースがあります。CI/CD パイプラインで npm install を使っていた環境が、今回もっとも被害を受けやすかったわけです。
# NG: CI/CD でこれをやっていると、攻撃窓の間に新バージョンを引いてしまう可能性がある
npm install
# OK: lockfile を厳密に尊重する
npm ci
これは今回に限った話じゃないです。サプライチェーン攻撃全般に対する防御として、CI/CD では npm ci を使うのが鉄則です。
影響を受けていた場合の対応
lockfile に不正バージョンが記録されていた場合、パッケージの入れ替えだけでは不十分です。RAT がインストール時に実行されている以上、その環境は「侵害済み」として扱う必要があります。
やるべきことを挙げると、
- axios を安全なバージョンに固定し直す(
npm install axios@1.14.0 --ignore-scripts) node_modules/plain-crypto-jsが存在していれば削除- そのマシンでアクセス可能だったクレデンシャルをすべてローテーション(SSH 鍵、API キー、npm トークン、クラウドのアクセスキーなど)
- CI/CD で使っていたシークレットも同様にローテーション
- 可能であれば、影響を受けたマシンは攻撃前のバックアップからクリーンに復元する
特にクレデンシャルのローテーションは最優先です。RAT が動いていた時間にマシン上にあった秘密情報は、すべて漏洩した前提で動くしかありません。
今後に向けて ― 手元でできる防御策
今回の件を受けて、個人プロジェクトや小規模チームでもやっておくべきことを整理します。
lockfile は必ずコミットする
package-lock.json や yarn.lock を .gitignore に入れているプロジェクトをたまに見かけますが、やめたほうがいいです。lockfile がなければ、npm install のたびにレジストリから最新を引いてきます。それはつまり、攻撃者が公開した不正バージョンをそのまま受け入れるということです。
CI/CD では npm ci を徹底する
繰り返しになりますが、npm ci は lockfile の内容を厳密に再現します。lockfile と package.json に矛盾があればエラーで止まるので、意図しないバージョンの混入を検知できます。
postinstall スクリプトを無効化する
今回の攻撃は postinstall フックが起点でした。CI/CD で --ignore-scripts を付けてインストールすれば、このクラスの攻撃を丸ごと無効化できます。
npm ci --ignore-scripts
ただし、ネイティブモジュールのビルドなど postinstall が正当に必要なパッケージもあるので、そこは個別に対処が要ります。
pnpm を検討する
pnpm はデフォルトで lifecycle スクリプト(postinstall 等)を実行しません。明示的に許可リストに追加したパッケージだけが実行されます。今回のような攻撃に対しては、パッケージマネージャーの選択自体が防御になります。
まとめ
今回の攻撃は、axios ほどの超メジャーパッケージでも npm アカウントが1つ乗っ取られるだけで全世界に影響が出る、ということを嫌というほど見せつけました。
被害の大小を分けたのは、結局のところ地味な運用でした。lockfile をコミットしていたか。CI で npm ci を使っていたか。postinstall スクリプトを制御していたか。
特別なセキュリティツールの話ではなく、npm の基本機能をちゃんと使っていたかどうかで明暗が分かれました。怠惰に見えて、実は一番手堅いです。
参考リンク
- Google Threat Intelligence Blog - North Korea-Nexus Threat Actor Compromises Widely Used Axios NPM Package
- Elastic Security Labs - Inside the Axios supply chain compromise
- StepSecurity - axios Compromised on npm
- Snyk Blog - Axios npm Package Compromised
- Huntress - Supply Chain Compromise of axios npm Package