npmパッケージをインストールするだけで、マルウェアがシステムに侵入する——。そんな事態が、2026年の今、実際に起きています。
2026年3月31日、週間1億ダウンロードを超える人気HTTPクライアント「Axios」が侵害され、数時間のあいだに世界中の開発者のマシンとCI/CDパイプラインにリモートアクセストロイの木馬(RAT)が配布されました。その数ヶ月前の2025年11月には、npmエコシステムを標的にした自己増殖型ワーム「Shai-Hulud 2.0」が700以上のパッケージを感染させ、25,000件以上のGitHubリポジトリにまで被害を広げています。
この記事では、この2つの事例を軸に、npmサプライチェーン攻撃の仕組みと、開発者・チームが今すぐ実践できる防御策を体系的に解説します。
[目次を開く]
npmサプライチェーン攻撃とは
攻撃の基本構造
npmサプライチェーン攻撃とは、開発者やCI/CDパイプラインが利用する信頼されたnpmパッケージを悪用してマルウェアを配布する攻撃手法です。ソースコードに直接手を加えるのではなく、依存関係の仕組みを悪用するのが特徴です。
一般的な攻撃の流れは次のようになります。
- パッケージメンテナのアカウントを乗っ取る(または悪意あるパッケージを新規公開する)
- 正規パッケージの悪意あるバージョンを公開する
-
npm installを実行した環境でpostinstall/preinstallスクリプトが自動実行される - マルウェアが認証情報の窃取、バックドアの設置、さらなる拡散を行う
この攻撃が厄介なのは、開発者が普段通りの作業をしているだけで被害に遭う点です。パッケージの ^ や ~ のバージョン指定により、悪意あるバージョンが自動的にインストールされてしまいます。
なぜ今深刻化しているのか
2025年後半から2026年にかけて、npmを狙ったサプライチェーン攻撃は頻度・規模ともに急増しています。背景にはいくつかの要因があります。
- 依存関係の深さ: 1つのプロジェクトが数百〜数千のパッケージに依存しており、見えないところに攻撃対象が潜んでいる
- npmのデフォルト動作:
npm installは最新バージョンを取得し、ライフサイクルスクリプトを自動実行する - 国家レベルの攻撃者の参入: Microsoftは2026年のAxios攻撃を北朝鮮の脅威アクターグループ「Sapphire Sleet(UNC1069)」に帰属させており、攻撃の洗練度が増している
事例1: Axiosサプライチェーン攻撃(2026年3月)
何が起きたか
2026年3月31日00:21 UTC頃、Axiosの主要メンテナ「jasonsaayman」のnpmアカウントが乗っ取られました。攻撃者はアカウントのメールアドレスを変更し、2つの悪意あるバージョンを公開しました。
-
axios@1.14.1(latestタグ) -
axios@0.30.4(legacyタグ)
これらのバージョンには plain-crypto-js@4.2.1 という隠し依存パッケージが追加されていました。このパッケージの postinstall フックにより、インストール時にクロスプラットフォームRAT(リモートアクセスツール)が自動的に展開される仕組みです。
攻撃の巧妙さ
この攻撃がとくに注目すべき点は、その周到な準備にあります。
- 18時間前のデコイ公開: 攻撃の18時間前に
plain-crypto-js@4.2.0(無害なバージョン)を公開し、「新規パッケージ」アラートを回避 - 二重難読化:
setup.jsはBase64逆転とXOR暗号(鍵:OrDeR_7077)の二重難読化を使用 - クロスプラットフォーム対応: macOS、Windows、Linuxそれぞれに専用のRAT(C++/PowerShell/Python)を用意
- 自己消去機能: マルウェアは実行後にすべてのトレースを消去し、フォレンジック調査を困難にする
- OIDC未使用での直接公開: 正規リリースでは使われていたOIDCプロヴェナンスやSLSAビルド証明が一切なく、盗んだトークンによる直接CLI公開だった
攻撃者はGitHub Actionsなどの正規CI/CDパイプラインを一切経由せず、盗んだ長期有効トークンでnpmレジストリに直接公開しています。
被害の規模
Axiosは週間1億ダウンロードを超えるパッケージであり、悪意あるバージョンは約2〜3時間レジストリ上で公開されていました(00:21〜03:15 UTC)。この短い間に npm install を実行したすべての環境が潜在的に侵害されたことになります。
Googleの脅威インテリジェンスグループ(GTIG)は、この攻撃を北朝鮮の脅威アクター「UNC1069」に帰属させています。
事例2: Shai-Hulud 2.0(2025年11月)
ワーム型の新しい脅威
Shai-Hulud 2.0は、2025年11月21〜23日に発生した大規模なnpmサプライチェーン攻撃です。Axiosのような単一パッケージの侵害とは異なり、自己増殖するワームとして設計されていた点が特異です。
感染したパッケージは796件以上に達し、Zapier、PostHog、Postman、ENS Domainsなど広く利用されるプロジェクトが一時的にトロイの木馬化されました。
攻撃の仕組み
Shai-Hulud 2.0の攻撃は以下のように進行します。
- 感染パッケージのインストール:
preinstallフック(postinstallではなく、テストやセキュリティチェックの前に実行される)で悪意あるコードが起動 - 認証情報の収集: GitHub PAT、npmトークン、SSH鍵、AWS / GCP / Azureのクラウド認証情報、
.envファイルなどを網羅的に窃取 - GitHub経由の窃取データ送信: 従来のC2(コマンド&コントロール)サーバーではなく、被害者のGitHubアカウントを使って公開リポジトリを作成し、認証情報をアップロード(リポジトリの説明文に「Sha1-Hulud: The Second Coming.」というマーカーを設定)
- 自動拡散: 被害者のnpmトークンを使い、その人がメンテナンスしているパッケージ(最大100件)に自動的にマルウェアを注入して再公開
環境適応型の動作
Shai-Hulud 2.0はCI/CD環境と開発者のローカルマシンを識別し、それぞれに最適化された動作をする高度なマルウェアでもあります。
さらに、Bunランタイムを使ってNode.jsの標準モニタリングを回避し、Trufflehogを悪用してファイルシステム内の秘密情報を再帰的にスキャンするなど、正規のセキュリティツールを攻撃に転用する手法も使われていました。
また、認証情報の窃取に失敗した場合の「デッドマンスイッチ」として、ユーザーのホームディレクトリを破壊するという破壊的なフォールバック機構も含まれていたことが報告されています。
2つの事例の比較
| 観点 | Axios(2026年3月) | Shai-Hulud 2.0(2025年11月) |
|---|---|---|
| 攻撃の種類 | 単一パッケージのアカウント乗っ取り | 自己増殖型ワーム |
| フック方式 | postinstall | preinstall(より攻撃的) |
| 影響パッケージ数 | 2バージョン + 関連2パッケージ | 796以上のパッケージ |
| データ送信先 | 外部C2サーバー | 被害者のGitHub公開リポジトリ |
| 拡散方法 | 手動(攻撃者による直接公開) | 自動(ワームが自己増殖) |
| 帰属 | 北朝鮮 UNC1069 / Sapphire Sleet | 未確定 |
| 対策の難易度 | lockfile遵守で防御可能 | preinstallのためより防御が困難 |
共通しているのは、npmのライフサイクルスクリプトを悪用している点と、正規メンテナの認証情報が起点になっている点です。
実践的な対策ガイド
対策1: lockfileの徹底と npm ci の使用
サプライチェーン攻撃に対する最も基本的かつ効果的な防御策がlockfileの活用です。
# CI/CDでは必ず npm ci を使う(npm install ではなく)
npm ci
# lockfileは必ずGitにコミットする
git add package-lock.json npm ci は package-lock.json に記録された正確なバージョンのみをインストールし、レジストリから最新版を取得する動作をしません。もしAxios攻撃のタイミングでlockfileが 1.14.0 を指していれば、npm ci を使っていた環境は影響を受けませんでした。
対策2: ライフサイクルスクリプトの無効化
Axios攻撃は postinstall、Shai-Hulud 2.0は preinstall を悪用しました。これらのスクリプトを無効化することで、攻撃チェーン全体をブロックできます。
# .npmrc に追加(プロジェクトルートまたはグローバル)
ignore-scripts=true
# CI/CDコマンドで指定する方法
npm ci --ignore-scripts ネイティブアドオンのコンパイルなど、正当にスクリプトが必要なパッケージがある場合は、以下のように明示的に実行します。
npm ci --ignore-scripts
npm rebuild <信頼できるパッケージ名> pnpmではライフサイクルスクリプトがデフォルトで無効化され、オプトインでの許可方式になっています。npmでも同様の運用を意識的に行うことが推奨されます。
対策3: バージョンの厳密な固定
^ や ~ のバージョン範囲指定は、悪意あるバージョンへの自動更新を許してしまいます。
// NG: 自動アップグレードを許可
"axios": "^1.14.0"
// OK: 厳密なバージョン固定
"axios": "1.14.0" 間接的な依存関係がAxiosなどを引き込むケースには、overrides(npm v14以降)を使って強制的にバージョンを固定できます。
{
"overrides": {
"axios": "1.14.0"
}
} 対策4: パッケージの最低公開日数を設定する
npmの min-release-age 設定を使うことで、公開されてから一定期間が経過していないバージョンのインストールを拒否できます。
# .npmrc に追加
min-release-age=7 Axios攻撃では plain-crypto-js@4.2.1 は公開から24時間未満でした。48時間の「クールダウン期間」を設定するだけでも、この攻撃は防げた可能性があります。セキュリティコミュニティが新しいリリースを分析する時間を確保する、実用的な対策です。
対策5: CI/CDパイプラインのネットワーク制御
Axios攻撃のドロッパーは、インストールから1.1秒以内にC2サーバーへ通信を開始しました。ビルド環境から外部への自由な通信を許可している場合、任意のC2サーバーへの接続が可能になります。
CI/CDランナーのエグレス(外向き)通信を、npmレジストリや必要なサービスのみに制限することで、マルウェアの外部通信をブロックできます。
対策6: npmアカウントのセキュリティ強化
両攻撃ともメンテナの認証情報が起点になっています。パッケージを公開する開発者は、以下の対策が必須です。
- MFA(多要素認証)の強制: フィッシング耐性のあるFIDO認証が理想的
- 短命トークンの使用: npm v10以降の細粒度アクセストークンを7日以内の有効期限で運用
- OIDCによるTrusted Publishing: GitHub Actionsから直接OIDCトークンで公開し、保存されたトークンを排除
- publish時のプロヴェナンス付与:
--provenanceフラグでSLSAビルド証明を付与し、ビルド元を検証可能にする
Axiosでは正規リリースにはOIDCプロヴェナンスが付いていましたが、悪意あるバージョンには付いていませんでした。これは重要な検出シグナルになります。プロヴェナンスが突然消えたリリースには注意が必要です。
対策7: 依存関係の監査とSBOM
定期的な依存関係の監査と、ソフトウェア部品表(SBOM)の維持も重要です。
# 脆弱性の確認
npm audit
# 依存関係ツリーの確認
npm ls axios ただし、npm audit は既知の脆弱性のみを検出するものであり、公開されたばかりのマルウェアには対応が遅れます。そのため、SnykやSocket.devなどのSCAツールやマルウェア検出サービスとの併用が推奨されます。
対策8: 開発マシンのセキュリティ
CI/CDだけでなく、開発者のローカルマシンもサプライチェーン攻撃の主要な攻撃対象です。Shai-Hulud 2.0は開発マシン上の .npmrc、.env、SSH鍵、クラウド認証情報を直接窃取しています。
- AIコーディングツールの提案で
npm installを実行する前に、必ずpackage.jsonの差分を確認する - 認証情報はマシン上にファイルとして保存するのではなく、シークレットマネージャーを活用する
- GitHubアカウントに見覚えのない公開リポジトリ(とくに「Shai-Hulud」を含む名前・説明文)がないか確認する
対策の優先度まとめ
| 優先度 | 対策 | 効果 | 導入コスト |
|---|---|---|---|
| 最優先 | lockfile コミット + npm ci | 既知の安全なバージョンのみインストール | 低 |
| 最優先 | ignore-scripts の有効化 | スクリプト実行型攻撃の完全ブロック | 低〜中 |
| 高 | バージョン厳密固定 + overrides | 自動アップグレードによる被害を防止 | 低 |
| 高 | MFA / OIDC Trusted Publishing | アカウント乗っ取りの防止 | 低 |
| 中 | min-release-age の設定 | 公開直後の攻撃に対するクールダウン | 低 |
| 中 | CI/CDのエグレス制限 | マルウェアのC2通信をブロック | 中 |
| 推奨 | SCAツール / マルウェアスキャン | 既知・未知の悪意あるパッケージの検出 | 中〜高 |
まとめ
Axios事件とShai-Hulud 2.0は、npmエコシステムのサプライチェーン攻撃が「起こるかどうか」ではなく「いつ起こるか」の問題であることを示しています。攻撃は年々洗練されており、国家レベルのアクターが関与するケースも増えています。
しかし、防御策は決して複雑ではありません。lockfileをコミットし、npm ci を使い、ignore-scripts を有効化し、バージョンを固定する——この基本を徹底するだけでも、2つの事例で見たような攻撃の大部分を防ぐことができます。
「便利だからこそ危険」というオープンソースの宿命に対して、まずは今日からできる対策を一つずつ実行していきましょう。

