841-biborokuWebフロントエンドの備忘録

ずっと放置していたnpmパッケージのアップデートに取り組んでみた

この備忘録ブログサイトを作ってから、パッケージの追加やアップデートは何度かしてきましたが、全体をしっかり見直すことはしていませんでした。
今回は、npmパッケージをまとめてバージョンアップデートしてみることに。

いくつかの記事を参考にしながら、自分なりに進めてみた備忘録です。

まずはnpm-check-updates

npm-check-updatesはプロジェクトにインストールされているnpmパッケージのバージョンを一括で確認・更新することができます。

# グローバルインストール
npm install -g npm-check-updates

# パッケージのバージョン確認
ncu

ncu(npm-check-updates)を実行すると、以下の情報が表示されます。

  1. 現在のバージョン
    プロジェクトにインストールされている各パッケージの現在のバージョン
  2. 最新のバージョン
    各パッケージの最新バージョンが表示され、どのパッケージが更新可能かを把握できる
  3. 更新が必要なパッケージの一覧
    どのパッケージを更新する必要があるかが一目でわかる

文字色

意味

🔴赤

メジャーアップグレード/major upgrade

🔵青

マイナーアップグレード/minor upgrade

🟢緑

パッチのアップグレード/patch upgrade

アップデートの実施:パッチからマイナーバージョンへ

一気にすべてのパッケージをアップデートするのが不安だったので、まずはパッチバージョンだけをアップデートすることにしました。

ncu -u -t patch

アップデートが完了した後、変更をコミットし、デプロイを実行。

デプロイでこける😱

npm installを実行してなかった..
package-lock.jsonを更新し、package.jsonと整合性を取る。

デプロイできた!

ncu -u --t minor

問題がなかったので次はマイナーバージョンをアップデート。

📝参考

パッケージのアップデートとknipの活用

パッケージのアップデートを行ったものの、使ってないパッケージやプロジェクト内の整理できてなかった‥

これを機にknipを使って未使用のコードや依存関係を整理してみました。

Knip finds unused files, dependencies and exports in your JavaScript and TypeScript projects. Less code and dependencies lead to improved performance, less maintenance and easier refactorings.

Knip は、JavaScript および TypeScript プロジェクト内の未使用のファイル、依存関係、エクスポートを検出します。コードと依存関係が少ないほど、パフォーマンスが向上し、メンテナンスが減り、リファクタリングが容易になります。

https://github.com/webpro-nl/knip

パッケージを入れて確認‥👀

# インストール
npm install -D knip

# 実行
npx knip

# オプションを使うとmarkdownのレポート形式で出してくれる
npx knip --reporter markdown

たくさん該当しました😂

使用していないファイル、パッケージ、型など削除します。

項目

説明

Unused files

プロジェクト内で参照されていないファイル

Unused dependencies

インストールされているが、コードで使用されていないパッケージ

Unused devDependencies

開発環境でインストールされたが、プロジェクト内で使用されていない開発用パッケージ

Unlisted binaries

package.jsonに記載されていない実行可能なバイナリファイル。

Unused exports

モジュールからエクスポートされているが、他のモジュールで参照されていないエクスポート

Unused exported types

型定義ファイルからエクスポートされているが、他のコードで使用されていない型

消したら動かなくなった😱

image/loader.jsが未使用ファイルとして検出され、誤って削除してしまった。

今後同じような問題を避けるために、以下の手順で設定を変更することにしました。

knip.json

{
  "entry": [
    "image/loader.js",
    "next-sitemap.config.js"
  ]
}

entryに指定されたファイルを未使用ファイルとしてマークしないため、検知されたくないファイルを指定しました!

整理できた!

✂️  Excellent, Knip found no issues.

📝参考

npm auditでセキュリティ脆弱性を確認

npm auditを実行したらcriticalはありませんでしたが、highが10個も該当しました😓

23 vulnerabilities (4 low, 5 moderate, 10 high)

レベル

内容

critical

非常に危険な脆弱性

high

深刻な脆弱性

moderate

影響のある脆弱性

low

低リスクの脆弱性

# npm audit report

axios  0.8.1 - 0.27.2 || 1.3.2 - 1.7.3
Severity: high
Axios Cross-Site Request Forgery Vulnerability - https://github.com/advisories/GHSA-wf5p-g6vw-rhxx
Server-Side Request Forgery in axios - https://github.com/advisories/GHSA-8hc4-vh64-cxmj
fix available via `npm audit fix --force`
Will install @sendgrid/[email protected], which is a breaking change
node_modules/@sendgrid/client/node_modules/axios
node_modules/axios
  @sendgrid/client  7.0.0 - 7.7.0
  Depends on vulnerable versions of axios
  node_modules/@sendgrid/client
    @sendgrid/mail  7.0.0 - 7.7.0
    Depends on vulnerable versions of @sendgrid/client
    node_modules/@sendgrid/mail

braces  <3.0.3
Severity: high
Uncontrolled resource consumption in braces - https://github.com/advisories/GHSA-grv7-fg5c-xmjg
fix available via `npm audit fix`
node_modules/braces

cookie  <0.7.0
cookie accepts cookie name, path, and domain with out of bounds characters - https://github.com/advisories/GHSA-pxg6-pf52-xh8x
No fix available
node_modules/cookie
  @cloudflare/next-on-pages  *
  Depends on vulnerable versions of cookie
  node_modules/@cloudflare/next-on-pages
  youch  2.0.4 - 3.3.3
  Depends on vulnerable versions of cookie
  node_modules/youch

…続く

npm auditを実行して大量の情報が表示されると、おお、、これ全部か……↘

どんな情報が出力されている?

dompurifyを見てみます。

dompurify  3.0.0 - 3.1.2
Severity: high
DOMPurify allows tampering by prototype pollution - https://github.com/advisories/GHSA-mmhx-hmjr-r674
DOMpurify has a nesting-based mXSS - https://github.com/advisories/GHSA-gx9m-whjm-85jf
fix available via `npm audit fix`
node_modules/dompurify

dompurify パッケージの 3.0.0 から 3.1.2 に関する脆弱性が報告されていて、2つの脆弱性が詳細リンクと一緒に記載されている。

npm audit fix を使用することで修正が可能である旨が表示され、最後に影響のあるパッケージのファイルパス(node_modules 配下の dompurify)も記載されている。

npm audit レポートの構成

セクション

説明

パッケージ情報

対象のパッケージ名と影響を受けるバージョン範囲

Severity(深刻度)

脆弱性の深刻度

脆弱性の詳細

脆弱性の名称と内容、影響範囲の概要

Advisory URL

各脆弱性の詳細情報へのリンク

修正方法

npm audit fix による自動修正方法や推奨バージョンへのアップデート案内

パス情報

対象のパッケージの場所
依存関係の深いパスもここにリストされる

修正してみる

fix available via npm audit fixとあるので、npm audit fix dompurifyを実行してみます。

17 vulnerabilities (3 low, 4 moderate, 10 high)

dompurifyのhighが消えて、npm auditレポートの該当件数も減りました!

npm audit fixで解消されるパッケージは、まとめて対応しました。

npm audit fixでは解決できないパッケージ

path-to-regexpを見てみます。

path-to-regexp  4.0.0 - 6.2.2
Severity: high
path-to-regexp outputs backtracking regular expressions - https://github.com/advisories/GHSA-9wv6-86v2-598j
fix available via `npm audit fix`
node_modules/@vercel/routing-utils/node_modules/path-to-regexp
node_modules/path-to-regexp
  @vercel/node  >=2.11.0
  Depends on vulnerable versions of path-to-regexp
  node_modules/@vercel/node
  @vercel/routing-utils  *
  Depends on vulnerable versions of path-to-regexp
  node_modules/@vercel/routing-utils
    @vercel/gatsby-plugin-vercel-builder  *
    Depends on vulnerable versions of @vercel/routing-utils
    node_modules/@vercel/gatsby-plugin-vercel-builder
      @vercel/static-build  >=1.3.0
      Depends on vulnerable versions of @vercel/gatsby-plugin-vercel-builder
      node_modules/@vercel/static-build
    @vercel/redwood  >=0.6.1-canary.0
    Depends on vulnerable versions of @vercel/routing-utils
    node_modules/@vercel/redwood

npm audit fix path-to-regexpを実行してみましたが、解消されません。

出力された脆弱性の詳細情報を確認してみます。

path-to-regexp outputs backtracking regular expressions - https://github.com/advisories/GHSA-9wv6-86v2-598j

path-to-regexp が出力する正規表現にはバックトラッキングが含まれており、悪意のある入力に対して正規表現の評価が長時間かかる可能性があります。

path-to-regexp outputs backtracking regular expressions
For users of 0.1, upgrade to 0.1.10. All other users should upgrade to 8.0.0.

0.1 のユーザーは 0.1.10 にアップグレードしてください。その他のすべてのユーザーは 8.0.0 にアップグレードする必要があります。

8.0.0にする必要がありそうです。

npm lsで依存関係を確認

npm ls path-to-regexpを実行。

├─┬ @cloudflare/[email protected]
│ └─┬ [email protected]
│   ├─┬ @vercel/[email protected]
│   │ └─┬ [email protected]
│   │   └── [email protected]
│   ├─┬ @vercel/[email protected]
│   │ └── [email protected]
│   └─┬ @vercel/[email protected]
│     └─┬ @vercel/[email protected]
│       └── [email protected]
└─┬ [email protected]
  └── [email protected]

具体的な依存関係

@cloudflare/[email protected] パッケージが、以下のパッケージを持っている。

👉特定のパッケージが他のパッケージに依存している状態

直接の依存関係

[email protected] パッケージが [email protected] に依存している。

👉プロジェクトが直接インストールしたパッケージ

該当パッケージのバージョンを最新にしてみる

@cloudflare/next-on-pagesとwranglerのパッケージを最新にアップデートしましたが、Severity: highのままでした。

特定のパッケージとそのサブ依存のバージョンを一括で上げる

npmの場合は依存関係ツリーをpackage.jsonで上書きするoverridesオプションがあります。

overrides

If you need to make specific changes to dependencies of your dependencies, for example replacing the version of a dependency with a known security issue, replacing an existing dependency with a fork, or making sure that the same version of a package is used everywhere, then you may add an override.

https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides

package.jsonにpath-to-regexpのバージョンを8.0.0で固定します。

package.json

{
  //略
  "overrides": {
    "path-to-regexp": "8.0.0"
  }
}

追加したあとにnpm installを実行。

17 vulnerabilities (4 low, 6 moderate, 7 high)

highが10→7に減りました!

npm ls path-to-regexpを確認してみる。

├─┬ @cloudflare/[email protected]
│ └─┬ [email protected]
│   ├─┬ @vercel/[email protected]
│   │ └─┬ [email protected]
│   │   └── [email protected] deduped
│   ├─┬ @vercel/[email protected]
│   │ └── [email protected] deduped
│   └─┬ @vercel/[email protected]
│     └─┬ @vercel/[email protected]
│       └── [email protected] deduped
└─┬ [email protected]
  └── [email protected] overridden

残りのhighのパッケージもアップデート

semver

semver  6.0.0 - 6.3.0 || 7.0.0 - 7.5.1
Severity: high
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix`
node_modules/@vercel/fun/node_modules/semver
node_modules/eslint-plugin-jsx-a11y/node_modules/semver

出力された情報の参照先に以下のバージョン以上に更新するようにと書いてあります。

  • 7.x ブランチ: 7.5.2 以上
  • 6.x ブランチ: 6.3.1 以上
  • 5.x ブランチ: 5.7.2 以上

package.jsonのoverridesで7.5.2以上を設定。

package.json

{
  //略
  "overrides": {
    "path-to-regexp": "8.0.0",
    "semver": ">=7.5.2"
  }
}

next

dependenciesのパッケージなので、nextはインストールしているバージョンをアップデートします。

next  10.0.0 - 14.2.6
Severity: high
Next.js Server-Side Request Forgery in Server Actions - https://github.com/advisories/GHSA-fr5h-rqp8-mj6g
Denial of Service condition in Next.js image optimization - https://github.com/advisories/GHSA-g77x-44xx-532m
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/next

SSRFはv13.5.7・v14.2.10以降で、イメージ最適化はv14.2.7以降と..

9 vulnerabilities (3 low, 6 moderate)

highが全部消えた!

(こまめに動作するか確認を挟んでましたが)最後に動作確認をして完了です。

実際にやってみて

  • 定期的にアップデートしないとまとめて実施するのが辛い。そもそもプロジェクト全体の健全性を保つためには、定期的に対応すべき。
  • パッケージの中のパッケージ=サブ依存関係の確認方法やアップデート方法が学びになった。
  • npm audit の中身が読めるようになると、とっつきにくさは軽減される。

📝参考

シェア