Rails 8.1.4.1で21件の脆弱性を修正|深刻度の高い5件の条件と、修正版が出ていない7.2系のアプリの対応

Rails 8.1.4.1で21件、8.0.5.2で19件の脆弱性が直った

Webアプリのフレームワーク「Ruby on Rails」のセキュリティ修正版、8.1.4.1と8.0.5.2が2026年11月4日(日本時間)に公開されました(8.1.4.1のリリースノート、8.0.5.2のリリースノート)。同じ日に公開されたセキュリティ勧告は21件で、深刻度はCriticalが1件、Highが4件、Mediumが13件、Lowが3件です。8.1.4.1は21件すべて、8.0.5.2は8.0系に関係する19件を直しています。

直った部品は、ファイルのアップロードを扱うActive Storage、リクエストを処理するAction Pack、画面の部品のAction Viewなど、Railsの広い範囲にわたります。Railsの保守方針では、セキュリティ修正の期間は各系列の最初のリリースから2年で、7.2系はすでに対象から外れているため、今回の修正版は出ていません。8.0系のセキュリティ修正の期間も、2026年11月7日で終わりました。

この記事では、21件のうち深刻度の高い5件について、影響を受けるアプリの条件と、すぐに上げられないときの回避策をまとめます。Strong ParametersとIPアドレスの判定、ImageMagickの安全設定の3つは、8.1.4と8.1.4.1を手元に入れて動きを比べました。自分のアプリが当てはまるか、どの順に対応するかを決める材料にしてください。

要点

8.1系と8.0系は修正版へ上げ、7.2系は8.1系への移行を急ぐ

21件の勧告の影響範囲と、Railsの保守方針をまとめました。

修正版

8.1.4.1と8.0.5.2

8.1系は21件、8.0系は19件の勧告が直りました。

いちばん重い1件

Active StorageでImageMagickを使うアプリ

アップロードされた画像の解析で、サーバーにファイルを書き込まれるおそれがあります。

7.2系

修正版なし

18件の勧告は影響範囲が7.2以前にも及びます。

8.0系

保守は11月7日で終了

今、セキュリティ修正の対象は8.1系だけです。

深刻度の高い5件は、Active StorageとAction Packに集まる

CriticalとHighの5件を、影響を受けるアプリの条件とともに並べました。5件とも、条件を満たさないアプリには影響しません。まずこの表で、自分のアプリが当てはまるものを探してください。

勧告(深刻度) 影響を受けるアプリ 起きること 影響する版
GHSA-f3w6-w445-fwh9
Critical
Active Storageの画像の処理にImageMagickを使い、信頼できない人のアップロードを受け付ける認証なしの攻撃者がサーバーにファイルを書き込めるおそれ。Diskサービスなら読めるおそれ8.1.4以前(8.0系、7.2以前も)
GHSA-v924-7rp8-4mxh
High
信頼できない人のアップロードを受け付け、動画・音声の解析、動画のプレビュー、ImageMagickでの処理のどれかを行う拡張子で選ばれた想定外の読み方でファイルが処理される。AviSynthを有効にしたFFmpegがあるサーバーでは、ファイルの読み取りやコードの実行につながるおそれ8.1.4以前(8.0系、7.2以前も)
GHSA-wm3x-v3qw-4jh3
High
paramsのeach_keyの戻り値を、モデルのnewやupdateに渡している許可していない属性(adminなど)まで書き込まれる8.1.4以前(8.0系、7.2以前も)
GHSA-2gff-2mmg-m73p
High
8.1系とRack 3を、利用者のForwardedヘッダーを消さないプロキシの後ろで動かし、request.remote_ipをアクセス制限、回数制限(rate_limitの既定を含む)、ログの記録に使う利用者が自分のIPアドレスを好きな値に見せかけられる8.1.0〜8.1.4だけ
GHSA-8474-xrp6-wh69
High
Action Cableを有効にしている(新しいアプリは既定で/cable)か、利用者の入力をsafe_constantizeに渡している細工した文字列で、サーバーのプロセスを止められるおそれがある8.1.4以前(8.0系、7.2以前も)

表は各勧告の「Affected applications」と「Versions affected」から要約。8.0系の修正版は8.0.5.2。「7.2以前も」は、勧告の影響範囲(activestorage < 8.0.5.2 など)に7.2以前の版が含まれることを表す。

Active StorageでImageMagickを使うアプリは、修正版で安全設定が入る

Criticalの1件は、Active Storageがアップロードされた画像をImageMagickで解析するときに起きます。ImageMagickは、ファイルの中身を見て読み方(coder)を選びます。coderの中には、画像の中に書かれた別のファイルを読んだり消したりするものがあり、Active Storageはこれを制限していませんでした。画像を添付した時点で解析が走るため、縮小画像やプレビューを作らないアプリでも影響します。

勧告によると、影響するのは次の3つの条件をすべて満たすアプリです。

  • config.active_storage.variant_processorが:mini_magick(config.load_defaultsが6.1以前のアプリの既定)
  • ImageMagickの安全設定(policy)が、関係するcoderを拒否していない。DebianとUbuntuのパッケージに入っているpolicyは拒否していない
  • 信頼できない人からのアップロードを受け付ける

8.1.4.1は、危ないcoderを拒否するImageMagickのpolicy(policy.xml)を同梱し、mini_magickが起動するすべてのImageMagickにそれを読ませます。手元のImageMagick 7.1.2-27(Homebrew)で、このpolicyを読ませた場合と読ませない場合に、文字のない1×1の白い画像を書き出して比べました。

同梱のpolicyなし(8.1.4まで)

PNGもPDFも書き出せる

手元のImageMagickの既定のpolicyでの結果です。8.1.4のActive Storageには、このpolicyのフォルダーがありません。

8.1.4.1が同梱するpolicy

PNGは書き出せ、PDFは拒否

スクリプトのcoder(MSL)、Ghostscriptを使うPDFやPostScriptのcoderなどが拒否されます。

magick: attempt to perform an operation not authorized by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/456.

8.1.4.1が同梱するpolicy.xmlのフォルダーをMAGICK_CONFIGURE_PATHで指定し、1×1の白い画像をPDFに書き出したときの表示。macOS 27.0.1、ImageMagick 7.1.2-27で2026年11月11日に確認。

8.1.4.1に上げるときは、次の4つに注意します。

  • mini_magickは5.1以上が要ります。勧告によると、古いmini_magickのままだと起動時に例外が出ます。手元でmini_magick 5.0.1と組み合わせると、ImageMagickで画像を変換する処理を読み込んだ時点でActive Storage's ImageMagick security policy requires mini_magick 5.1 or later.というエラーになりました。5.4.0では、同梱のpolicyのフォルダーがMiniMagick.cli_envのMAGICK_CONFIGURE_PATHに入っていました。
  • PDFやPostScriptをImageMagickで変換しているアプリは、サーバーのpolicy.xmlでgsと使うcoderを許可し直す必要があります。リリースノートによると、サーバーのpolicyで許可したcoderは、同梱のpolicyの拒否より優先されます。
  • 同梱のpolicyが効かないアプリもあります。起動後にMiniMagick.cli_envを置き換える、MiniMagick.cli_prefixで環境を消す、独自のMiniMagick::Shellを使う、のどれかに当たるアプリは、同じ規則をサーバーのImageMagickのpolicyに書きます。GraphicsMagickを使うアプリにも同梱のpolicyは効きません。GraphicsMagickはImageMagickのpolicyを読まないためです。
  • 添付ファイルをDiskサービスに保存しているアプリは、上げるだけでは足りません。勧告は、secret_key_base、マスターキー、config/credentials.yml.encの中身、ストレージやデータベースの認証情報など、アプリのプロセスが読める秘密情報をすべて変え、古い値を予備として残さないよう求めています。

すぐに上げられない場合の回避策として、勧告は、同梱のpolicyの規則をサーバーのImageMagickのpolicy(例: /etc/ImageMagick-7/policy.xml)へ写す方法を挙げています。少なくとも、MSLのcoder、Ghostscriptのcoder、gsのdelegateを拒否します。

アップロードの拡張子で、FFmpegとImageMagickの読み方が決まっていた

Highの1件(GHSA-v924-7rp8-4mxh)も、アップロードされたファイルの扱いの問題です。勧告によると、ファイル名と内容の種類(content type)はアップロードする側が申告でき、動画・音声の解析は添付したときに既定で走ります。信頼できない人のアップロードを受け付け、動画・音声の解析を既定のまま有効にしているアプリは、画像だけを受け付けるつもりでも、:vipsで画像を処理していても当てはまります。Active Storageは、解析や変換の前にファイルを元の名前の拡張子のまま一時ファイルに書き、ffprobe、ffmpeg、ImageMagickに渡していました。これらのツールは、中身から形式が決まらないと拡張子で読み方を選ぶため、拡張子を偽ったファイルで想定外の読み方をさせられます。8.1.4.1は、拡張子が記録された形式と合うときだけ拡張子を残します。

勧告によると、ファイルの読み取りやコードの実行につながる攻撃は、AviSynthを有効にしてビルドしたFFmpegと、AviSynthPlusがサーバーに入っている場合に成り立ちます。主なLinuxディストリビューションやHomebrewのFFmpegでは無効で、ffmpeg.orgで配られているWindows・Linux向けのGPLビルドでは有効です。この条件に当たるアプリは、上げたうえで、secret_key_baseなどアプリが読める秘密情報をすべて変えるよう求められています。AviSynthがなくても、FFmpegやImageMagickが拡張子で選ぶほかの読み方を使われるおそれがあるため、条件に当たらないアプリも上げます。

すぐに上げられない場合は、config.active_storage.previewersからActiveStorage::Previewer::VideoPreviewerを、config.active_storage.analyzersからActiveStorage::Analyzer::VideoAnalyzerとActiveStorage::Analyzer::AudioAnalyzerを外すと、アップロードされたファイルにFFmpegを使わなくなります。この回避策で止まるのはFFmpegの経路だけで、ImageMagickでの処理の経路は残ります。

Strong Parametersのeach_keyは、許可していない属性を通していた

ActionController::Parameters#each_keyをブロック付きで呼ぶと、8.1.4まではparamsの中身のハッシュ(HashWithIndifferentAccess)を返していました。このハッシュには「許可したか」の情報がないので、モデルのnewやupdateに渡すと、permitしていない属性まで書き込まれます。2020年のCVE-2020-8164でeachなどは直りましたが、each_keyだけが残っていました。

nameとadminを持つActive Modelのクラスに、params[:user].each_key { }の戻り値を渡して比べました。

params = ActionController::Parameters.new(user: { name: "alice", admin: "1" })
ret = params[:user].each_key { |k| }

# 8.1.4
ret.class      #=> ActiveSupport::HashWithIndifferentAccess
User.new(ret)  #=> 成功。name="alice"、admin=true

# 8.1.4.1
ret.class      #=> ActionController::Parameters
User.new(ret)  #=> ActiveModel::ForbiddenAttributesError

actionpack 8.1.4と8.1.4.1、Ruby 3.4.3で2026年11月11日に確認。どちらの版でも、params[:user]をそのまま渡すとForbiddenAttributesError、permit(:name)を渡すとadminはfalseのままだった。

Rails自身はこの呼び方をしないので、影響するのは、アプリのコードがeach_keyの戻り値をモデルに渡している場合だけです。grep -rn "each_key" app/ lib/などで呼び出しを探し、戻り値を使っている箇所を、permitしたparamsを渡す書き方に直します。この直し方は、Railsを上げられない7.2系のアプリでもそのまま使えます。8.1.4.1へ上げると、戻り値を使っていたコードはForbiddenAttributesErrorになるので、テストがその処理を通っていれば見つかります。

8.1系のremote_ipは、利用者が付けたForwardedヘッダーを信じていた

この1件は8.1系だけの問題です。Rails 8.1.0から、request.remote_ipはRackのforwarded_forで接続元を求めるようになりました。Rack 3は、標準のヘッダーのForwardedをX-Forwarded-Forより優先して読みます。手前のプロキシがX-Forwarded-Forに本当の接続元を足し、利用者が送ったForwardedをそのまま通すと、利用者が書いた値がremote_ipになります。勧告によると、IPアドレスでのアクセス制限やrate_limitの既定のby:をすり抜けられ、ログに残る接続元も偽られます。

手前のプロキシ(10.0.0.2)がX-Forwarded-For: 203.0.113.10を付け、利用者がForwarded: for=198.51.100.99を送った場合を、両方の版のActionDispatch::RemoteIpに渡しました(Rack 3.2.8)。

届いたヘッダー 8.1.4 8.1.4.1
ForwardedとX-Forwarded-Forの両方198.51.100.99(利用者が書いた値)IpSpoofAttackErrorで止まる
X-Forwarded-Forだけ203.0.113.10203.0.113.10
両方(forwarded_priority = [:x_forwarded]を設定)203.0.113.10203.0.113.10

config.action_dispatch.ip_spoofing_checkは有効(既定)。actionpack 8.1.4と8.1.4.1、Rack 3.2.8で2026年11月11日に確認。

8.1.4.1は、2つのヘッダーの接続元が食い違うとIpSpoofAttackErrorで止めます。ただし勧告によると、手前のプロキシがX-Forwarded-Forを付けない構成では、8.1.4.1でも食い違いを見つけられません。プロキシの設定で、利用者が送ったForwardedを消すか上書きします。

すぐに上げられない場合、プロキシがX-Forwarded-Forを付ける構成なら、イニシャライザーにRack::Request.forwarded_priority = [:x_forwarded]を書くと、8.0系と同じくX-Forwarded-Forから接続元を求めます。手元でも、この設定のあとは8.1.4で203.0.113.10になりました。この設定は、スキーム、ホスト、ポートの判定でもForwardedを無視するようにします。

safe_constantizeには、Action Cableとアプリのコードから利用者の入力が届く

safe_constantize(文字列からクラスを探す処理)は、クラスの読み込みに失敗したとき、渡された名前を正規表現に組み込んでいました。細工した名前を渡すと、Rubyの正規表現のコンパイラーの欠陥を突いてプロセスを止められるおそれがあります。Action Cableは、接続してきたクライアントが送るチャンネル名をこの処理に渡すため、既定の設定のままでは、認証していないクライアントも細工したチャンネル名を送れます。Action Cableを使っていなくても、paramsなど利用者が決められる文字列をsafe_constantizeに渡すコードがあれば、同じく影響します。

すぐに上げられない場合、Action Cableを使っていないアプリはconfig.action_cable.mount_path = nilでエンドポイントを外します。使っているアプリは、ApplicationCable::Connection#connectで認証していない接続にreject_unauthorized_connectionを呼びます。後者は、細工した名前を送れる相手を認証済みの利用者に絞るだけで、問題そのものは残ります。どちらもAction Cableの経路だけの回避策で、アプリのコードから利用者の入力を渡している箇所は、上げるまで残ります。

残りの16件は、Action View、Action Pack、Active Storageが中心

MediumとLowの16件は、特定の部品や設定を使うアプリに影響します。題名から内容を要約しました。

部品 内容(深刻度) 影響する版
Action Viewタグのヘルパー、テキストのヘルパー(highlightとsimple_format)、strip_tags、highlightの別の箇所でのクロスサイトスクリプティング(4件、Medium)8.1.4以前(8.0系、7.2以前も)
Action PackCacheStoreで破棄したセッションが戻る、コンテンツネゴシエーションでのキャッシュ汚染、ActionController::Liveのサービス妨害、Active Storageのプロキシでのセッション情報の漏れ(4件、Medium)。CookieStore以外のセッションのcookieにSameSiteが付かない(Low)8.1.4以前(8.0系、7.2以前も)
Active Storagecache_controlを設定したGCSへの直接アップロードでContent-Typeが署名されない、GCSへの直接アップロードでサイズの上限を回避できる、ファイル名の扱いのサービス妨害、プロキシでのストレージのエラーのサービス妨害(4件、Medium)。動画のプレビューと解析でのローカルのファイルの漏れ(Low)8.1.4以前(8.0系、7.2以前も)。プロキシのエラーだけは8.0.0以降
Active SupportMessagePackのシリアライザーで、HTMLとして安全でなくなった文字列が安全な文字列として戻る(Medium)8.1.0〜8.1.4だけ
Action MailboxMailgunの受信で署名を使い回せる(Low)8.1.4以前(8.0系、7.2以前も)

各勧告の題名と「Versions affected」から要約。8.0系の修正版は8.0.5.2。MessagePackとプロキシのエラー以外の14件は、7.2以前の版も影響範囲に入る。勧告の一覧は8.1.4.1のリリースノートにある。

MessagePackの修正は、デプロイのしかたにも関係します。8.1.4.1は、html_safeでなくなったSafeBufferを印つきで保存し、修正前の版はその形式を読めません。cookie、キャッシュ、MessageVerifierなどのシリアライザーに:message_packを使っている8.1系のアプリは、デプロイの途中で古い版のプロセスと混在するときや、上げたあとに8.1.4へ戻すときに、読めない値が出ることがあります。

7.2系のアプリは、8.1.4.1へ上げる計画を立てる

Railsの保守方針では、8.1系のセキュリティ修正は2027年10月10日まで、8.0系は2026年11月7日までで、8.0系はすでに期間を過ぎました。7.2系は一覧に入っていません。保守の終わった系列については、修正をgitで公開することはあっても、新しい版は出さないと書かれています。

21件のうち、Strong Parameters、ImageMagick、動画の解析、safe_constantizeを含む18件は、勧告の影響範囲が「8.0.5.2より前」で、7.2以前の版も含みます。7.2系の最新は2026年9月25日(日本時間)の7.2.4で、今回の修正を含む版は出ていません。7.2系のアプリは、当面は上で挙げた回避策(ImageMagickのpolicy、動画の解析を外す、Action Cableの認証、each_keyの戻り値を使わない)で影響を減らし、8.1.4.1への移行を計画します。アプリのコードからsafe_constantizeに利用者の入力を渡している箇所のように、勧告に回避策のない経路は、上げるまで残ります。8.0系のアプリも、8.0.5.2へ上げたうえで、次の問題に備えて8.1系への移行を進めます。

上げる前後に確かめる6つのこと

1. 版を上げる

GemfileのRailsを8.1.4.1(8.0系なら8.0.5.2)にしてbundle update railsを実行し、Gemfile.lockのrails (8.1.4.1)で確かめます。

2. mini_magickとImageMagick

variant_processorが:mini_magickなら、mini_magickを5.1以上にします。PDFやPostScriptをImageMagickで変換しているなら、サーバーのpolicyでgsを許可し直します。

3. 秘密情報を変えるアプリ

ImageMagickの条件に当たり添付ファイルをDiskサービスに保存していたアプリと、AviSynthを有効にしたFFmpegがあるサーバーで、信頼できない人のアップロードを受け付けていたアプリは、secret_key_baseや認証情報を変えます。勧告によると、secret_key_baseを変えると、ログイン中のセッション、署名・暗号化したcookie、Active StorageのURLなどが無効になります。

4. Active Storageの設定

GCSへブラウザから直接アップロードしているなら、バケットのCORS設定のresponseHeaderにx-goog-content-length-rangeを加えます。config.active_storage.ffmpeg_allowed_formatsにない形式(MXF、DV、AC3など)の動画・音声は、プレビューが失敗し、解析ではメタデータが記録されなくなるので、必要な形式を足します。

5. プロキシのヘッダー

8.1系では、プロキシで利用者のForwardedを消すか上書きします。上げたあとにIpSpoofAttackErrorがログに出たら、プロキシの設定を見直します。

6. each_key、safe_constantize、MessagePack

each_keyの戻り値をモデルに渡すコードと、利用者の入力をsafe_constantizeに渡すコードを探します。シリアライザーが:message_packなら、デプロイ中の混在と前の版への戻しに注意します。strip_tagsの結果をテキストのメールやJSONで使っているなら、引用符が&quot;と&#39;になるので、出力を確かめます。

参考資料

検証環境

  • macOS 27.0.1(Apple Silicon)、Ruby 3.4.3、Bundler 2.6.8
  • Rails 8.1.4と8.1.4.1、Rack 3.2.8、mini_magick 5.4.0と5.0.1
  • ImageMagick 7.1.2-27
  • 検証日: 2026年11月11日

この記事は、AIが調査と下書きを担当し、上記の環境で実際に動かして結果を確かめ、下書きとは別の担当が公開前に本文と出典を確認しています。制作と訂正の方針は編集・訂正方針で公開しています。