【Rails】GitHubのセキュリティアラートで発見された脆弱性を解消する方法

はじめに

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セクションに記述したパッケージのバージョンは、本来そのパッケージに正式に対応していないパッケージにまで使用を強制するため、正しく動かなくなる可能性があります。使用する場合は慎重に検討したほうが良さそうです。

まとめ

セキュリティアラートで脆弱性が発見されたからと言って、即座に対応しなければいけないとも限りません。まずは脆弱性の中身を見極め、直接的に影響がありそうな場合のみ対応すればいいのではないかと思います。

本記事を参考にして、セキュリティアラートで発見された脆弱性を解消していただければと思います。

関連記事

【Rails】Paranoiaを使用した論理削除(ソフトデリート)
# はじめに Paranoiaは、Railsアプリケーションで論理削除(ソフトデリート)を実現するためのGemです。 論理削除は、データベースのレコードを物理的に削除するのではなく、削除フラグを設定することで「削除済み」とみなす方法です。こ [...]
2024年7月20日 21:33
【Rails】activerecord-multi-tenantを使用したマルチテナントアプリケーションの作成
# はじめに マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。 activerecord-multi-tenantは、このようなマルチテナント環境をサポートするための便 [...]
2024年7月18日 16:50
【Rails】RubyとRailsにおけるattr_reader, attr_writer, attr_accessorの概念と使用方法
# はじめに RubyとRailsの開発において、`attr_reader`,`attr_writer`,`attr_accessor`は非常に便利なメソッドです。これらは、クラス内でインスタンス変数に対するゲッターおよびセッターメソッドを簡単に [...]
2024年7月17日 18:11
【Rails】RubyとRailsにおけるyieldの概念と使用方法
# はじめに RubyとRailsにおける`yield`は、メソッドやテンプレートの中で動的にコードブロックを実行する能力を提供し、これによってコードの再利用性と拡張性が大幅に向上します。本記事では、RubyとRailsにおける`yield`の概 [...]
2024年7月17日 13:15
【Rails】AASMを使用してオブジェクトの状態遷移を効率的に管理
# はじめに Railsアプリケーションにおいて、オブジェクトの状態管理は重要な課題の一つです。AASM (Acts As State Machine) gemは、複雑な状態遷移を効率的に管理します。本記事では、AASMの基本的な使い方を解説して [...]
2024年7月16日 18:00
【Rails】RSpec + Swagger + rswagでアプリケーションのAPIをテストおよびドキュメント化する方法
# はじめに Railsアプリケーションの開発において、APIのテストとドキュメント化は重要な要素です。 RSpecはテストフレームワークとして広く利用されており、SwaggerはAPIの設計とドキュメント化を支援します。これらを統合するr [...]
2024年7月16日 14:27
【Rails】mailcatcherを使用して開発環境でメール送信をテストする方法
# はじめに mailcatcherは、開発環境でのメール送信をキャプチャするためのツールです。ローカルで送信されたメールをブラウザ上で簡単に確認できるようにします。mailcatcherをRailsアプリケーションで使用する方法について説明しま [...]
2024年7月15日 16:37
【Rails】impressionistを使用してページビューやクリック数を追跡する方法
# はじめに impressionist Gemを使用してRailsアプリケーションでページビューやクリック数を追跡する方法について説明します。 # 実装方法 ## impressionist Gemのインストール まず、impre [...]
2024年7月15日 14:18