axiosサプライチェーン攻撃を踏まえて開発環境のnpm設定を見直す

セキュリティ

はじめに

2026年3月31日、npmパッケージ「axios」がサプライチェーン攻撃を受けました。メンテナーのアカウントが侵害され、悪意あるコードを仕込んだ axios@1.14.1axios@0.30.4 が公開されました。npm install を実行するだけでトロイの木馬がインストールされる仕組みで、約2〜3時間の間に公開されたバージョンを取り込んだ環境が影響を受けた可能性があります。

この事件をきっかけに、筆者のメイン開発環境の npm 設定を見直しました。今回は .npmrc を使った ignore-scriptsmin-release-age の設定、そして @lavamoat/allow-scripts を組み合わせた対策手順をまとめます。

攻撃の仕組み

今回の攻撃は postinstall フックを悪用したものです。問題のバージョンには悪意あるパッケージ plain-crypto-js が依存関係として追加されており、npm install を実行するだけで postinstall に登録されたスクリプトが自動実行されます。

// plain-crypto-js  package.json(抜粋)
{
  "scripts": {
    "postinstall": "node setup.js"
  }
}

.npmrc による対策

ignore-scripts の設定

.npmrc に以下を追加することで、npm install 時に postinstall などのライフサイクルスクリプトが実行されなくなります。

# .npmrc
ignore-scripts=true

これにより今回のような postinstall を悪用した攻撃を防ぐことができます。

min-release-age の設定

min-release-age はパッケージの公開から一定期間が経過していないバージョンをインストール対象から除外する設定です。公開直後の悪意あるバージョンを自動的に取り込まないようにするための「クールダウン」機能です。

# .npmrc
ignore-scripts=true
min-release-age=7d

注意:min-release-age は npm 11.10.0 以降 でサポートされた機能です。node --versionnpm --version で使用中のバージョンを確認し、古い場合はアップグレードが必要です。

allow-scripts による例外設定

ignore-scripts=true を設定すると、bcryptesbuildなどのネイティブモジュールのビルドに postinstall を使うパッケージが動作しなくなります。そのような場合は @lavamoat/allow-scripts を使って信頼できるパッケージのスクリプトだけを個別に許可できます。

セットアップ手順

まず開発依存としてインストールします。

npm i -D @lavamoat/allow-scripts

production 環境で必要な場合は -D を外してインストールしてください。

次に以下のコマンドを実行して .npmrc への設定追加と package.json へのポリシー自動生成を行います。

# .npmrc に ignore-scripts=true を追加し、ポリシーの雛形を生成する
npx --no-install allow-scripts setup
npx --no-install allow-scripts auto

allow-scripts auto を実行すると、package.json にライフサイクルスクリプトを持つパッケージが列挙されます。許可するパッケージを true、不要なものを false に設定します。

// package.json(抜粋)
{
  "lavamoat": {
    "allowScripts": {
      "bcrypt": true,
      "esbuild": true,
      "sharp": false
    }
  }
}

ポリシーを設定したあとは npm install の代わりに以下のコマンドで依存関係のインストールと許可スクリプトの実行を行います。

# インストール後に許可リストのスクリプトだけを実行する
npm install && npx --no-install allow-scripts run

package.jsonscripts に登録しておくと運用しやすくなります。

// package.json(抜粋)
{
  "scripts": {
    "setup": "allow-scripts run"
  }
}

Docker 環境での対応

Docker を使った開発環境では、Dockerfile 内の npm install にも同じ設定を適用する必要があります。

設定前の Dockerfile

FROM node:22-slim

WORKDIR /app

COPY package*.json ./

# postinstall スクリプトが無制限に実行される
RUN npm ci

COPY . .

設定後の Dockerfile

FROM node:22-slim

WORKDIR /app

COPY package*.json ./

# .npmrc をコピーして ignore-scripts と min-release-age を有効化する
COPY .npmrc ./

# ignore-scripts によって postinstall の自動実行を防止できる
RUN npm ci

# allow-scripts で許可したスクリプトだけを実行する
RUN npm run setup

COPY . .

.npmrc はプロジェクトルートに置いて COPY .npmrc ./ でコンテナ内に取り込みます。これにより CI/CD 環境を含むすべての Docker ビルドで同じポリシーが適用されます。

グローバル npm 設定への追加

プロジェクト単位の .npmrc に加えて、ホストマシンのグローバル設定 ~/.npmrc にも同様の設定を追加しておくことを推奨します。プロジェクトを問わず npm install を実行するすべての場面で保護が機能するようになります。

# グローバル設定に追記する
npm config set --location=global ignore-scripts true
npm config set --location=global min-release-age 7d

または ~/.npmrc を直接編集します。

# ~/.npmrc
ignore-scripts=true
min-release-age=7d

まとめ

今回の axios サプライチェーン攻撃を踏まえて、.npmrcignore-scriptsmin-release-age、そして @lavamoat/allow-scripts を組み合わせた対策手順をまとめました。Docker 環境では .npmrc をコンテナに取り込むことで CI/CD を含めた一貫した設定が実現できます。ぜひこの機会に開発環境の npm 設定を見直してみてください。

コメント

タイトルとURLをコピーしました