はじめに
こんにちは!
プログラミング学習中のまいです。
今回、Active Storage脆弱性(CVE-2026-66066)が発表されたことを受け、
応急処置と根本的な対策としてRailsバージョンアップを行ったので、その記録を残しておきます。
脆弱性の概要(CVE-2026-66066とは)
- CVSSスコア: 9.5
- 影響: 認証なしでの任意ファイル読み取り、RCE(リモートコード実行)につながる可能性
- 影響を受ける構成: Active Storage + libvips
- 公式のセキュリティ勧告: https://github.com/rails/rails/security/advisories/GHSA-xr9x-r78c-5hrm
自分のアプリが対象かどうかの確認
今回のCVEはは、画像のアップロード機能(Active Storage)で、libvipsという画像処理ライブラリを使っているRailsアプリです。
心当たりがある人は、以下の2つを確認すればOKです。
① まずはRailsのバージョンをチェック
bin/rails -v
出てきたバージョンを、公式のセキュリティアドバイザリ(GHSA-xr9x-r78c-5hrm)と照らし合わせます。
今回の脆弱性はCVSSスコア9.5(10点満点中)という、かなり深刻な部類の評価がついています。
対象バージョンと、修正済みバージョンは以下の通りです。
| 系列 | 対象(危ない) | 修正済み |
|---|---|---|
| 7.0系〜7.2系 | 7.2.3.1以前すべて | 7.2.3.2 |
| 8.0系 | 8.0.0〜8.0.5 | 8.0.5.1 |
| 8.1系 | 8.1.0〜8.1.3 | 8.1.3.1 |
私のアプリは Rails 7.1.6 だったので、見事に対象範囲に入っていました。
② 次にlibvipsを使っているか確認
そもそもlibvipsを使っていなければ、今回の脆弱性は関係ありません。
以下のどちらかに当てはまれば、使っていると考えてOKです。
-
config/application.rbやconfig/environments/*.rbにconfig.active_storage.variant_processor = :vipsという設定がある -
Gemfile.lockにruby-vipsという記述がある
バージョンは以下のコマンドで確認できます。
bundle exec ruby -e "require 'vips'; puts Vips::VERSION"
→ 自分の場合は ruby-vips 2.3.0 / libvips 8.14.1 でした。
まとめると
「① 対象のRailsバージョンを使っていて、② libvipsで画像処理している」の両方に当てはまれば、対象です。自分のアプリはどちらもバッチリ当てはまっていたため、すぐに対応が必要と判断しました。
まずは応急処置(Vips.block_untrusted)
- 公式勧告のWorkaroundsに記載されている、正式な回避策
config/initializers/vips.rbを新規作成
require "vips"
Vips.block_untrusted(true)
-
require "vips":ruby-vipsというgemを読み込む -
Vips.block_untrusted(true): libvipsに対して「信頼できない(安全性が十分にテストされていない)画像読み込み方法は使わないでください」と設定
これで応急的な対応が完了しました。
根本対応:Rails 8へのアップグレード
そもそもRails7系でアプリを作成していましたが、本件のセキュリティ上の問題の対応も含め、これを機にバージョンは公式Rails 8.1.3.1へアップグレードすることにしました。
gem "rails", "~> 7.1.6"
こちらを
gem "rails", "~> 8.1.3.1"
gemfileを書き換えて、bundle updateします
docker compose exec web bundle update rails
Rails8にアップグレードしたことでDeviseのバージョンをあげる必要が出てきたのでこちらも対応します。(4.9.4 → 5.0.4)
gem "devise", "~> 5.0.4"
書き換えて、
docker compose exec web bundle update devise
Railsのバージョンを新しくしたので、設定ファイルも書き換えます。
docker compose exec web bin/rails app:update
設定ファイルにコンフリクトが発生した場合、差分を確認しながら上書きするか、元のものを残すか判断していきました。
| ファイル | 判断 | 理由 |
|---|---|---|
config/application.rb |
維持 | omniauth除外・日本語ロケール・UUID主キー等の独自設定が消えるため |
config/environments/development.rb |
維持 | 開発メール確認設定(letter_opener_web)が消えるため |
config/environments/production.rb |
維持 | ストレージ・メール送信・force_sslの設定が消える、最重要ファイル |
bin/dev |
維持 | Rails+CSS同時起動の仕組みが失われるため |
puma.rb / test.rb / 各initializer / bin/setup
|
更新 | 独自設定なし、または安全な改善のみ |
public/404.html / 422.html / 500.html
|
更新 | 日本語化等のカスタマイズなし、見た目刷新のみ |
application.css / cors.rb
|
自動削除 | 未使用ファイル |
テストも無事通り、アップグレードでアプリが壊れていないことを確認して完了です⭐️
まとめ・学び
今回は応急的に脆弱性を塞ぐ処理をしたのち、Railsのアップグレードを行いました。
Railsのバージョンアップデートのような大きな作業を行う場合は、既存のアプリのコードが壊れてしまわないか慎重に進めることが大切だと改めて実感しました。
間違っている点や、気になる点がございましたらご指摘いただけますと助かります!