npm を中心としたエコシステムの発展により、ソフトウェアサプライチェーンはこれまでにない規模と速度で成長しました。私たちも日々、その恩恵を受けて開発を進めています。フロントエンド開発では、多くの開発者が大量の npm パッケージに支えられているのではないでしょうか。
しかしその一方で、脆弱性を含む依存パッケージを長期間使い続けているプロジェクトも少なくありません。今年はサプライチェーンを狙った攻撃が例年以上に目立ち、Shai-Hulud のような巧妙な手口に対応を迫られた方もいると思います。だからこそ、まずは足元が固まっているかを見直すことが重要です。
現実として、多くのセキュリティ侵害は、すでにパッチが公開されていたにもかかわらず適用されていなかった「既知の脆弱性(CVE)」を突かれたものだといわれています。サプライチェーン攻撃への対策はもちろん大事ですが、足元の対策ともいえる既知の脆弱性への対応もしっかりやっていきたいものです。
そこで、今日からできる対策 npm audit について、できるだけ最低限の内容で書きます。
npm install はするけど npm audit はしたことがない
Web の脆弱性は毎日のように報告され続けていますが、npm install で導入したパッケージを古いまま使い続けていないでしょうか。
npm audit は、プロジェクトに 既知の脆弱性を含む依存パッケージが混入していないか をチェックするツールです。使い方は非常に簡単で、まずは現状を知るところから始められます。
package-lock.json があるディレクトリで次のコマンドを実行すると、依存関係がスキャンされ、npm が持つ脆弱性データベースと照合されます。
(※チェックするだけなので、プロジェクトのファイルは書き換えられません。)
npm audit
実行してみて、出力の多さに驚く方もいるかもしれません。
しかし、それはそのまま 既知の脆弱性を抱えた状態だった ということです。
npm audit は、もっとも早く・もっとも手軽に既知の脆弱性を検知できるツールです。
だからこそ、こまめに実行し、問題が小さいうちに対処することが重要になります。
npm audit fix でパッケージを更新する
npm audit で脆弱性が検知されたら、npm audit fix で自動更新を試みましょう。
npm が自動的に安全なバージョンを探し、依存パッケージを可能な範囲で更新してくれます。
npm audit fix
できるだけ頑張って更新してくれますが、できないものもあります。
この場合、下記のコマンドで強制的に更新できますが、いわゆる破壊的変更を含む更新となる可能性があるので、ビルドが通らなくなるなどを修正することになります。
破壊的変更の影響をローカルで確認するくらい用途で使うのが良いと思います。
npm audit fix --force
CI/CDへの組み込み
npm auditをCI/CDパイプラインへ組み込むと効率的な仕組みとなるのではないでしょうか。
例えばGitHub Actionsに危険度の高い脆弱性が見つかったら自動的にビルドエラーとするなどすれば、脆弱性を含むパッケージの混入を初期段階で食い止めることができます。
npm audit --audit-level=high
ビルドエラーになれば、手元でnpm audit fixで更新するなどして安全なバージョンのモジュールとならない限り、デプロイ環境に提供されません。
パッケージ更新の遅れによる技術的負債を防ぎ、脆弱性対応を属人的な作業ではなく仕組みで回すことができます。
まとめ
- まずは既知の脆弱性を放置しないことが最優先です。
→ npm audit で現状を可視化しましょう。 - 脆弱性が解消された安全なバージョンへ更新する。
→ npm audit fix で楽できます。(自動でアップデート) - npm auditを CI/CD に組み込み、継続的に運用する。
→ “たまたま対応する” ではなく “仕組みで防ぐ” 状態を作りましょう。