ちょっと雑ですが、npmパッケージのバージョンアップと脆弱性対応の方法をまとめました。これがベストかはわからないけど、一つのやり方として紹介します。
node: v14.15.1
npm: v8.1.3
yarn: v1.22.17
パッケージのバージョンアップ
-
バージョンアップ必要なパッケージを調査
-
npm-check-updates
をインストールnpm install -g npm-check-updates // or yarn add global npm-check-updates
-
バージョンアップが必要なパッケージをリストアップ
ncu > @nuxtjs/eslint-config 5.0.0 → 6.0.1 > @nuxtjs/eslint-config-typescript 3.0.0 → 6.0.1 > eslint 7.24.0 → 8.1.0 > eslint-config-prettier 7.2.0 → 8.3.0 > eslint-plugin-prettier 3.3.0 → 4.0.0 > eslint-webpack-plugin 2.4.1 → 3.0.1
-
-
バージョンを書き換え
-
上記内容で package.json を最新バージョンに書き換え
ncu -u
-
修正後の package.json でインストール
npm install // or yarn install > npm ERR! While resolving: xxx@1.0.0 > npm ERR! Found: eslint@8.1.0 > npm ERR! node_modules/eslint > npm ERR! dev eslint@"8.1.0" from the root project > npm ERR! > npm ERR! Could not resolve dependency: > npm ERR! peer eslint@"^7.27.0" from @nuxtjs/eslint-config@6.0.1 > npm ERR! node_modules/@nuxtjs/eslint-config > npm ERR! dev @nuxtjs/eslint-config@"6.0.1" from the root project
=> 今回は以下のバージョンコンフリクトが発生した
- ルートで
eslint@8.1.0
が指定されている -
@nuxtjs/eslint-config@6.0.1
がeslint@"^7.27.0"
(>=7.27.0 && <8.0.0) に依存している
- ルートで
-
-
コンフリクトしたバージョンを調整
-
pakcage.json を修正
npm install eslint@7.32.0 // or yarn add eslint@7.32.0
=> eslint を
8.1.0
=>7.32.0
(7系の最新) 戻している -
改めてインストール
npm install // or yarn install
=> エラーなくインストールできたので完了
-
脆弱性を含むパッケージを確認
-
リストアップ
npm audit // or yarn audit > (一部抜粋) > glob-parent <5.1.2 > Severity: high > Regular expression denial of service - https://github.com/advisories/GHSA-ww39-953v-wcq6 > fix available via `npm audit fix --force` > Will install nuxt@2.13.3, which is a breaking change > node_modules/scssfmt/node_modules/glob-parent > node_modules/watchpack-chokidar2/node_modules/glob-parent > chokidar 1.0.0-rc1 - 2.1.8 > Depends on vulnerable versions of glob-parent > node_modules/scssfmt/node_modules/chokidar > node_modules/watchpack-chokidar2/node_modules/chokidar > scssfmt * > Depends on vulnerable versions of chokidar > Depends on vulnerable versions of globby > node_modules/scssfmt > watchpack-chokidar2 * > Depends on vulnerable versions of chokidar > node_modules/watchpack-chokidar2 > watchpack 1.7.2 - 1.7.5 > Depends on vulnerable versions of watchpack-chokidar2 > node_modules/watchpack > webpack 4.44.0 - 4.46.0 > Depends on vulnerable versions of watchpack > node_modules/webpack > @nuxt/webpack * > Depends on vulnerable versions of cssnano > Depends on vulnerable versions of webpack > node_modules/@nuxt/webpack > @nuxt/builder >=2.14.0 > Depends on vulnerable versions of @nuxt/webpack > node_modules/@nuxt/builder > nuxt >=2.14.0 > Depends on vulnerable versions of @nuxt/webpack > node_modules/nuxt > fast-glob <=2.2.7 > Depends on vulnerable versions of glob-parent > node_modules/scssfmt/node_modules/fast-glob > globby 8.0.0 - 9.2.0 > Depends on vulnerable versions of fast-glob > node_modules/scssfmt/node_modules/globby > 30 vulnerabilities (7 moderate, 23 high)
- 読み方
-
glob-parent <5.1.2
-
glob-parent
のバージョンが5.1.2
未満は脆弱性を含む。5.1.2
以上にアップデート必要
-
- 脆弱性の詳細: https://github.com/advisories/GHSA-ww39-953v-wcq6
- 正規表現を利用したReDoS攻撃に関する脆弱性があるらしい
-
npm audit fix --force
で fix できるけど、nuxt
が2.13.3
に戻ってしまう
-
nuxt
=>@nuxt/webpack
=>webpack
=>watchpack-chokidar2
=>chokidar
=>glob-parent
のように依存している
-
- 読み方
-
脆弱性を含むパッケージの依存ツリーを確認
npm ls glob-parent // or yarn list --pattern glob-parent xxx@1.0.0 ├─┬ eslint-webpack-plugin@3.0.1 │ └─┬ webpack@4.46.0 │ └─┬ watchpack@1.7.5 │ └─┬ watchpack-chokidar2@2.0.1 │ └─┬ chokidar@2.1.8 │ └── glob-parent@3.1.0 ├─┬ eslint@7.27.0 │ └── glob-parent@5.1.2 ├─┬ sass@1.43.3 │ └─┬ chokidar@3.5.2 │ └── glob-parent@5.1.2 deduped ├─┬ scssfmt@1.0.7 │ ├─┬ chokidar@2.1.8 │ │ └── glob-parent@3.1.0 │ └─┬ globby@8.0.2 │ └─┬ fast-glob@2.2.7 │ └── glob-parent@3.1.0 deduped └─┬ stylelint@14.0.0 └─┬ fast-glob@3.2.7 └── glob-parent@5.1.2 deduped
=> どのパッケージからの依存関係でインストールされているかを確認できる
脆弱性を含むパッケージを対処
脆弱性を含むパッケージを利用しないバージョンに強制的に戻す
npm audit fix --force
// yarn audit では fix できない。やりたい場合、https://www.npmjs.com/package/yarn-audit-fix を利用する
=> これで解決することもあるけど、例えばこのケースだと肝心のnuxt
のバージョンが下がってしまうので、今回は使えない(nuxtのバージョンを上げることが目的の一つなので)。
脆弱性を含むパッケージのバージョンを強制的にあげる
この方法だと、脆弱性は解決されますが、依存パッケージのバージョンの範囲を超えて、強制的に脆弱性を含むパッケージのバージョンを上げることになるので、問題なく動作するかどうかは分かりません(保証されません)。
従って、予期しないエラーや動作が発生する可能性がありますので、脆弱性のリスクとこの対応をすることによるリスクを比較して、本当に対応するかを検討する必要があります。
また、対応する場合は、動作確認を手厚くおこないましょう。
-
npm-force-resolutions
をインストール(npmのみ必要。yarn では基本機能に含まれる)npm -g install npm-force-resolutions -D
-
package.json
にresolutions
の設定を追加"resolutions": { "glob-parent": "^5.1.2" }
-
指定したパッケージのバージョンを強制的にアップデート
npx npm-force-resolutions
=> これにより、
package-lock.json
が強制的に書き換える -
package-lock.json
を元にインストールするnpm ci // or yarn install
=>
npm install
だと、package.json
をもとにインストールされるのでもとに戻ってしまうので要注意。 -
パッケージが更新されたか確認
-
脆弱性確認
npm audit // or yarn audit (一部抜粋) > 10 moderate severity vulnerabilities
=>
glob-parent
はリストアップされなくなった -
パッケージのバージョン確認
xxx ├─┬ eslint-webpack-plugin@3.0.1 │ └─┬ webpack@4.46.0 │ └─┬ watchpack@1.7.5 │ └─┬ watchpack-chokidar2@2.0.1 │ └─┬ chokidar@2.1.8 │ └── glob-parent@^5.1.2 invalid: "^3.1.0" from node_modules/watchpack-chokidar2/node_modules/chokidar ├─┬ eslint@7.27.0 │ └── glob-parent@^5.1.2 invalid: "^5.0.0" from node_modules/eslint ├─┬ sass@1.43.3 │ └─┬ chokidar@3.5.2 │ └── glob-parent@^5.1.2 invalid: "~5.1.2" from node_modules/chokidar ├─┬ scssfmt@1.0.7 │ ├─┬ chokidar@2.1.8 │ │ └── glob-parent@^5.1.2 invalid: "^3.1.0" from node_modules/scssfmt/node_modules/chokidar │ └─┬ globby@8.0.2 │ └─┬ fast-glob@2.2.7 │ └── glob-parent@^5.1.2 invalid: "^3.1.0" from node_modules/scssfmt/node_modules/fast-glob └─┬ stylelint@14.0.0 └─┬ fast-glob@3.2.7 └── glob-parent@^5.1.2 invalid: "^5.1.2" from node_modules/fast-glob
=> 強制的にバージョンを変えているので
invalid
になっているけど、5.1.2
以降の5系の最新が指定されている
-
-
動作確認
一通りアプリを動かして、問題ないか確認する。今回は問題なく動いた -
(参考)
npx npm-force-resolutions
の影響調査
今後、パッケージを追加する時に、何か考慮する必要があるかを調べておく-
新しいパッケージを追加したときに、
glob-parent
がもとに戻るかnpm install serverless // or yarn add serverless
=> 問題なし(脆弱性を含むバージョンには戻らなかった)
-
パッケージを削除した際に、
glob-parent
がもとに戻るかnpm uninstall serverless // or yarn remove serverless
=> 問題なし(脆弱性を含むバージョンには戻らなかった)
-
glob-parent
自体のバージョンを変更できるかnpm install -D glob-parent@3 // or yarn add -D glob-parent@3 > npm ERR! Invalid Version: ^5.1.2
=> エラー発生。変更するには一旦
package-lock.json
を削除してやり直す必要あり
-