2026年3月31日、JavaScriptのHTTPクライアントライブラリ「axios」のnpmパッケージが乗っ取られました。
axiosはフロントエンドからバックエンドまで幅広く使われており、週間ダウンロード数は1億を超えます。攻撃者はメンテナのnpmアカウントを乗っ取り、悪意あるバージョン(1.14.1および0.30.4)を公開しました。npm install を実行しただけで、リモートアクセス型トロイの木馬(RAT)がインストールされる内容です。
私たちQurated Labでも、AI駆動開発の中でこの問題に直面し、即日で対策のhookを実装しました。この記事では、その経験をもとに、npmサプライチェーン攻撃の仕組みと具体的な対策を整理します。
npm install は「コードの実行」である
多くの開発者にとって npm install は日常的なコマンドです。しかし、このコマンドにはあまり意識されていない側面があります。npmパッケージの package.json には postinstall というフィールドを定義でき、npm install を実行すると、そこに書かれたスクリプトが自動的に実行されます。
npm install は「パッケージのダウンロード」ではなく「パッケージ作者が定義した任意のコードの実行」を含むコマンドです。
正規のパッケージであれば、ネイティブバイナリのビルドなど正当な目的で使われる仕組みです。しかし、パッケージが乗っ取られた場合は話が変わります。環境変数の窃取、認証情報の外部送信、バックドアのインストールなど、あらゆる操作が可能になります。
2025年〜2026年、攻撃は加速している
npmのサプライチェーン攻撃は以前から存在していましたが、この1年で質・量ともに大きく深刻化しています。主な事例を時系列で整理します。
2025年8月 - Nx攻撃 モノレポツール「Nx」(週間約400万DL)のGitHub Actionsワークフローの脆弱性を突かれ、npmの公開トークンが盗まれました。バックドア入りのバージョンが公開され、攻撃者はさらにAWSへの侵入にも成功しています(The Hacker News)。
2025年9月 - Shai-Hulud(第1波) フィッシングで盗まれたメンテナの認証情報を使い、500以上のパッケージが一斉に汚染されました。このとき注目されたのは「自己増殖型」という特徴です。感染したパッケージからnpmトークンを窃取し、そのトークンを使ってさらに別のパッケージへ感染を広げるワーム型の攻撃でした。米国のサイバーセキュリティ機関CISAが公式アラートを発出しています。
2025年9月 - Chalk/Debug攻撃 chalk、debug、ansi-stylesなど18のパッケージが乗っ取られました。これらは合計で週間26億ダウンロードを超えるパッケージ群です。偽の2FAリセットメールによるソーシャルエンジニアリングが攻撃の起点で、約5,000万ドル相当の暗号通貨が窃取されたと報告されています。
2025年11月 - Shai-Hulud(第2波) わずか数時間のうちに796パッケージが汚染され、25,000以上のGitHubリポジトリに影響が及びました(Check Point Blog)。
2026年1月 - PackageGate
セキュリティ企業Koiが、npm、pnpm、vlt、Bunに影響する6つのゼロデイ脆弱性を公開しました。git依存関係を悪用することで、後述する --ignore-scripts を設定していても攻撃が成立することが判明しています。pnpm、vlt、Bunは修正済みですが、npm側は「想定された動作」として修正を拒否しました。
2026年3月 - axios攻撃 週間1億DLのaxiosが乗っ取られ、1.x系と0.x系の両方が39分以内に汚染されました(Socket.dev)。冒頭で触れた事例です。
AI駆動開発で特に注意が必要な理由
Claude CodeやGitHub Copilotなど、AIツールが開発の一部を担う現場が増えています。サプライチェーン攻撃と組み合わさると、従来とは異なるリスクが生じます。
AIがnpm installを自動的に実行する場合がある
AIツールは開発の流れの中で npm install <パッケージ名> を提案し、許可すればそのまま実行します。パッケージの信頼性を人間が確認する前にインストールが完了し、postinstallスクリプトが実行される可能性があります。
AIは依存パッケージの安全性を判断できない
AIはパッケージが機能的に適切かどうかは判断できますが、そのパッケージが直近で乗っ取られていないか、依存先に悪意あるコードが混入していないかまでは判断できません。
開発速度の向上がリスクの増幅にもなりうる
AI駆動開発の強みはスピードです。ただし、確認なしに高速でインストールが進む環境は、攻撃者にとっても都合のよい状態です。
実際に私たちのチームでも、AIが提案したパッケージを深く確認せずにインストールしてしまうケースがありました。幸い実害はありませんでしたが、この経験が今回の対策を講じるきっかけになっています。
今すぐできる対策
1. —ignore-scripts をデフォルトにする
最もシンプルで効果的な対策です。--ignore-scripts を付けることで、パッケージのインストール時にライフサイクルスクリプトの実行をスキップできます。
npm install --ignore-scripts
npm ci --ignore-scripts
プロジェクトルートの .npmrc に以下を記述すれば、そのプロジェクトに関わる全員が同じ設定で作業できます。
ignore-scripts=true
ネイティブビルドが必要なパッケージ(sharp、esbuild、bcrypt等)は、インストール後に個別に npm rebuild パッケージ名 で対応できます。
2. Claude Codeのhookでnpm installをガードする
.npmrc による対策はシンプルですが、設定し忘れる可能性があります。特にAI駆動開発では、AIがコマンドを組み立てて実行するため、人間が都度確認するのは現実的ではありません。
そこで有効なのが、Claude Codeの「hook」機能です。hookを使うと、AIがコマンドを実行する前に自動でチェックを挟むことができます。
hookの仕組み
Claude Codeには PreToolUse というイベントがあり、AIがBashコマンドを実行しようとした瞬間に、事前に登録したスクリプトが呼び出されます。スクリプトの終了コードが 2 の場合、そのコマンドの実行はブロックされます。
実装例:npm installガード
以下は、--ignore-scripts が付いていない npm install を検出してブロックするスクリプトの実装例です。
// セキュリティチェック対象のコマンドパターン
const NPM_INSTALL_PATTERNS = [
/\bnpm\s+(install|i|ci|add)\b/,
/\bpnpm\s+(install|i|add)\b/,
/\byarn\s+(install|add)\b/,
/\bnpx\s+/,
];
function detectDangerousCommand(command) {
for (const pattern of NPM_INSTALL_PATTERNS) {
if (pattern.test(command) && !command.includes('--ignore-scripts')) {
return {
dangerous: true,
description: 'npm install without --ignore-scripts is blocked.',
};
}
}
return { dangerous: false };
}
このスクリプトをClaude Codeのhook設定(hooks.json)に登録します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/pre-tool-use.js"
}
]
}
]
}
}
ブロック対象と許可対象の整理
| コマンド | 判定 | 理由 |
|---|---|---|
npm install express | ブロック | postinstallが実行される |
npm ci | ブロック | 同上 |
npx create-next-app | ブロック | パッケージのDLと実行を行う |
npm install --ignore-scripts | 許可 | スクリプト実行をスキップ |
npm run build | 許可 | パッケージインストールではない |
npm test | 許可 | 同上 |
npm rebuild sharp | 許可 | 特定パッケージの明示的なビルド |
hookはプロジェクトの .claude/ ディレクトリに含まれるため、リポジトリをcloneした全員に同じガードが自動的に適用されます。個人の設定に依存しない点が .npmrc との違いです。
3. lockfileを確実に運用する
package-lock.json や yarn.lock をリポジトリにコミットし、インストール時は npm ci --ignore-scripts を使うことで、意図しないバージョンの混入を防げます。
今回のaxios攻撃では、package.json でキャレット指定(^1.14.0)を使っていたプロジェクトが、汚染されたバージョンを自動的に取得してしまいました。lockfileがあれば、この自動更新を防ぐことができます。
4. パッケージ追加時の確認を習慣化する
新しいパッケージを導入する際は、以下の点を確認しておくことをおすすめします。
- メンテナンス状況: 最終更新日、Issue対応の頻度
- 利用規模: npmでの週間ダウンロード数、GitHubのスター数
- 依存の深さ: 依存パッケージの数が少ないほど攻撃面が小さい
- セキュリティスキャン: Socket.devやSnykなどのツールで既知の脆弱性をチェック
—ignore-scripts は万能ではない
ここまで --ignore-scripts を中心に対策を紹介してきましたが、これだけで完全に安全になるわけではない点は明記しておきます。
2026年1月に公開されたPackageGateの脆弱性では、git依存関係を悪用することで --ignore-scripts を迂回できることが示されました。npm CLI 11.10.0以降では --allow-git=none オプションが追加されており、併用が推奨されています。.npmrc に両方を記述する場合は以下のようになります。
ignore-scripts=true
allow-git=none
コマンドラインで指定する場合はこうです。
npm install --ignore-scripts --allow-git=none
OWASPのNPMセキュリティチートシートでも ignore-scripts=true の設定は推奨されていますが、あくまで多層防御の一つとして位置づけられています。単一の対策に頼るのではなく、lockfileの運用、hookによるガード、パッケージの信頼性確認を組み合わせることが重要です。
まとめ
npm install は開発者にとって最も身近なコマンドの一つですが、その裏で任意のコードが実行されうる仕組みは、今や深刻なセキュリティリスクです。
2025年のShai-Hulud、2026年のaxios攻撃と、攻撃の規模も巧妙さも年々増しています。AI駆動開発が広がる中で、「AIが自動的にnpm installを実行した結果、マルウェアが入った」というインシデントがいつ起きてもおかしくない状況です。
対策自体はシンプルです。--ignore-scripts をデフォルトにする。lockfileを使う。AI開発ツール側にもガードを入れる。どれも今日から始められるものばかりです。
まずは自分のプロジェクトの .npmrc を確認するところから始めてみてください。