見出し画像

npm v12がインストール時のスクリプト実行をやめた | 攻撃の「入口」が閉まる

npm(エヌピーエム)は、JavaScriptのライブラリを取り込むための定番ツールです。その`npm install`と打つと、依存パッケージを取ってくる途中で、パッケージが用意したスクリプトが自動で走ります。ビルドや初期設定のための便利な仕組みですが、ここが長らくサプライチェーン攻撃(正規のソフトや部品に不正なコードを紛れ込ませて広める攻撃)の入口になってきました。

2026年7月8日に公開されたnpm v12.0.0は、この自動実行を既定でやめました。依存パッケージのインストール時スクリプトは、明示的に許可しない限り実行されません。パッケージ管理の世界で「信頼が既定」から「承認が既定」への切り替えが、npm本体でも起きたことになります。


「インストールしただけで動く」とはどういうことか

npmのパッケージには、`preinstall`・`install`・`postinstall`といった「ライフサイクルスクリプト」を仕込めます。これは本来、C言語で書かれた部分をその場でビルドする、といった正当な用途のための仕組みです。従来のnpmは、依存パッケージにこれらのスクリプトがあれば、インストールの過程で自動的に実行していました。

攻撃者から見ると、この自動実行は都合のいい足がかりになります。あるセキュリティ解説の言い方を借りれば、攻撃コードがインストール中に走るので、そのパッケージをコードの中で読み込む(import する)必要すらありません。`npm install`を一度通しただけで、悪意のあるコードが手元の環境で動いてしまいます。

実例も相次ぎました。2026年3月31日には、週に約1億回ダウンロードされる人気ライブラリのAxios(アクシオス)で、メンテナーのアカウントが乗っ取られる事件が起きています。このとき攻撃者はAxios本体のコードには手を付けず、悪意のある別の依存パッケージを裏で足し、その`postinstall`スクリプトから遠隔操作型のマルウェアを送り込みました。2025年には、GitHubやnpmの認証情報を盗んで自分自身を他のパッケージへ複製していく「Shai-Hulud(シャイ・フルード)」と呼ばれるワームも広がっています。いずれも、インストール時に何かが自動で走るという前提の上で成り立つ攻撃でした。

v12で既定が反転した

npm v12.0.0が変えたのは、大きく3点です。いずれも「これまで手を挙げれば有効にできた安全策を、最初からオンにした」という性質のものです。

中心になるのが、依存パッケージのライフサイクルスクリプトを既定で実行しなくなったことです。許可されていないスクリプトは黙って飛ばされ、代わりに「スキップしたパッケージの一覧」が表示されます。C言語部分の自動ビルド(`node-gyp`による処理)も、宣言されたスクリプトと同じように扱われ、許可リストになければ止まります。

残る2点は、依存の取得元をしぼる変更です。Gitのリポジトリを直接指す依存(Git依存)と、URLで直接ダウンロードするtarball(リモート依存)が、どちらも既定では解決されなくなりました。これらは正規の設定ファイルを差し替える、より静かな実行経路になり得るため、明示許可制に寄せられています。

許可は`npm approve-scripts`というコマンドで与えます。承認した内容は`package.json`の`allowScripts`という項目に、バージョン番号付きで書き込まれます。この設定はコミットしてチームで共有する前提です。「誰が、どのパッケージの、どのバージョンのスクリプトを信頼したか」がリポジトリの履歴として残る、という設計になっています。

従来はnpm installの途中でpostinstallスクリプトが自動実行されていたのに対し、npm v12では承認ゲートが1つ挟まり、許可されたスクリプトだけが実行される流れの違いを示した図

何が「壊れる」か

破壊的変更なので、これまで通っていたインストールが止まる場面が出てきます。影響が大きいのは、インストール時にビルドやバイナリのダウンロードを行うパッケージ、Gitのリポジトリを直接指した依存、URL指定のtarball依存です。心当たりがある構成ほど、更新後にCI(継続的インテグレーション。コードを自動でビルド・テストする仕組み)が赤くなる可能性があります。

移行の手順は公式が案内しています。まずnpm 11.16.0以降に上げると、v12でブロックされる箇所が、止まるのではなく警告として表示されます。その状態で一度インストールを回し、警告に出たパッケージのうち信頼できるものを`npm approve-scripts`で承認する。更新した`package.json`をコミットしてから、あらためてv12へ上げる、という順番です。いきなりv12にせず、警告の段階で棚卸ししておくと、本番のビルドが突然止まる事故を避けやすくなります。

あわせて、公開用トークンまわりの締め付けも進みます。二要素認証を回避できる設定になっていた一部のアクセストークンは、2026年8月初旬に重要な操作で認証を飛ばせなくなり、2027年1月頃には直接の公開もできなくなる予定です。

「信頼が既定」から「承認が既定」へ

この変更は、npm単独の思いつきではありません。同じ考え方は、ほかのパッケージ管理ツールが先に採り入れていました。pnpm(ピーエヌピーエム)は2025年1月のv10で、インストール時スクリプトを既定でブロックする方針に切り替えています。Bun(バン)も、多くの一般的なパッケージだけを組み込みの許可リストで通し、それ以外は明示的に信頼を宣言させる作りです。npm本体は、こうした先行例に後から追いついた立場になります。

背景にあるのは、「有名で広く使われているパッケージだから安全」とは言い切れなくなった現実です。攻撃はパッケージの中身そのものより、公開する人のアカウントや自動リリースの仕組みを狙うようになりました。そうなると、利用する側が「何を実行させるか」を既定でしぼっておく方が、守りとして現実的になります。便利さのために全部を最初から信頼する設計から、必要なものだけを名指しで信頼する設計へ、少しずつ重心が移っています。

おわりに

npm v12の変更は、開発者の手元では「インストールが一度うまくいかなくなる」という、地味で面倒な形で現れます。ただ、その面倒さは、これまで自動で通り抜けていた実行経路に、承認という一段を挟んだ結果でもあります。

まずは手元やCIで、インストール時にスクリプトを走らせているパッケージがどれだけあるかを、警告の段階で一度見ておく。そこが、この切り替えに向き合う入口になります。

もっと詳しく知りたい方へ

いいなと思ったら応援しよう!

Haru - AIと働くひとのメモ帳。 励みになります。いただいたチップは活動費に使わせていただきます。