はじめに
こんばんは、mirukyです。
2026年3月31日、npmの Axios パッケージ(週間1億ダウンロード)がサプライチェーン攻撃を受けました。攻撃者はメンテナーへの標的型ソーシャルエンジニアリングでセッションを乗っ取り、悪意ある依存 plain-crypto-js を注入した axios@1.14.1 と axios@0.30.4 をレジストリに公開しました。このパッケージは postinstall フックで多段階RATを展開し、macOS・Windows・Linuxすべてに対応する本格的なバックドアを設置するものです。影響はOpenAIのmacOS署名パイプラインにまで及び、証明書のローテーションが実施される事態となりました。
OWASP Top 10:2025でも Software Supply Chain Failures(サプライチェーンの障害)が第3位 に新設されるなど、依存パッケージの脆弱性管理はもはや「やったほうがいい」ではなく「やらなければならない」フェーズに入っています。
本記事では、GitHubとnpm(package.json)の機能を活用して脆弱なパッケージを ダウンロードする前に防ぐ ための設定・確認事項を8つに厳選してまとめます。
npmを前提に解説しますが、pnpmやyarnでも多くの対策が適用可能です(overridesは pnpm.overrides / resolutions、auditや .npmrc の ignore-scripts も同様に使えます)。
以前、AIコーディング時代のセキュリティについて広く取り上げた記事を書いています。本記事はその中でもサプライチェーン防御に特化した、より実践的な内容です。
最初にまとめ
| 対策 | 何を防ぐか | 対象 |
|---|---|---|
| ① Dependabot Alerts | 既存依存の既知の脆弱性 | GitHub設定 |
| ② dependabot.yml | 依存関係の陳腐化 | リポジトリ設定 |
| ③ Dependency Review Action | PRでの脆弱な依存の混入 | GitHub Actions |
| ④ npm audit in CI | ビルド時の脆弱性見逃し | CI/CDパイプライン |
| ⑤ overrides | 推移的依存の脆弱性 | package.json |
| ⑥ package-lock.json管理 | 再現性のないビルドと改ざん | ファイル管理 |
| ⑦ npm audit signatures | 改ざんされたパッケージ | npmレジストリ |
| ⑧ ignore-scripts | 悪意あるinstallスクリプト | .npmrc |
① Dependabot Alertsとセキュリティアップデートを有効化する
GitHubが提供する Dependabot は、リポジトリの依存関係をGitHub Advisory Databaseと照合し、脆弱性が検出されるとアラートを発行する機能です。さらに セキュリティアップデート を有効にすると、脆弱性を修正するPRを自動生成してくれます。
設定手順
リポジトリの Settings > Advanced Security から、以下の2つを有効にします。
| 設定項目 | 説明 |
|---|---|
| Dependency graph | 依存関係の可視化。これが土台になる |
| Dependabot alerts | 脆弱性検出時にアラートを発行 |
| Dependabot security updates | 脆弱性を修正するPRを自動作成 |
パブリックリポジトリでは Dependency graph と Dependabot alerts がデフォルトで有効です。プライベートリポジトリでは手動で有効にする必要があります。
アラートの優先順位付け
Dependabotは大量のアラートを発行する場合があります。GitHubは CVSS(深刻度) と EPSS(悪用される確率) の2軸で優先順位を付けることを推奨しています。
| 指標 | 意味 | 判断基準 |
|---|---|---|
| CVSS | 脆弱性の技術的な深刻度(0.0〜10.0) | 9.0以上は即対応 |
| EPSS | 30日以内に悪用される確率(0〜1) | 0.5以上は優先対応 |
npmの場合、推移的依存(間接的な依存)に脆弱性がある場合でも、Dependabotは親パッケージの更新や不要なサブ依存の削除を含むPRを自動生成します。
② dependabot.ymlで依存関係の自動更新を設定する
セキュリティアップデートとは別に、 バージョン更新 を定期的にチェックする設定もあります。.github/dependabot.yml をリポジトリに配置することで、依存関係を常に最新に保つことができます。
基本的な設定例
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
timezone: "Asia/Tokyo"
open-pull-requests-limit: 10
groups:
# devDependenciesをまとめて1つのPRにする
dev-dependencies:
dependency-type: "development"
# productionの依存はpatchとminorをグループ化
production-minor-patch:
dependency-type: "production"
update-types:
- "minor"
- "patch"
主要な設定オプション
| オプション | 説明 |
|---|---|
schedule.interval |
チェック頻度。daily、weekly、monthly 等から選択 |
open-pull-requests-limit |
同時に開くPRの上限(デフォルト5) |
groups |
複数の依存更新を1つのPRにまとめる。PR数の爆発を防げる |
ignore |
特定のパッケージやバージョン範囲を除外 |
versioning-strategy |
バージョン制約の更新方法。increase(最小バージョンを引き上げ)がアプリ向け |
groups を活用しないと、依存パッケージの数だけPRが作られて通知が溢れます。development と production を分けてグループ化するのが実用的です。
GitHub Actionsのピン留め
サプライチェーン攻撃はnpmパッケージだけでなく、GitHub Actionsも標的になります。2026年4月にGitHubが発表した「Securing the open source supply chain across GitHub」でも、 ActionsをフルレングスのコミットSHAにピン留めする ことが最重要対策として挙げられています。
# dependabot.ymlにGitHub Actionsの自動更新も追加
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
dependabot.ymlにこの設定を追加すると、Actionsのバージョンが更新されたときにPRを自動生成してくれます。ただし、 外部からのPRでActionsのSHAが変更されている場合は疑ってください 。Dependabotが作ったPRであることを必ず確認しましょう。
③ Dependency Review ActionでPR時に脆弱性をブロックする
Dependabot alertsは既存の依存関係に対して脆弱性を検出しますが、 新たに追加される依存関係 に脆弱性がないかをPR時点でチェックするのが Dependency Review Action です。
ワークフロー設定
name: Dependency Review
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
deny-licenses: GPL-3.0, AGPL-3.0
主要なオプション
| オプション | 説明 |
|---|---|
fail-on-severity |
指定した深刻度以上の脆弱性があればPRを失敗させる。low、moderate、high、critical
|
deny-licenses |
禁止するライセンスを指定 |
allow-licenses |
許可するライセンスのホワイトリスト |
Dependency Review Actionはパブリックリポジトリでは無料で利用できます。プライベートリポジトリではGitHub Code Securityのライセンスが必要です。
ブランチ保護ルール(またはRuleset)と組み合わせて、このチェックをマージの必須条件にすれば、 脆弱なパッケージが追加されたPRはマージできなくなります 。
④ npm auditをCI/CDパイプラインに組み込む
npm audit は、 package-lock.json に記載されたすべての依存パッケージをnpm Advisory Databaseと照合し、既知の脆弱性を検出するコマンドです。
CIワークフロー例
name: Security Audit
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npm audit --audit-level=high
audit-levelの使い分け
| レベル | 説明 | 推奨用途 |
|---|---|---|
critical |
criticalのみ検出 | 既存プロジェクトへの段階導入 |
high |
high以上を検出 | 本番環境のCI/CD |
moderate |
moderate以上を検出 | セキュリティ要件が厳しいプロジェクト |
low |
low以上を検出 | 新規プロジェクト |
npm audit は脆弱性を検出するだけで修正はしません。自動修正には npm audit fix を使いますが、CIでは検出のみにとどめ、修正は手動で行うのが安全です。 npm audit fix --force はメジャーバージョンの変更を含む場合があり、互換性を壊す可能性があります。
npm audit は package-lock.json が存在しないと正確に動作しません。後述する「⑥ package-lock.jsonをコミットし厳密に管理する」と必ずセットで設定してください。
npm auditが検出できないもの
npm audit はnpm Advisory Databaseに登録された 既知のCVEのみ を対象とします。つまり、以下のような脅威には対応できません。
| 脅威 | 例 | npm auditで検出 |
|---|---|---|
| タイポスクワッティング |
axios → axois、lodash → 1odash、npm → npmp
|
不可 |
| 新規公開の悪意あるパッケージ | CVE未登録のマルウェア | 不可 |
| 不審なメンテナ変更 | 突然のオーナー交代後のコード注入 | 不可 |
| 難読化されたコード | base64エンコードされたペイロード | 不可 |
| パッケージの鮮度異常 | 数年放置後に突然更新されたパッケージ | 不可 |
本記事ではGitHubとnpmのネイティブ機能に絞って8つの設定を紹介していますが、これらの「CVE以前の脅威」に対しては、本記事で出典として参照している Socket (socket.dev)のような行動分析ベースのツールが有効です。Socketはパッケージの実際のコードを静的解析し、 70以上のサプライチェーンリスクシグナル を検出します。
- タイポスクワッティング検出 … 人気パッケージと類似した名前のパッケージを自動検出
-
リリースの鮮度分析(release-age / minimumReleaseAge) … パッケージの公開日数、メンテナーの変更履歴、突然の依存追加といった異常を検出。OpenAIは今回のAxios事件で
minimumReleaseAgeを設定していなかったことを根本原因の一つとして公式に開示しています - AI検出 … AIによる潜在的マルウェアのコード分析
- Socket Firewall … パッケージマネージャーとレジストリの間に入り、悪意あるパッケージのインストール自体をブロック
GitHub App、CLI( socket npm / socket npx )、VS Code拡張として利用でき、①〜⑧のネイティブ対策と組み合わせることでより堅牢な防御層を構築できます。
⑤ package.jsonのoverridesで脆弱な推移的依存を強制修正する
Dependabotが自動修正PRを出してくれない場合や、親パッケージのアップデートが追いつかない場合、 overrides フィールドを使って推移的依存のバージョンを強制的に指定できます。
使用例
例えば、some-package が内部で脆弱な vulnerable-dep@1.0.0 に依存している場合、以下のように修正済みバージョンを強制できます。
{
"name": "my-app",
"dependencies": {
"some-package": "^2.0.0"
},
"overrides": {
"vulnerable-dep": "^1.2.3"
}
}
overridesの注意点
| 項目 | 内容 |
|---|---|
| 対応パッケージマネージャー | npm 8.3以降(Node.js 16.14以降に同梱)。yarnの場合は resolutions フィールドを使用 |
| 特定パッケージ配下のみ上書き |
"some-package": { "vulnerable-dep": "^1.2.3" } のようにネスト指定が可能 |
| 互換性リスク | バージョンを強制変更するため、APIの互換性が壊れる場合がある。テストを必ず実行する |
| 一時的な対策として使う | 親パッケージの正式アップデートがリリースされたら overrides を削除する |
{
"overrides": {
"some-package": {
"vulnerable-dep": "^1.2.3"
}
}
}
上記のように書くと、some-package の依存ツリー内にある vulnerable-dep のみが上書きされます。プロジェクト全体に影響を与えたくない場合はこの書き方が安全です。
⑥ package-lock.jsonをコミットし厳密に管理する
package-lock.json は、依存関係の正確なバージョン、取得元URL、整合性ハッシュ(integrity)を記録するファイルです。 これをコミットしないことは、再現性のないビルドを許容することと同義 です。
なぜ重要か
| 観点 | lock fileなし | lock fileあり |
|---|---|---|
| バージョンの再現性 |
^1.0.0 の範囲内で異なるバージョンがインストールされうる |
全環境で同一バージョンがインストールされる |
| 整合性の検証 | 検証なし |
integrity フィールドのSHA-512ハッシュで改ざんを検出 |
| 脆弱性の追跡 | どのバージョンが入っているか不明確 | 正確なバージョンに基づいて npm audit が動作 |
必ず守るべきルール
【npm ci を使う】
CIや本番デプロイでは npm install ではなく npm ci を使います。npm ci は package-lock.json と package.json の整合性が取れない場合にエラーで停止するため、意図しないバージョン変更を防げます。
# 開発環境:package-lock.jsonを更新する場合
npm install
# CI/本番環境:package-lock.jsonに厳密に従う
npm ci
【.gitignoreに入れない】
package-lock.json を .gitignore に追加しているプロジェクトを見かけますが、これはアンチパターンです。ライブラリ開発の場合でも、npmの公式ドキュメントは package-lock.json のコミットを推奨しています。
node_modules/ は .gitignore に入れるべきですが、 package-lock.json は絶対に .gitignore に入れないでください。
⑦ npm audit signaturesでパッケージの真正性を検証する
npmレジストリからダウンロードしたパッケージが、本当にレジストリが配布したものかどうかを検証する機能が npm audit signatures です。
レジストリ署名とProvenance
| 種別 | 内容 |
|---|---|
| レジストリ署名(Registry Signatures) | npmレジストリがパッケージに付与するデジタル署名。パッケージが改ざんされていないことを証明 |
| Provenance(来歴証明) | パッケージがどのソースコードから、どのCI/CD環境でビルドされたかをSigstoreの透明性ログで証明 |
実行方法
npm audit signatures
audited 1267 packages in 6s
1267 packages have verified registry signatures
74 packages have verified attestations
Provenanceが付与されたパッケージは、npmのパッケージページに緑色のチェックマークで表示されます。
CIへの組み込み
- run: npm ci
- run: npm audit signatures
Provenanceの生成には、GitHub ActionsまたはGitLab CI/CDからの公開が必要です。パッケージ作成者側の対応ですが、利用者としてはProvenanceが付与されているパッケージを優先的に選ぶことで、サプライチェーンの信頼性を高められます。
2025年7月にnpmがTrusted Publishing(OIDC)のGA(一般提供)を発表し、 Trusted Publishingの採用を強く推奨 する方針に転換しています。しかし2026年3月のAxios攻撃では、Trusted Publishingと長期間有効なnpmトークンが共存していたことが侵害の一因とされています。トークンを使わずにCI/CDから安全にパッケージを公開できる仕組みであり、パッケージ作成者は 古いnpmトークンを廃止 しTrusted Publishingへ完全に移行すべきです。
⑧ .npmrcでignore-scriptsを設定し悪意あるスクリプトを防ぐ
Axios攻撃で使われた plain-crypto-js も、 postinstall スクリプトにマルウェアを仕込む手法で侵害を実現しました。npm install を実行するだけで、ユーザーの意図に関係なく任意のコードが実行される仕組みです。
ライフサイクルスクリプトとは
npmは install 時に以下のスクリプトを自動実行します。
| スクリプト | 実行タイミング |
|---|---|
preinstall |
パッケージのインストール前 |
install |
パッケージのインストール時 |
postinstall |
パッケージのインストール後 |
攻撃者はこの仕組みを悪用し、postinstall にトークン窃取やバックドア設置のコードを仕込みます。
ignore-scriptsの設定
プロジェクトのルートに .npmrc ファイルを作成し、以下を追加します。
ignore-scripts=true
または、コマンドラインで指定することもできます。
npm install --ignore-scripts
副作用と対処法
ignore-scripts=true にすると、正当な postinstall スクリプト(ネイティブモジュールのビルドなど)も実行されなくなります。
| パッケージ例 | postinstallの用途 |
|---|---|
esbuild |
プラットフォーム固有のバイナリをダウンロード |
sharp |
libvipsのネイティブバイナリをビルド |
bcrypt |
C++アドオンをコンパイル |
このようなパッケージが必要な場合、ignore-scripts=true を設定した上で、信頼できるパッケージのスクリプトだけを個別に実行します。
# ignore-scriptsでインストール後、必要なパッケージだけスクリプトを実行
npm install --ignore-scripts
npm rebuild esbuild
npm rebuild sharp
ignore-scripts=true はすべてのサプライチェーン攻撃を防ぐわけではありません。require() 時に実行されるコードには効果がないため、パッケージ自体の信頼性確認(①〜⑦の対策)と組み合わせて使ってください。
おわりに
ここまでお読みいただきありがとうございます。
本記事で紹介した8つの設定をまとめます。
| 対策 | 何を防ぐか | 対象 |
|---|---|---|
| ① Dependabot Alerts | 既存依存の既知の脆弱性 | GitHub設定 |
| ② dependabot.yml | 依存関係の陳腐化 | リポジトリ設定 |
| ③ Dependency Review Action | PRでの脆弱な依存の混入 | GitHub Actions |
| ④ npm audit in CI | ビルド時の脆弱性見逃し | CI/CDパイプライン |
| ⑤ overrides | 推移的依存の脆弱性 | package.json |
| ⑥ package-lock.json管理 | 再現性のないビルドと改ざん | ファイル管理 |
| ⑦ npm audit signatures | 改ざんされたパッケージ | npmレジストリ |
| ⑧ ignore-scripts | 悪意あるinstallスクリプト | .npmrc |
2025年のOWASP Top 10でサプライチェーン攻撃が3位に浮上し、2026年にはAxios(週間1億ダウンロード)やLiteLLM、Trivyといった主要OSSが相次いで侵害を受けています。パッケージの脆弱性管理は開発者全員が取り組むべき課題です。8つすべてを一度に導入する必要はありません。まずは①と④から始めて、段階的に防御層を増やしていくことをお勧めします。
なお、本記事で紹介した8つはGitHubとnpmのネイティブ機能に限定したものです。④で触れたように、タイポスクワッティングやリリースの鮮度異常といった「CVE以前の脅威」にはSocketのような行動分析ツールが有効です。ネイティブ機能で基盤を固めた上で、サードパーティツールを重ねていくのが実践的なアプローチです。
ではまた、お会いしましょう。
参考リンク
GitHub公式ドキュメント
- Dependabot Alerts - GitHub Docs
- Dependabot Security Updates - GitHub Docs
- Dependabot Options Reference - GitHub Docs
- About Dependency Review - GitHub Docs
- dependency-review-action - GitHub
npm公式ドキュメント
GitHub Blog
- Our Plan for a More Secure npm Supply Chain - GitHub Blog
- Securing the Open Source Supply Chain Across GitHub - GitHub Blog
- Cutting Through the Noise: How to Prioritize Dependabot Alerts - GitHub Blog








