はじめに
GitHubにはセキュリティアラートという機能があります。セキュリティアラートはリポジトリに含まれるライブラリやパッケージの脆弱性を定期的にチェックし、脆弱性のあるライブラリやパッケージが発見されたらアラートで知らせてくれるという機能です。
本記事では、GitHubのセキュリティアラートで発見された脆弱性を解消する方法について説明します。
Gemのアップデート手順
アップデートの準備
Gemのアップデートを行う前に、Gem自体のアップデートとBundlerのアップデートを行います。
# Gem自体のアップデート
$ gem update --system
# Bundlerのアップデート
$ gem update bundler
アップデートできたらバージョン確認を行います。
# Gem自体のバージョン確認
$ gem -v
# Bundlerのバージョン確認
$ gem list bundler
Gemのアップデート
まず、セキュリティアラートで発見された脆弱性のあるGemを確認し、脆弱性が解消されたバージョンのchangelogやリリースノートを確認します。例えば、Ruby on RailsのchangelogはGitHub、リリースノートはRailsガイドで確認できます。
更新内容に問題ないことが確認できたらGemのアップデートを行います。必要に応じてGemfile
のバージョン指定を修正し、以下のコマンドを実行します。
$ bundle update rails
Gemのアップデートが行われない場合は以下の記事を参照してください。
npmパッケージのアップデート手順
Rails 6から標準導入されたWebpackerを使っていると、npmパッケージとしてWebpackerがインストールされています。Webpackerはたくさんのパッケージに依存しているため、それらの依存パッケージで脆弱性が発見されることがあります。
パッケージのアップデート
まず、セキュリティアラートで発見された脆弱性のあるパッケージを確認し、脆弱性が解消されたバージョンのchangelogを確認します。例えば、WebpackerのchangelogはGitHubで確認できます。
更新内容に問題ないことが確認できたらパッケージのアップデートを行います。
# バージョン指定してアップデート
$ yarn upgrade @rails/webpacker@5.4.3
# 最新バージョンにアップデート
$ yarn upgrade @rails/webpacker@latest
なお、上記のコマンドでは間接的な依存パッケージのアップデートが行われない場合があります。その場合、パッケージをいったん削除して追加し直す必要があります。
パッケージがpackage.json
のdependenciesセクションにある場合とdevDependenciesセクションにある場合で-D
オプションの有無が変わってくるので注意してください。
package.json
{
"name": "sample-app",
"private": true,
"dependencies": {
"@rails/webpacker": "5.4.3"
},
"devDependencies": {
"webpack-dev-server": "^4.7.3"
}
}
このような場合、以下のコマンドを実行します。
# dependenciesセクションのパッケージの場合
$ yarn remove @rails/webpacker && yarn add @rails/webpacker
# devDependenciesセクションのパッケージの場合
$ yarn remove webpack-dev-server && yarn add -D webpack-dev-server
間接的な依存パッケージのアップデート
セキュリティアラートで発見された脆弱性のあるパッケージがpackage.json
に含まれていない場合、そのパッケージは間接的な依存パッケージとなります。この場合、まずパッケージの依存関係を調べる必要があります。
$ yarn why serialize-javascript
...
=> Found "serialize-javascript@4.0.0"
info Has been hoisted to "serialize-javascript"
info Reasons this module exists
- Hoisted from "@rails#webpacker#compression-webpack-plugin#serialize-javascript"
- Hoisted from "@rails#webpacker#webpack#terser-webpack-plugin#serialize-javascript"
...
上記のコマンドを実行すると、「serialize-javascript」というパッケージは「compression-webpack-plugin」と「terser-webpack-plugin」というパッケージに依存していることが確認できます。また、それらのパッケージはさらに「@rails/webpacker」に依存していることも確認できます。
$ yarn why @rails/webpacker
...
=> Found "@rails/webpacker@5.4.3"
info Has been hoisted to "@rails/webpacker"
info This module exists because it's specified in "dependencies".
...
「@rails/webpacker」の依存関係を調べると、package.json
のdependenciesセクションに記述されていることがわかります。このため、「@rails/webpacker」のバージョンをアップデートすることで、連鎖的に間接的な依存パッケージのアップデートが行われることになります。
脆弱性の解消されたバージョンに対応していない場合
セキュリティアラートで発見された脆弱性のあるパッケージに依存しているパッケージが、脆弱性の解消されたバージョンに対応していない場合があります。例えば、「nth-check」というパッケージに脆弱性が発見され、バージョン2.0.1で脆弱性が解消されたが、「nth-check」に依存している「@rails/webpacker」が「nth-check」のバージョン2.0.1に対応していないという場合です。このような場合、強制的に「nth-check」のバージョン2.0.1を使うように指定することが可能です。
package.json
に以下を追記します。
package.json
{
"name": "sample-app",
"private": true,
"dependencies": {
"@rails/webpacker": "^5.4.3"
},
"devDependencies": {
"webpack-dev-server": "^4.7.3"
},
// 以下を追記
"resolutions": {
"nth-check": "^2.0.1"
}
}
resolutionsセクションにパッケージとバージョンを追記したら、以下のコマンドを実行します。
$ yarn
コマンドを実行すると「nth-check」のバージョン2.0.1がインストールされ、強制的に使用するように変更されます。また、yarn.lock
もそのように書き換わります。
resolutionsセクションに記述したパッケージのバージョンは、本来そのパッケージに正式に対応していないパッケージにまで使用を強制するため、正しく動かなくなる可能性があります。使用する場合は慎重に検討したほうが良さそうです。
まとめ
セキュリティアラートで脆弱性が発見されたからと言って、即座に対応しなければいけないとも限りません。まずは脆弱性の中身を見極め、直接的に影響がありそうな場合のみ対応すればいいのではないかと思います。
本記事を参考にして、セキュリティアラートで発見された脆弱性を解消していただければと思います。