はじめに
npm install を叩くたびに、依存関係の postinstall が何をしているかまで確認している人はそう多くない。npm はこの前提を突いたサプライチェーン攻撃が続いてきたツールで、2026年7月だけでも Jscrambler の侵害パッケージやAsyncAPIのリリースパイプライン侵害が報じられている12。npm 12 でここに機械的な歯止めが入ったと知り、実際に手元で試した。
結果、ブロック自体は効いていたが、復旧手順を伝えているセキュリティ系ニュース記事のコマンドと、実際に npm 12 が案内してくるコマンドが一致しなかった。二次情報だけで対処しようとすると詰まる箇所がある。
TL;DR
- npm 12(2026-07-08 リリース)で
allow-scripts・allow-git・allow-remoteの3つがデフォルトで無効化された - ローカル依存の
postinstallを実際にブロックさせて確認した。file: 依存の postinstall は実行されない - github: 依存を追加すると
EALLOWGITで即座にインストールが止まる - 復旧コマンドはニュース記事が伝える
npm approve-scripts --allow-scripts-pendingではなく、実際はnpm install-scripts approve <pkg>(npm 12.0.1 実機で確認)
背景・課題
npm はライフサイクルスクリプト(preinstall/install/postinstall)を npm install の完了までに自動実行する仕様を持ち続けてきた。ここに悪意あるコードを仕込む手口は目新しくなく、直近でも PostCSS を騙る偽パッケージや、Bitwarden 系パッケージの侵害が報告されている3。
npm 12 のリリースノートには git 依存・tarball URL 依存について次の記述がある。
allow-git and allow-remote now default to 'none'; set them to 'all' (or 'root') to install git or user-supplied tarball-URL dependencies.
— npm/cli v12.0.0 Release Notes(2026-07-08)
postinstall 自動実行を制御する allow-scripts 側のデフォルト変更は、このリリースノートの文面には明記がない。実際に npm 12.0.1 の npm config list を確認すると空リストになっていることが分かる(後述の検証1)。依存パッケージの postinstall 自動実行・git 依存・ユーザー指定 tarball URL 依存という3つの経路が、それぞれ別の設定値でまとめて塞がれた形になる。ここまでは公式情報と設定値の確認だが、実際に何が起きるかは動かして確認しないと分からない。
やったこと
環境構築
グローバルインストールは今回の検証環境では依存解決エラー(MODULE_NOT_FOUND: promise-retry)で失敗したため、ローカルディレクトリに --prefix でインストールした。
mkdir -p /tmp/npm12-test && cd /tmp/npm12-test
npm install npm@12.0.1 --prefix .
./node_modules/.bin/npm --version
# => 12.0.1
npm config list -l で該当の設定値を確認すると、リリースノートどおり無効化された状態になっている。
./node_modules/.bin/npm config list -l | grep -i "script\|allow-git\|allow-remote"
allow-git = "none"
allow-remote = "none"
allow-scripts = [""]
allow-scripts-pending = false
ignore-scripts = false
ignore-scripts 自体は false(従来どおりスクリプト実行を許可する設定)のままだが、allow-scripts が空リストのため実質的にどのパッケージのスクリプトも許可リストに載っていない。挙動を決めているのは ignore-scripts ではなく allow-scripts 側だと分かる。
検証1: postinstall は実行されるか
postinstall でファイルを書き込むだけのダミーパッケージを file: 依存として追加した。
# evil-pkg/package.json
{
"name": "evil-pkg",
"version": "1.0.0",
"scripts": {
"postinstall": "node -e \"require('fs').writeFileSync('PWNED.txt','pwned')\""
}
}
npm install
added 1 package, and audited 3 packages in 594ms
found 0 vulnerabilities
npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts evil-pkg@1.0.0 (postinstall: node -e "require('fs').writeFileSync('PWNED.txt','pwned')")
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.
ls node_modules/evil-pkg/PWNED.txt
# => No such file or directory
postinstall は実行されず、PWNED.txt は作られなかった。警告メッセージに実行すべきコマンドが npm install-scripts ls / npm install-scripts approve <pkg> として明示されている点に注目したい。
検証2: git 依存は解決されるか
github: 形式の依存を1件だけ追加して npm install した。
# package.json
"dependencies": { "is-odd": "github:jonschlinkert/is-odd" }
npm error code EALLOWGIT
npm error Fetching packages of type "git" have been disabled
npm error Refusing to fetch "is-odd@github:jonschlinkert/is-odd"
警告ではなくエラーで即座に停止した。postinstall のブロックは「インストールは進むがスクリプトだけ止まる」挙動だったのに対し、git 依存のブロックは「インストール自体が失敗する」挙動になっており、npm 12 内でも制御の強さが経路によって異なる。
検証3: 復旧コマンドは記事どおりか
npm 12 の変更を報じたセキュリティニュースの記事では、スクリプトを許可する手順として次のコマンドが紹介されていた。
「
npm approve-scripts --allow-scripts-pendingを実行し、結果として生成される allowlist を package.json ファイルにコミットします」
この形のコマンド(npm approve-scripts)は npm 12.0.1 の実機には存在しない。実際に警告メッセージが案内していたコマンドで試すと、次のように通った。
npm install-scripts ls
1 package has install scripts blocked because they are not covered by allowScripts:
evil-pkg@1.0.0 (postinstall: node -e "require('fs').writeFileSync('PWNED.txt','pwned')")
Run `npm install-scripts approve <pkg>` to allow, or `npm install-scripts deny <pkg>` to deny.
npm install-scripts approve evil-pkg
Approved file:../../evil-pkg:
added file:../../evil-pkg
package.json には allowScripts フィールドが追記され、再インストールすると postinstall が実際に実行された。
{
"name": "consumer",
"dependencies": { "evil-pkg": "file:../evil-pkg" },
"allowScripts": { "file:../../evil-pkg": true }
}
rm -rf node_modules && npm install
ls node_modules/evil-pkg/PWNED.txt
# => 存在する(許可後は実行される)
コマンド名の食い違いは、記事執筆時点のnpm 11系プレリリース版の想定コマンド名が変わった可能性もあるが、確認できる一次情報はリリースノートの設定値の記述までで、コマンド名までは明記されていない。実機で確認した npm install-scripts 系サブコマンドが npm 12.0.1 時点の正解になる。
ハマりポイント
ignore-scripts を見ても分からない
ignore-scripts は npm に以前からある設定で、true にすると全パッケージのスクリプトを一律止められる。npm 12 の変更はこれとは別軸で、allow-scripts という許可リスト方式が新設された形になる。npm config get ignore-scripts だけを見て「false だから止まっていないはず」と判断すると誤る。
二次情報のコマンド名は検証してから使う
ニュース記事やまとめ記事に載っているコマンド例は、CLIのメジャーバージョンアップ直後は特に、実際のリリース版と食い違うことがある。今回のように破壊的変更が入ったバージョンでは、警告メッセージ自身が案内するコマンド(npm install-scripts ls / approve / deny)を一次情報として使うほうが確実だった。
まとめ
npm 12 の allow-scripts / allow-git / allow-remote はいずれも実機で機能していることを確認できた。file 依存の postinstall は警告付きでスキップされ、git 依存は EALLOWGIT で即エラーになる。CI や既存プロジェクトを npm 12 に上げる際は、依存ツリーの中で本当に postinstall を必要とするパッケージ(node-gyp を使うネイティブモジュール等)を洗い出し、npm install-scripts approve で明示的に許可してから移行するほうが安全に見える。
自動アップグレードの手が回っていないプロジェクトでも、npm install-scripts ls を実行するだけで現在ブロックされているパッケージの一覧を先に確認できる。
著者視点の発見ポイント
セキュリティニュース記事の復旧コマンド(npm approve-scripts --allow-scripts-pending)をそのままコピペしても動かない。実際に npm 12.0.1 を動かして得られる警告メッセージには npm install-scripts approve <pkg> としか書かれておらず、二次情報の文言と実機の挙動を照合してはじめてこのズレに気づいた。CLI破壊的変更のまとめ記事は、コマンド名まで鵜呑みにせず自分の手元で1回動かして確認する価値がある。
参考リンク
- npm/cli v12.0.0 Release Notes — allow-git/allow-remote のデフォルト変更の一次情報として引用
- npm 12 Disables Install Scripts by Default to Reduce Supply Chain Risk - The Hacker News — 変更の経緯と(実機と食い違っていた)復旧コマンド例の引用元
-
Compromised jscrambler 8.14.0 npm Release Drops Rust Infostealer During Install - The Hacker News(Jscrambler の npm パッケージが侵害された2026-07-11の事案) ↩
-
The npm Threat Landscape: Attack Surface and Mitigations - Unit 42(AsyncAPI リポジトリのリリースパイプライン侵害を含む更新版レポート) ↩
-
Malicious npm Packages Pose as PostCSS Tools to Deliver Windows RAT - The Hacker News ↩