要するに
NPMサプライチェーン攻撃は、2024年だけで3,000以上の悪意のあるパッケージに急増し、2026年3月のAxios侵害は、トップ10に入るパッケージでさえ安全ではないことを証明しました。このガイドでは、API開発者が必要とする防御のすべての層、すなわちロックファイルの強制、postinstallスクリプトのブロック、プロベナンス検証、行動分析ツール、そして攻撃対象領域を縮小するアーキテクチャの選択について説明します。
はじめに
2026年3月31日に発生したAxiosサプライチェーン攻撃は、初めてのnpm侵害ではありませんでした。そして、これが最後になることもないでしょう。しかし、週8,300万回のダウンロードと、乗っ取られた単一のメンテナーアカウントを通じて展開されたクロスプラットフォームのRAT(リモートアクセスツール)は、JavaScriptエコシステムが受けた最も大きな警鐘でした。
これが一般的な「依存関係を更新してください」というアドバイスと異なるのは、Axios攻撃が従来のあらゆる防御を迂回した点です。悪意のあるコードはAxios自体にはなく、postinstallフックをトリガーする偽の依存関係を介して注入されました。攻撃期間中にnpm installを実行した場合、ロックファイルは役に立ちませんでした。まだバージョンを固定していなかった場合、バージョン固定も役に立ちませんでした。
API開発者は特に危険にさらされています。テストスクリプト、CI/CDパイプライン、モックサーバー、HTTPクライアントはすべてnpmから取得されます。ツールチェーン内の単一の侵害されたパッケージが、開発マシンからAPIキー、データベース認証情報、クラウドトークンを漏洩させる可能性があります。
このガイドでは、基本的なロックファイル衛生から高度な行動分析まで、7つの保護層について説明します。
レイヤー1:ロックファイルの強制
ロックファイルが重要な理由
A ロックファイルは、インストール時のすべてのパッケージとその推移的依存関係の正確なバージョンを記録します。ロックファイルがない場合、npm installはセマンティックバージョニング範囲に一致する最新バージョンを解決します。package.jsonに"axios": "^1.14.0"と記述されており、悪意のある1.14.1がレジストリに存在する場合、その悪意のあるバージョンが取得されます。
ルール
常にロックファイルをコミットしてください。 package-lock.json (npm)、yarn.lock (Yarn)、pnpm-lock.yaml (pnpm)、またはbun.lock (Bun) のいずれであっても、バージョン管理下に置くべきです。
CI/CDではフリーズインストールを使用してください。 自動化された環境でnpm installを実行しないでください。以下のフリーズロックファイル相当のものを使用してください。
# npm
npm ci
# yarn
yarn install --frozen-lockfile
# pnpm
pnpm install --frozen-lockfile
# bun
bun install --frozen-lockfile
npm ciはnode_modulesを削除し、ロックファイルから厳密にインストールします。ロックファイルがpackage.jsonと一致しない場合、失敗します。これにより、解決の予期せぬ事態を防ぎます。
プルリクエストでロックファイルの差分を確認してください。 PRがpackage-lock.jsonを変更した場合、何が変更されたかを確認してください。新しい依存関係、バージョンアップ、レジストリURLの変更はすべて精査が必要です。Socket.devのような自動化ツールは、PRレビューで疑わしいロックファイルの変更をフラグ付けできます。
ロックファイルのギャップ
ロックファイルは予期せぬバージョン解決から保護しますが、最初のインストールからは保護しません。攻撃期間中にプロジェクトを初期化したり、新しい依存関係を追加したりすると、悪意のあるバージョンが固定されてしまいます。これが、ロックファイルがレイヤー1であり、唯一のレイヤーではない理由です。
レイヤー2:postinstallスクリプトの無効化
主要な攻撃ベクトル
Axios攻撃、ua-parser-js攻撃、event-stream攻撃、その他数十の攻撃はすべて同じメカニズムを使用しました。それは、npm install中に任意のコードを実行するpostinstallスクリプトです。このフックは、アプリケーションコードが実行される前、パッケージをレビューする前、そしてランタイムセキュリティツールが介入できる前に実行されます。
スクリプトをグローバルにブロックする
あなたの.npmrcに追加します:
ignore-scripts=true
またはCLI経由で設定します:
npm config set ignore-scripts true
これにより、パッケージのインストール中にすべてのライフサイクルスクリプト(preinstall、install、postinstall、prepare)が実行されるのを防ぎます。
スクリプトを必要とするパッケージの処理
一部のパッケージは、ネイティブコンパイルのためにpostinstallスクリプトを必要とします(例:bcrypt、sharp、またはsqlite3)。2つの選択肢があります:
オプション1:インストール後にスクリプトを選択的に実行する
npm ci --ignore-scripts
npm rebuild bcrypt sharp
オプション2:許可リストを使用する (npm 10+)
信頼できるパッケージのみがスクリプトを実行できるようにする.scriptsrc.jsonを作成します:
{
"allowScripts": {
"bcrypt": true,
"sharp": true
}
}
オプション3:プリビルドバイナリを使用する
以前はネイティブコンパイルが必要だった多くのパッケージが、現在ではプリビルドバイナリを提供しています。例えばsharpは、ほとんどのプラットフォーム向けにプリビルドバイナリを同梱しており、postinstallコンパイルの必要性を排除しています。依存関係を確認してください。思っているよりもスクリプトの例外が少なく済むかもしれません。
PackageGateの注意点
2026年1月、研究者たちはnpm、pnpm、vlt、およびBunに影響を与える「PackageGate」と呼ばれる6つのゼロデイ脆弱性を開示しました。一つの発見として、Gitベースの依存関係は、ライフサイクルスクリプトが無効になっている場合でもコード実行を可能にする設定ファイルを運ぶ可能性があることが挙げられます。もしpackage.jsonが依存関係としてGit URLを参照している場合、ignore-scriptsだけでは十分ではありません。それらの依存関係を特定のコミットハッシュに固定し、リポジトリの内容を監査してください。
レイヤー3:厳密なバージョン固定
セマンティックバージョン範囲の使用をやめる
npm install --saveのデフォルトの動作では、キャレットプレフィックス付きでパッケージが追加されます:
{
"axios": "^1.14.0"
}
^は「1.14.0と互換性がある」ことを意味し、最新の1.x.xバージョンに解決されます。Axios攻撃の際、それは1.14.1に解決されることを意味しました。
代わりに厳密なバージョンを固定します:
{
"axios": "1.14.0"
}
npmがデフォルトで厳密なバージョンを保存するように設定します:
# .npmrc
save-exact=true
save-prefix=''
推移的依存関係にオーバーライドを使用する
直接の依存関係には、独自の依存関係があります。推移的な依存関係が侵害された場合、直接の依存関係を固定しても効果はありません。オーバーライドを使用して推移的な解決を制御します:
{
"overrides": {
"axios": "1.14.0",
"plain-crypto-js": "npm:empty-npm-package@1.0.0"
}
}
Yarnの場合:
{
"resolutions": {
"axios": "1.14.0"
}
}
pnpmの場合:
{
"pnpm": {
"overrides": {
"axios": "1.14.0"
}
}
}
トレードオフ
厳密な固定は、自動パッチアップデートが行われないことを意味します。バージョンを手動で上げる必要があり、メンテナンスのオーバーヘッドが発生します。このトレードオフは意図的なものであり、自動的な更新よりも制御された更新を選択しています。セキュリティに敏感なプロジェクトでは、このトレードオフは価値があります。
レイヤー4:パッケージのプロベナンスを検証する
プロベナンスの意味
npmのプロベナンス証明は、公開されたパッケージをそのソースコードおよびビルド環境にリンクし、公開透明性台帳に記録されたSigstore署名を使用します。プロベナンスが有効なCI/CDパイプラインからパッケージが公開されると、パッケージには以下の暗号学的証明が含まれます:
- どのソースリポジトリからビルドされたか
- どのCI/CDシステムがビルドしたか
- どのコミットがビルドをトリガーしたか
プロベナンスの確認方法
npm audit signatures
これにより、インストールされたパッケージが有効なプロベナンス証明を持っていることを確認します。開発者のマシンから手動で公開されたパッケージにはプロベナンスはありません。
悪意のあるAxiosバージョンにはOIDCプロベナンスバインディングがなく、対応するGitHubコミットもありませんでした。自動化されたプロベナンスチェックが標準的な慣行であれば、この攻撃はすぐに警告を発したでしょう。
自身のパッケージでプロベナンスを有効にする
npmパッケージを公開する場合、CI/CDでプロベナンスを有効にします:
# GitHub Actionsの例
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
あなたの.npmrcに追加します:
provenance=true
制限事項
プロベナンスはオプトインです。ほとんどのnpmパッケージにはまだありません。また、プロベナンスはパッケージがどこでビルドされたかのみを証明します。ソースコードが安全であることを証明するものではありません。侵害されたCI/CDパイプラインは、有効なプロベナンスを持つ悪意のあるパッケージを公開する可能性があります。
レイヤー5:行動分析ツールの使用
脆弱性スキャンを超えて
npm auditやSnykのような従来のツールは、既知の脆弱性(CVE)データベースと照合してチェックします。これらは報告された問題を検出しますが、ゼロデイ攻撃は見逃します。Axios侵害は、公開された時点ではどのCVEデータベースにも含まれていませんでした。
行動分析ツールは、パッケージについて報告されていることではなく、パッケージが何をするかを検査します。
Socket.dev
Socketは、インストール中および実行時のパッケージの振る舞いを分析します。次の点をフラグ付けします:
- インストール中のネットワーク要求
- パッケージディレクトリ外のファイルシステムアクセス
- シェルコマンドの実行
- 環境変数の収集
- 難読化されたコードパターン

GitHubと統合すると、新しい依存関係が疑わしい動作を示すと、SocketはPRにコメントします。Axios攻撃のplain-crypto-js依存関係は、難読化されたコード、postinstall中のネットワーク要求、パッケージディレクトリ外のファイルシステム書き込みなど、複数のSocketアラートをトリガーしたでしょう。
# Socket CLIをインストール
npm install -g @socketsecurity/cli
# プロジェクトをスキャン
socket scan
Snyk
Snykは、リスクスコア、エクスプロイト成熟度データ、修正ガイダンスを備えた脆弱性管理を提供します。既知の脆弱性には強いですが、ゼロデイの行動検出には弱いです。
# Snyk CLIをインストール
npm install -g snyk
# プロジェクトをテスト
snyk test

多層的なアプローチ
両方を使用してください。SocketはSnykが見逃す行動異常を検出します。SnykはSocketが提供するよりも豊富なコンテキストで既知の脆弱性を検出します。ベースラインとしてnpm auditを追加してください:
# ベースライン
npm audit
# 行動分析
socket scan
# 脆弱性管理
snyk test
CI/CDでこれら3つすべてをゲートとして実行してください。重大な発見があった場合はビルドをブロックすべきです。
レイヤー6:依存関係の表面積を最小化する
より深い問題
あなたのnode_modules内のすべてのパッケージは信頼の決定です。Axios攻撃は、週8,300万回ダウンロードされるパッケージを侵害しました。平均的なNode.jsプロジェクトには数百の推移的依存関係があります。それぞれが潜在的な攻撃ベクトルです。
最も効果的な防御策は、防御すべき依存関係を減らすことです。
依存関係ツリーの監査
# 総依存関係数をカウント
npm ls --all | wc -l
# 重複をチェック
npm ls --all | sort | uniq -c | sort -rn | head -20
各依存関係について以下の質問をしてください:
- 言語やランタイムがこれをネイティブに提供していますか?Node.js 18+には、以前はパッケージが必要だった
fetch、crypto、URL、FormData、および多くのユーティリティが含まれています。 - この依存関係は数十の推移的依存関係を引き込んでいますか?50のサブ依存関係を持つ単一のパッケージは、攻撃対象領域を50倍にします。
- これをベンダー化できますか?小さなユーティリティパッケージの場合、ソースをプロジェクトにコピーすることで、サプライチェーンのリスクを完全に排除できます。
一般的なパッケージのネイティブな代替手段
| パッケージ | ネイティブの代替手段 | 利用可能バージョン |
|---|---|---|
| axios, node-fetch, got | fetch (グローバル) |
Node.js 18 |
| uuid | crypto.randomUUID() |
Node.js 19 |
| dotenv | --env-file フラグ |
Node.js 20.6 |
| chalk | util.styleText() |
Node.js 21.7 |
| glob | fs.glob() |
Node.js 22 |
| path-to-regexp | ネイティブURLパターンAPI | Node.js 23 |
特にAPIテストについて
APIテストワークフローは、通常、HTTPクライアントライブラリ、アサーションライブラリ、テストランナー、およびモックサーバーに依存しています。それぞれの依存関係が攻撃対象領域となります。

Apidogは、スタック全体を単一のプラットフォームで置き換えます:
- HTTPクライアント:組み込みで、npm依存関係は不要
- アサーション:組み込みのアサーションを備えたビジュアルテストビルダー
- テストランナー:Apidog CLIを介したCI/CD統合による自動テストシナリオ
- モックサーバー:動的応答を持つスマートモックで、Expressやサードパーティのモックライブラリは不要
- ドキュメンテーション:API仕様から自動生成
APIテストワークフローをApidogに移行することで、テストインフラから数十のnpm依存関係を排除できます。依存関係が少ないということは、信頼の決定が少なく、攻撃ベクトルも少ないことを意味します。
Apidogを無料で試して、APIテストスタックを統合しましょう。
レイヤー7:ネットワークおよびランタイム監視
既知の悪質なドメインをブロックする
サプライチェーン攻撃の後、コマンド&コントロールインフラをネットワークレベルでブロックします:
# /etc/hostsに追加
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
CI/CD環境では、既知の安全なドメインへのアウトバウンドネットワークアクセスを制限してください。ほとんどのビルドプロセスは、npmレジストリ、Gitホスト、およびデプロイターゲットへのアクセスのみを必要とします。その他はデフォルトでブロックされるべきです。
CI/CDにStepSecurity Harden-Runnerを使用する
StepSecurityのHarden-Runnerは、GitHub Actionsのワークフローをリアルタイムで監視します。npm install開始から1.1秒以内にAxiosドロッパーがC2に接触したことを検出しました。このツールは以下を提供します:
- GitHub Actionsのアウトバウンドネットワーク監視
- プロセス実行追跡
- ファイル整合性監視
- 異常な動作に対する自動アラート
# GitHub Actions
- uses: step-security/harden-runner@v2
with:
egress-policy: audit # 厳格モードでは 'block'
ランタイムプロセス監視
開発マシンについては、Node.jsによって起動された疑わしい子プロセスをフラグ付けするエンドポイント検出・応答(EDR)ツールを検討してください。Axios RATは、npmインストールプロセス内からosascript (macOS)、cscript (Windows)、python3 (Linux) を起動しました。これらの子プロセスパターンは検出可能です。
推奨される.npmrc設定
上記レイヤーを組み合わせた、セキュリティ強化された.npmrcファイルは以下のとおりです:
# 厳密なバージョンを固定
save-exact=true
save-prefix=
# ライフサイクルスクリプトを無効化
ignore-scripts=true
# 公開用のプロベナンスを有効化
provenance=true
# 公式レジストリを使用
registry=https://registry.npmjs.org/
# 公開に2FAを要求
auth-type=web
# 監査レベルの閾値
audit-level=moderate
このファイルをリポジトリにコミットし、すべてのチームメンバーが同じセキュリティ設定を使用するようにしてください。
CI/CDセキュリティパイプラインの例
以下は、7つのレイヤーすべてを強制するGitHub Actionsワークフローの例です:
name: セキュアなビルド
on: [push, pull_request]
jobs:
security-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: step-security/harden-runner@v2
with:
egress-policy: audit # 厳格モードでは 'block'
- uses: actions/setup-node@v4
with:
node-version: 22
# レイヤー1+2:フリーズロックファイル、スクリプトなし
- run: npm ci --ignore-scripts
# レイヤー3:予期せぬバージョンがないことを確認
- run: npm ls --all > deps.txt
# レイヤー4:プロベナンスの確認
- run: npm audit signatures
# レイヤー5:行動分析
- run: npx socket scan
# レイヤー5:脆弱性スキャン
- run: npx snyk test
# レイヤー1:ベースライン監査
- run: npm audit --audit-level=moderate
# 許可されたネイティブ依存関係のみを再ビルド
- run: npm rebuild sharp bcrypt
npmセキュリティの今後の動向
人気パッケージに対するプロベナンスの義務化
npmは、特定のダウンロードしきい値を超えるパッケージに対してプロベナンス証明を義務付けることを検討しています。これにより、Axios攻撃を可能にした手動のトークンベース公開が防止されるでしょう。
二人制リリース承認
金融取引が二重承認を必要とするように、ダウンロード数の多いパッケージは、リリースを承認するために二人目のメンテナーが必要になる場合があります。単一の侵害されたアカウントだけでは不十分となるでしょう。
ランタイム権限スコープ設定
Denoは、明示的に許可されない限り、スクリプトがアクセスできるもの(ネットワーク、ファイルシステム、環境変数)を既に制限しています。Node.jsも同様のパーミッションモデルを検討中です。これが実装されれば、postinstallスクリプトはネットワーク要求を行ったり、ファイルシステムにアクセスしたりするために明示的な許可が必要になります。
パッケージマネージャーの収束
pnpmの厳格な分離モデル(パッケージは宣言された依存関係のみにアクセスできる)は、多くの依存関係混同攻撃を防ぎます。npmが同様の厳格さを採用するにつれて、攻撃対象領域は縮小します。
よくある質問
npmにおけるサプライチェーン攻撃とは何ですか?
npmにおけるサプライチェーン攻撃とは、アプリケーションを直接狙うのではなく、ソフトウェアの依存関係チェーンを標的とするものです。攻撃者は、パッケージメンテナーアカウントを侵害したり、人気のあるパッケージに悪意のあるコードを注入したり、似た名前のタイポスクワットパッケージを公開したりします。依存関係をインストールまたは更新すると、悪意のあるコードがマシンまたはCI/CDパイプラインで実行され、認証情報を盗んだり、バックドアをインストールしたり、データを外部に漏洩させたりします。
npm auditはサプライチェーン攻撃から保護するのに十分ですか?
いいえ。npm auditは既知の脆弱性(CVE)データベースと照合してチェックします。Axios侵害のようなゼロデイ攻撃は、発生時にはどのCVEデータベースにもありません。パッケージについて報告されていることではなく、パッケージが何をするかを検査するSocket.devのような行動分析ツールが必要です。npm auditはベースラインとして使用し、唯一の防御策とはしないでください。
npmの使用を完全にやめるべきですか?
いいえ。npmは依然として最大のパッケージエコシステムであり、ほとんどのパッケージは安全です。目標は、厳密なバージョン固定、ロックファイルの強制、スクリプトのブロック、および依存関係の最小化を通じて、リスクを減らすことです。各依存関係が必要かどうかを検討し、可能な場合はネイティブな代替手段を使用してください。
Apidogはnpmサプライチェーンリスクの削減にどのように役立ちますか?
Apidogは、API開発向けに組み込みのHTTPクライアント、テストランナー、モックサーバー、およびドキュメントジェネレーターを提供します。これにより、Axios、node-fetch、Jest、Express(モック用)、その他のテスト依存関係といったnpmパッケージの必要性がなくなります。npm依存関係が少ないということは、API開発ワークフローにおける攻撃ベクトルが少ないことを意味します。
npmにおけるパッケージのプロベナンスとは何ですか?
パッケージのプロベナンスは、Sigstoreを使用して公開されたパッケージをそのソースリポジトリおよびCI/CDビルド環境に暗号学的にリンクします。これは、パッケージがどこでどのようにビルドされたかを証明します。npm audit signaturesでプロベナンスを確認できます。開発者マシンから手動で公開されたパッケージにはプロベナンスがなく、これはダウンロード数の多いパッケージにとっては危険信号です。
悪意のあるnpmパッケージはどのくらいありますか?
Snykは2024年に3,000を超える悪意のあるnpmパッケージを特定しました。2025年第4四半期には、Sonatypeがnpm、PyPI、その他のレジストリ全体で1四半期だけで120,612件のマルウェア攻撃をブロックしました。その数は増加しています。ほとんどの悪意のあるパッケージはダウンロード数の少ないタイポスクワットですが、Axiosのような著名な侵害は、人気のあるパッケージでさえ無縁ではないことを証明しています。
PackageGate脆弱性とは何ですか?
PackageGateは、2026年1月に開示された、npm、pnpm、vlt、およびBunに影響を与える6つのゼロデイ脆弱性のセットです。一つの発見は、Gitベースの依存関係が、ライフサイクルスクリプトが無効になっている場合でもコード実行を可能にする設定ファイルを運ぶ可能性があることを示しています。これは、依存関係がGitリポジトリを参照している場合、ignore-scriptsだけでは十分ではないことを意味します。Git依存関係を特定のコミットハッシュに固定してください。
主要なポイント
- ロックファイルの強制は基礎ですが、攻撃期間中の最初のインストールからは保護されません
.npmrcでignore-scripts=trueを設定してpostinstallスクリプトをグローバルに無効にするsave-exact=trueで厳密なバージョンを固定し、セマンティックバージョン範囲の予期せぬ事態を防ぐnpm audit signaturesでパッケージのプロベナンスを検証し、手動アップロードを検出する- Snyk(既知の脆弱性)と
npm audit(ベースライン)の上にSocket.dev(行動分析)を重ねて使用する - Node.jsネイティブAPIやApidogのような統合プラットフォームを使用することで、依存関係の数を減らす
- StepSecurity Harden-RunnerでCI/CDネットワークのアウトバウンドトラフィックを監視する
すべての依存関係は信頼の決定です。依存関係が少ないほど、攻撃対象領域は小さくなります。検証のレイヤーを多く適用するほど、攻撃者がすり抜けるのが難しくなります。防御は単独ではなく、多層的に構築してください。
