npm v12 がインストールスクリプトを既定オフに - サプライチェーン攻撃時代の破壊的変更とCI移行

npm v12 がインストールスクリプトを既定オフに - サプライチェーン攻撃時代の破壊的変更とCI移行

作成日:
読了:16
更新日:
この記事を読む人におすすめPR / Amazonアソシエイト

当サイトは Amazon.co.jp を宣伝しリンクすることで紹介料を得る手段を提供する、Amazonアソシエイト・プログラムの参加者です。価格・在庫はリンク先の最新情報をご確認ください。

axiosTanStack と、npm サプライチェーン攻撃の事件を追ってきました。これらに共通していたのは、npm install した瞬間に走る postinstall 系スクリプトが攻撃の起点になるという構造です。pnpm 10 の防御設定でも触れたとおり、パッケージマネージャ側で「入れた瞬間にやられる」を止める流れが加速していました。

そしてついに、npm 本体が同じ方向へ舵を切りました。npm v12 は、依存パッケージのインストールスクリプトを既定でオフにします。npm v12.0.0 は 2026年7月8日にリリースされ、安定版パッチの v12.0.1 が7月10日に続きました(出典: npm/cli releases)。この破壊的変更は 2026年6月9日に GitHub の公式 Changelog で予告されていたものです(出典: GitHub Changelog)。

この記事では、3つの破壊的変更、CI が壊れる仕組み、approve-scripts を使った承認ワークフロー、そして2FAバイパストークンの段階的無効化と trusted publishing への移行までを、実務目線で整理します。

npm v12とは何か - 「暗黙の信頼」からの決別

これまでの npm は、依存パッケージに含まれる preinstall / install / postinstall スクリプトを、インストール時に何の確認もなく自動実行してきました。ネイティブモジュールのビルド(node-gyp)などに必要な仕組みですが、同時に攻撃者にとって最も手軽な実行経路でもありました。汚染された依存を1つ引き込むだけで、開発者や CI の環境で任意コードが走ってしまう。これが「暗黙の信頼」の代償です。

npm v12 は、この前提を反転させます。依存パッケージのスクリプトは明示的に許可したものだけが実行され、それ以外は既定でスキップされます。pnpm 10 が先に採用した「デフォルトで止めて、必要なものだけ承認する」設計に、npm 本体が追いついた形です。

3つの破壊的変更

npm v12 の破壊的変更は、大きく3つあります。いずれも「明示的な許可がなければリスクのある解決・実行を行わない」という同じ思想に基づいています。

変更1: allowScripts が既定オフ

最も影響が大きいのがこれです。依存パッケージの preinstall / install / postinstall スクリプトは、明示的な許可がない限り実行されなくなりました。

対象はいわゆる postinstall だけではありません。node-gyp によるネイティブビルドや、git 依存・file 依存・link 依存で走る prepare スクリプトも同じくブロックされます。つまり、これまでインストール時に自動でビルドが走っていたパッケージは、v12 では何もせずスキップされる可能性があります。

変更2: --allow-git が既定 none

--allow-git の既定値が none になりました。git 依存(package.json に GitHub URL などを直接書いたもの、および推移的に含まれるもの)は、明示的な許可がないと解決されません。

これは単なる利便性の変更ではなく、脆弱性を塞ぐための変更です。従来、.npmrc で Git 実行ファイルのパスを差し替えることで、--ignore-scripts を設定していても任意コードを実行できてしまう抜け道がありました。git 依存の解決を既定で止めることで、この経路を封じます。

なお、このフラグ自体は npm v12 でいきなり登場したわけではなく、11.10 から 11.15 系にかけて先行して段階導入されていました。導入バージョンについては公式 Changelog と Socket の記述に食い違いがあるため、ここでは幅を持たせて扱います。

変更3: --allow-remote が既定 none

--allow-remote の既定値も none になりました。HTTPS tarball など、リモート URL を直接指した依存(直接・推移的とも)は、明示的な許可がないと解決されません。レジストリを経由しない任意 URL からのコード取り込みを既定で止める狙いです。

一方で、--allow-file--allow-directory は既定の変更がありません。ローカルの file 依存・directory 依存はこれまでどおり解決されます。

なぜ今か - Shai-Hulud / axios が突いた postinstall の穴

これほど大きな破壊的変更に踏み切った背景には、ここ1年で連続したサプライチェーン攻撃があります。いずれも postinstall を悪用したものです。

  • Shai-Hulud(2025年9月): postinstall 経由で自己増殖するワームが、500を超えるパッケージを汚染しました(@ctrl/tinycolor など)。
  • Shai-Hulud 2.0(2025年11月): 796の npm パッケージがバックドア化されました。
  • Mini Shai-Hulud(2026年5月): 170を超える npm および PyPI のパッケージへ拡散しました。
  • axios 乗っ取り(2026年3月): 週間およそ1億ダウンロードのパッケージが標的になりました(詳細はaxiosの記事)。

出典: Palo Alto Unit 42, Aikido

自己増殖するワームが半年で数百から数千のパッケージへ広がる状況では、「利用者が個別に注意する」という運用はもう限界です。npm がデフォルトの挙動そのものを安全側へ倒したのは、この構造的な圧力への回答だと言えます。

「ソフトスキップ」の挙動とCIでの落とし穴

ここで注意したいのが、v12 の既定挙動がハードエラーではない点です。未承認のスクリプトはスキップされ警告が出るだけで、インストール自体は成功します。これを「ソフトスキップ」と呼びます(出典: Socket)。

一見やさしい挙動ですが、CI では逆に落とし穴になります。ネイティブビルドが必要なパッケージのスクリプトが黙ってスキップされたまま npm install が成功扱いになると、ビルド済みバイナリが存在しないのに次のステップへ進んでしまうからです。結果として、後続のテストや実行時に「モジュールが見つからない」「ネイティブアドオンがロードできない」といった、原因のわかりにくいエラーで CI が壊れます。インストールのログに出た警告を見落とすと、追跡が難しくなります。

WARNING

npm install は成功しているのにアプリが動かない」という症状が v12 移行後に出たら、まずインストール時の「スクリプトをスキップした」警告を疑ってください。ソフトスキップは失敗を隠すため、成功ステータスを鵜呑みにできません。

strict-allow-scripts でハード失敗に

CI では、このソフトスキップをハード失敗に変換しておくのが安全です。strict-allow-scripts を有効にすると、未承認スクリプトのスキップがそのままインストールの失敗になります。

.npmrc(CI 用)
strict-allow-scripts=true

こうしておけば、「知らないうちに必要なビルドがスキップされていた」状態を、後続ではなくインストールの時点で検知して止められます。承認漏れをレビューのタイミングで気づけるようになるわけです。

実践: approve-scripts での承認ワークフローと package.json 管理

必要なスクリプトは、明示的に承認して動かします。npm v12 には承認用のコマンドが用意されています。

Shell
# ブロックされているスクリプトを確認し、信頼するものを承認する
npm approve-scripts
 
# 特定のパッケージのスクリプト実行を拒否する
npm deny-scripts

npm approve-scripts を実行すると、既定でブロックされている対象の一覧が表示され、信頼するパッケージを承認できます。逆に「これは絶対に走らせない」を明示したいときは npm deny-scripts を使います(出典: Aikido)。

重要なのは、承認した許可リストが package.json に書き込まれる点です。この許可リストは必ず Git にコミットしてください。コミットしておけば、どの依存にスクリプト実行を許したかがレビュー対象になり、CI や他メンバーの環境でも同じ承認状態が再現されます。pnpm 10 の onlyBuiltDependencies と同じ「許可リスト方式」で、新しく増えた依存が勝手にスクリプトを走らせることはありません。

CI移行チェックリスト

v12 への移行は、いきなり本番 CI で v12 を使うのではなく、事前準備を挟むのが安全です。npm 11.16.0 以降には、v12 の挙動を先取りして警告を出す仕組みがあります。これを使って移行します。

  1. ローカルまたは検証環境で npm を 11.16.0 以降に上げる。
  2. 通常どおり npm install を走らせ、「スクリプトをスキップした」警告を確認する。どの依存がスクリプト実行を必要としているかを洗い出す。
  3. 洗い出した信頼できるパッケージを npm approve-scripts で承認する。
  4. 更新された package.json(許可リスト)を Git にコミットする。
  5. CI の .npmrcstrict-allow-scripts=true を設定し、承認漏れがハード失敗になるようにする。
  6. この状態で npm v12 に上げ、CI が通ることを確認する。

NOTE

事前準備の肝は、v12 に上げる前に許可リストを確定させてコミットしておくことです。ここを飛ばして v12 に上げると、必要なビルドがまとめてスキップされ、原因調査から始める羽目になります。

なお、npm v12 が対応する Node.js のバージョン範囲は ^22.22.2 || ^24.15.0 || >=26.0.0 です。移行前に、CI や本番のランタイムがこの範囲に収まっているかも確認しておきましょう。v12 は Node 24 / 26 LTS へのバックポートも Node リリースチームで検討中ですが、これは未確定です(出典: Socket)。

2FAバイパストークンの段階的無効化

npm v12 のリリースと並行して、npm 側では公開(publish)に使うトークンの締め付けも進みます。対象は、2FA を回避できる設定になっている Granular Access Token(GAT)です。

フェーズ1は 2026年8月上旬に開始します。該当トークンから、次の操作ができなくなります。

  • トークンの作成・削除
  • パスワード・メールアドレス・2FA 設定の変更
  • パッケージアクセスやメンテナーの変更
  • trusted publishing 設定の編集
  • org / team の管理

フェーズ2は 2027年1月頃を予定しています。ここでは、これらのトークンからの直接 publish 権限そのものが剥奪され、private パッケージの読み取りと、2FA 承認を要するステージ公開のみが可能になります(出典: The Hacker News, Socket)。

長寿命の publish トークンを CI に置いている運用は、フェーズ2の時点で publish できなくなります。移行の猶予は限られているので、8月のフェーズ1が始まる前に、自分のプロジェクトが該当トークンに依存していないかを棚卸ししておくべきです。

trusted publishing(OIDC) への移行という本命

では、トークンの代わりに何を使うのか。GitHub が推奨しているのは、長寿命の publish トークンをやめ、trusted publishing(OIDC)または人間の承認を挟むステージ公開へ移行することです(出典: GitHub Changelog)。

trusted publishing は、GitHub Actions などの CI ワークフローと npm レジストリを OIDC で暗号的に紐づける仕組みです。ワークフローの実行そのものが身元の証明になるため、盗まれて悪用される長寿命トークンが存在しません。実際、axios 事件では、正規リリースが OIDC で公開されていた一方、攻撃者は盗んだトークンで手動公開して OIDC を回避しました。トークンという「持ち出せる鍵」を排除することが、この種の攻撃への根本的な対策になります。

publish 権限を人間の手で守る場合は、物理的な MFA デバイスを併用すると強度が上がります。フィッシング耐性のあるハードウェアキーで publish 操作を保護しておけば、認証情報が漏れても公開そのものを止められます。

まとめ - 今日やるべきこと

  • npm v12 は依存パッケージの preinstall / install / postinstall スクリプトを既定でオフにする。node-gyp ビルドや git/file/link 依存の prepare も対象。
  • --allow-git--allow-remote の既定が none になり、git 依存・リモート URL 依存は明示許可がないと解決されない。
  • 既定挙動はソフトスキップ(インストールは成功)。CI では strict-allow-scripts=true でハード失敗に変えておく。
  • 必要なスクリプトは npm approve-scripts で承認し、package.json の許可リストをコミットする。
  • 移行はまず npm 11.16.0 以降で警告を確認し、許可リストを確定してから v12 へ上げる。
  • 2FA バイパス設定の GAT は 8月にフェーズ1、2027年1月頃にフェーズ2で publish 権限が段階的に無効化される。trusted publishing(OIDC)への移行を今から進める。

今日できる最初の一歩は、ローカルの npm を 11.16.0 以降に上げて npm install を1回走らせ、スキップされたスクリプトの警告を確認することです。自分のプロジェクトがどの依存のスクリプト実行に頼っているかを把握するところから始めてください。

参考リンク

【緊急】npm パッケージ「axios」が乗っ取られた事件まとめ — 2026年3月31日のサプライチェーン攻撃

【緊急】npm パッケージ「axios」が乗っ取られた事件まとめ — 2026年3月31日のサプライチェーン攻撃

13

2026年3月31日、週間1億ダウンロードを超える人気パッケージ「axios」のnpmアカウントが乗っ取られ、悪意あるバージョン1.14.1と0.30.4が公開されました。攻撃の全容、影響を受けるバージョンの確認方法、今後の防御策をまとめます。

【サプライチェーン攻撃】2026年3月31日、npmパッケージ「axios」乗っ取り事件の全容と対策

【サプライチェーン攻撃】2026年3月31日、npmパッケージ「axios」乗っ取り事件の全容と対策

17

週1億ダウンロードを誇るnpmパッケージ「axios」が、北朝鮮系脅威アクターによって乗っ取られた事件を解説。攻撃の手口、影響を受けたバージョン、自分のプロジェクトの確認方法、今後の防御策をまとめます。

pnpm のパッチ機能に潜むパストラバーサル - CVE-2026-50015 とは何か

pnpm のパッチ機能に潜むパストラバーサル - CVE-2026-50015 とは何か

16

2026年6月、pnpm のパッチ適用パイプライン(patchedDependencies / @pnpm/patch-package)に複数のパストラバーサル脆弱性が公開されました。中心となる CVE-2026-50015 は、悪意ある .patch ファイルの diff --git ヘッダに ../ を仕込むと、pnpm install 実行時にパッケージディレクトリ外へ任意ファイルを書き込める問題です。攻撃の仕組み、影響バージョン、修正版、自分が影響を受けるかの確認方法と対処を、GHSA と NVD の一次情報で整理します。