Rails Active Storage の RCE、8.1.4.1 で修正(GHSA-f3w6-w445-fwh9)
Rails Active Storage の 8.0.5.2 と 8.1.4.1 より前では、細工したアップロードで ImageMagick や FFmpeg にサーバーのファイルを読み書きさせ、RCE に至る恐れがあります。今すぐ更新を。
TL;DR
- ImageMagick で添付ファイルを処理する Rails アプリケーションへの悪意あるアップロードにより、認証されていない攻撃者がサーバー上に任意のファイルを書き込める可能性があります。Rails チームは 2026 年 11 月 4 日にこの脆弱性を公表しました。
- Active Storage は 8.0.5.2 より前、8.1 系は 8.1.4.1 より前が対象です。同じリリースには、アップロードのファイル名が FFmpeg や ImageMagick のどのデコーダーを動かすかを選べる第二の脆弱性も含まれます。
- Rails チームはファイル書き込みの脆弱性をクリティカル(CVSS v3.0 9.8)、デコーダーの脆弱性を高深刻度(CVSS v3.1 8.8)に分類しています。CVE は割り当てられておらず、2026 年 11 月 4 日時点でどちらの脆弱性も CISA の Known Exploited Vulnerabilities(KEV)カタログに載っていません。
- activestorage を今すぐ 8.0.5.2 または 8.1.4.1 に更新し、移行ノートを読んでください。修正は mini_magick 5.1 以降を必要とする ImageMagick セキュリティポリシーを同梱します。「修正するには?」を参照。
影響を受けるのは?
クリティカルなファイル書き込み脆弱性 GHSA-f3w6-w445-fwh9 では、次の条件がすべて成り立つ必要があります:
- 対象のアプリケーションが Active Storage の添付ファイルを ImageMagick で処理している。これは
config.active_storage.variant_processor = :mini_magick、load_defaults 6.1以前のアプリケーションの既定値です。 - ホストの ImageMagick が、該当コーダーをすでに拒否していないセキュリティポリシーのもとで動作している。
policy.xmlでMSL、MVG、Ghostscript 系コーダーを確認してください。Debian 12 の同梱ポリシーは Ghostscript 系と URL のコーダーを拒否しますが、MSLの規則はなく、唯一のMVGの規則はコメントアウトされているため、報告されたチェーンは防げません。 - 対象のアプリケーションが信頼できないユーザーからのファイルアップロードを受け付けている。
デコーダー脆弱性 GHSA-v924-7rp8-4mxh では、次の条件がすべて成り立つ必要があります:
- 対象のアプリケーションが信頼できないユーザーからのアップロードを受け付けている。
- 動画または音声の添付ファイルを解析している(Active Storage は添付時に既定で解析を行います)、動画プレビューを生成している、または ImageMagick で画像を処理している。
デコーダー脆弱性の AviSynth 経路には、--enable-avisynth でビルドされた FFmpeg と AviSynthPlus ランタイムが必要です。アップストリームの FFmpeg と一般的な Linux ディストリビューション・Homebrew のパッケージでは有効化されていません。ffmpeg.org から Windows と Linux 向けに配布される GPL ビルドでは有効で、拡張子から選ばれる他のデコーダーは AviSynth なしで到達できる場合があります。
| ブランチ | 対象バージョン | 修正バージョン |
|---|---|---|
| 8.1.x | 8.1.0 から 8.1.4 | 8.1.4.1、2026-11-04 リリース |
| 8.0.x | 8.0.0 から 8.0.5.1 | 8.0.5.2、2026-11-04 リリース |
| 7.2 とそれ以前の全系列 | 修正は提供されない。系列はサポート対象外 | 最低でも 8.0.5.2 へのアップグレード |
Rails のセキュリティリリースは 8.0 と 8.1 の系列のみに提供され、8.0 系列はメンテナンスポリシーにより 2026 年 11 月 7 日にセキュリティサポートを終了します。7.2 以前のアプリケーションは、このリリースをサポート対象系列への移行期限と捉えるべきです。activestorage gem は 2026 年 11 月 4 日時点で RubyGems 上に 561,823,760 回、rails gem は 811,345,791 回ダウンロードされています。
実行環境を確認:
# Version in the application's Gemfile.lock
grep -m1 'activestorage (' Gemfile.lock
# Version of the installed gem
bundle info activestorage | head -1
# Which variant processor is configured (no output means the framework default)
grep -R 'variant_processor' config/
# Does your FFmpeg admit the AviSynth demuxer? (prints the flag when enabled)
ffmpeg -version | grep -i avisynth
修正するには?
- アプリケーションを修正済みリリースに移行します。rails gem を 8.1.4.1 に、8.0 系列では 8.0.5.2 に固定します:
# Gemfile
gem "rails", "~> 8.1.4.1"
# then
bundle update rails
- デプロイ前に移行ノートを読みます。修正済みリリースは MiniMagick が起動するすべての ImageMagick プロセスにセキュリティポリシーを適用し、これには mini_magick 5.1 以降が必要です。より古い mini_magick のアプリケーションは起動時に例外を発生させます。
- コンテナーでデプロイしている場合はアプリケーションのコンテナーを作り直します。実行中のコンテナーを作り直さずイメージだけを取得しても、古いコードが残ります。
- アプリケーションが ImageMagick で PostScript や PDF をレンダリングする場合は、ホストの
policy.xmlでgsデリゲートと使用するコーダーを再許可してください。同梱ポリシーはこれらを拒否します。コーダーを許可するホストポリシーは、同梱ポリシーの拒否より優先されます。 - 同梱ポリシーがアプリケーションに届かない場合は、そのルールを ImageMagick のシステムポリシーに移します。アプリケーションが次のいずれかに当てはまる場合です:
- 起動後に
MiniMagick.cli_envを置き換える、MiniMagick.cli_prefixで環境を消去する、または独自のMiniMagick::Shellを組み込む。 - ImageMagick のポリシーを読まない GraphicsMagick を使う。
- 起動後に
すぐにアップグレードできないアプリケーションへの回避策は、アドバイザリのとおり、同梱ポリシーのルールを ImageMagick のシステムポリシーにコピーすることです。同梱ファイルは activestorage/lib/active_storage/image_magick/policy.xml で、一般的なシステムパスは /etc/ImageMagick-7/policy.xml です。最低限、MSL コーダー、Ghostscript 系コーダー、gs デリゲートを拒否します:
<policy domain="coder" rights="none" pattern="MSL"/>
<policy domain="delegate" rights="none" pattern="gs"/>
<policy domain="coder" rights="none" pattern="{PS,PS2,PS3,EPS,EPS2,EPS3,EPI,EPSF,EPSI,EPT,EPT2,EPT3,PDF,AI,EPDF,PDFA,POCKETMOD,XPS,PCL}"/>
デコーダー脆弱性については、アップグレードできないアプリケーションは、Active Storage がアップロードファイルに FFmpeg を実行するのを止められます(アドバイザリより改変)。これは FFmpeg 経路を閉じますが、拡張子で選ばれる ImageMagick のデコーダーは閉じません:
# config/environments/production.rb
config.active_storage.previewers =
ActiveStorage.previewers - [ActiveStorage::Previewer::VideoPreviewer]
config.active_storage.analyzers =
ActiveStorage.analyzers - [ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer]
根本原因は何か?
外部ツールの 2 つの性質が、Active Storage の 2 つの既定値と重なりました。
クリティカル側について、ImageMagick は与えられたファイルの内容からコーダーを選びます。一部のコーダーは画像そのものではなく、画像内に名前が書かれたファイルに作用します。MSL コーダーは ImageMagick の XML スクリプトインターフェースで、画像内に名前が書かれたファイルの読み書きを行います。他のコーダーは画像以外のファイルの読み取りや削除、Ghostscript デリゲートへの受け渡しを行います。
Active Storage はこのリリースまで ImageMagick のコーダーに何の制約も課していませんでした。ImageMagick アナライザーはファイル添付時に実行されるため、アップロードを添付するだけでコーダーに到達できます。variant・preview・analyze の呼び出しは不要です。
8.1 向けの修正コミット 468aa9a93fc98f5476b6821770f4ccfcb7f7d328(「Ship an ImageMagick security policy for every MiniMagick process」、2026 年 11 月 3 日)はポリシーを追加し、engine 経由で組み込みます:
# activestorage/lib/active_storage/engine.rb at 8.1.4.1
if ActiveStorage::MINIMAGICK_AVAILABLE && !ActiveStorage::MINIMAGICK_UNSECURABLE
ActiveStorage::ImageMagick.apply_policy
end
高深刻度側について、ActiveStorage::Blob#open は blob をテンポラリファイルに書き出し、その名前にはアップロードされたファイル名の拡張子が付き、そのパスを ffprobe・ffmpeg・ImageMagick に渡します。8.1.4 の脆弱な行:
# activestorage/app/models/active_storage/blob.rb, line 324 at v8.1.4
def open(tmpdir: nil, &block)
service.open(
key,
checksum: checksum,
verify: !composed,
name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ],
tmpdir: tmpdir,
&block
)
end
filename.extension_with_delimiter はアップロード者の選択です。FFmpeg は .avs 拡張子だけで AviSynth デマクサーを選び、ImageMagick も同じように拡張子からコーダーとデリゲートを選びます。
どのように悪用されるか?
クリティカル側:
- 攻撃者は対象アプリケーションに悪意あるファイルをアップロードします。ファイルは添付されるだけでよく、アナライザーは添付時に実行され、variant・preview・
analyzeの呼び出しは不要です。 - ImageMagick はファイルの内容からコーダーを選びます。報告された攻撃チェーンでは、アップロードされた SVG が
MSLスクリプトコーダーに到達しました。このコーダーはスクリプトが名指しするファイルの読み書きを行います。 - そのコーダーは攻撃者が選んだファイルをサーバー上に書き込みます。添付ファイルが Disk サービスで保存されている場合、同じクラスのコーダーはアプリケーションプロセスが読み取れる任意ファイルを読み出せます。
- それらのファイルには通常
secret_key_baseと外部システムの資格情報が含まれます。アドバイザリは、リモートコード実行への昇格や横移動につながる可能性があり、1 つの具体的な攻撃チェーンが報告されたものの他にも存在し得ると述べています。
高深刻度側は、修正の独自テストが攻撃の名前を文書化しています:
- 攻撃者は
attack.avsという名前のファイルをアップロードし、Content-Type をvideo/mp4と宣言します。blob は添付時に解析され、Active Storage はテンポラリファイルをffprobeとffmpegに渡します。 - テンポラリファイルの名前が
.avsで終わるため、AviSynth サポート付きでビルドされた FFmpeg はファイルを AviSynth スクリプトとして評価します。 - スクリプトはアプリケーションプロセスが読み取れるファイルを取り込み、プレビュー画像経由でそれを漏洩させます。攻撃者がアップロードしたネイティブライブラリを読み込み、FFmpeg プロセス内でのリモートコード実行につながる可能性もあります。
- FFmpeg や ImageMagick が拡張子から選ぶ他のデコーダーは、AviSynth なしで到達できる場合があります。テストは
evil.mp4も扱っています。これはimage/pngと宣言され、内容がローカルファイルを名指しするプレイリストであるアップロードです。その.mp4拡張子により、ImageMagick がファイルを FFmpeg に委譲する恐れがあります。
攻撃はどのように流れるか?
認証なしのアップロードが、アップロードから指示を受け取る外部ツールに到達し、そのツールが攻撃者の名指ししたファイルに作用します。
アナライザーを実行"] B --> C["ImageMagick がファイル内容から
コーダーを選択"] C --> D["コーダーを制限する
ポリシーなし"] D --> E["MSL コーダーが画像内に名前の
あるファイルに作用"] E --> F["サーバー上への
任意ファイル書き込み"] F --> G["Disk サービス:秘密ファイルの読み取り、
コード実行への昇格の可能性"]
攻撃者に何ができるか?
クリティカルな脆弱性は、認証なしのアップロード者にサーバー上の任意ファイル書き込みを与える可能性があります。Rails チームの評価は CVSS v3.0 9.8、CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H です。成立には 3 つの条件が揃う必要があります:ImageMagick のバリアントプロセッサー、該当コーダーをすでに拒否していないホストポリシー、そして信頼できないユーザーからのアップロードです。
MSL コーダーや同様のファイル書き込みコーダーは、添付ファイルが Disk サービスを使うときにファイルの読み出しも行い、典型的には secret_key_base、マスターキー、外部システムの資格情報を晒します。Rails チームは、これがリモートコード実行やそれらのシステムへの横移動への昇格を許す可能性があると述べています。
高深刻度の脆弱性は、生成されたプレビュー画像を通じてアプリケーションプロセスが読み取れるファイルを漏洩させる可能性があります。Rails チームの評価は CVSS v3.1 8.8、CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H で、アプリケーション上で低い権限を持つ攻撃者を想定しています。
高深刻度側では、ファイルの漏洩もコード実行も、AviSynth サポート付きの FFmpeg が必要です。拡張子から選ばれる他のデコーダーは AviSynth なしで到達できる場合がありますが、アドバイザリはそれらに具体的な影響を挙げていません。
なぜ修正は機能するか?
クリティカル側の修正は、アナライザーだけではなく MiniMagick が起動するすべての ImageMagick プロセスを制約します。同梱ポリシーが拒否するもの:
MSLコーダー、および画像以外のファイルの読み取りや削除を行うコーダー- リモートとローカルの参照、および画面表示
- Ghostscript 基盤の全コーダー(
gsデリゲートとともに) @filename間接参照
ImageMagick は検索パス上のすべての policy.xml を適用するため、同梱ポリシーはホストのポリシーを置き換えるのではなく追加します。
高深刻度側の修正は、アップロードされたファイル名がデコーダーを選ぶのを止めます。テンポラリファイルは、Marcel がその拡張子を blob の記録済み Content-Type に対応させるときのみ拡張子を保持し、それ以外は拡張子を持ちません。修正コミット 72136ff39153bc8d63ecbc899993848eb3d6573e(「Active Storage: tempfile extension must match the blob's content type」)は、生の拡張子を検証済みの選択に置き換えます:
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -321,7 +322,7 @@ def open(tmpdir: nil, &block)
key,
checksum: checksum,
verify: !composed,
- name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ],
+ name: [ "ActiveStorage-#{id}-", tempfile_extension ],
tmpdir: tmpdir,
&block
)
@@ -360,6 +361,25 @@ def service
end
private
+ # The extension is there for tools that cannot tell the type from the bytes (316d87e4: ImageMagick
+ # needs it for an SVG with no XML declaration), but some tools choose a decoder on it alone: FFmpeg
+ # runs a `.avs` file as an AviSynth script. So the uploaded extension is kept only when it denotes
+ # the blob's media type.
+ def tempfile_extension
+ extension = filename.extension_with_delimiter
+ return "" if extension.blank?
+
+ type_for_extension = Marcel::MimeType.for(name: filename.to_s)
+ return "" if type_for_extension == Marcel::MimeType::BINARY || type_for_extension != media_type
+
+ extension
+ end
+
+ # Marcel answers in canonical lowercase, so drop parameters and case before comparing.
+ def media_type
+ content_type.to_s.split(";").first.to_s.strip.downcase
+ end
+
def compute_checksum_in_chunks(io)
アップロードされた拡張子が Content-Type と一致しないファイルも引き続き処理され、外部ツールが内容から形式を検出します。Rack のテンポラリファイルが同じ検査を通らないフォームアップロードは、処理前に正しい名前のテンポラリファイルへコピーされます。
クリティカル側の修正は攻撃対象を狭めますが、他の攻撃チェーンが存在しないことを証明するものではありません。アドバイザリは、1 つの攻撃チェーンが報告され、Rails チームはそれが唯一だとは考えていないと述べています。同梱ポリシーを受け取らないアプリケーションもあります。「修正するには?」を参照してください。
侵害されたか確認するには?
Rails はどちらの脆弱性についてもインジケーターを公表していません。失敗した試行は痕跡を残さない場合があります。
クリティカル側では、アプリケーションユーザーが作成していないファイル、特に Web で配信されるパスのファイルをサーバー上で確認してください。更新前に影響条件を満たし、添付ファイルを Disk サービスで保存していた場合は、アプリケーションプロセスが読み取れる秘密をすべて漏洩したものとして扱ってください。アドバイザリは secret_key_base、マスターキー、config/credentials.yml.enc の内容すべて、ストレージとデータベースの資格情報、サードパーティーサービスのトークンを挙げています。
高深刻度側では、AviSynth サポート付きの FFmpeg を実行していたアプリケーションは、同じ範囲のアプリケーションプロセスが読み取れる秘密を漏洩したものとして扱うべきです。secret_key_base を変更すると、アクティブなセッションが失効し、署名・暗号化済み Cookie、署名済みグローバル ID、Active Storage の URL が無効になります。
年表
テンポラリファイルの修正は、協調リリースの 53 日前に書かれていました。
- 2026-09-12:テンポラリファイル拡張子の修正が 8.1 ブランチで書かれた(コミット 72136ff3)。
- 2026-11-03:ImageMagick セキュリティポリシーの修正がコミットされた(コミット 468aa9a9、20:10 UTC)。
- 2026-11-04:Rails 8.0.5.2(02:31 UTC)と 8.1.4.1(02:46 UTC)が GitHub でリリースされた。
- 2026-11-04:修正された 21 件をまとめた協調アナウンスが oss-security に投稿された(02:58 UTC)。
- 2026-11-04:2 つのアドバイザリが公開された(GHSA-v924-7rp8-4mxh は 03:02 UTC、GHSA-f3w6-w445-fwh9 は 03:09 UTC)。
FAQ
修正はアプリケーションの起動を変えますか?
バリアントプロセッサーが :mini_magick のアプリケーションは、ポリシー適用に必要な mini_magick 5.1 以降が要ります。より古い mini_magick では、アプリケーションは起動時に例外を発生させます。load_defaults 7.0 以降の既定値である libvips を使うアプリケーションは、この要件の対象外です。
libvips を使っています。影響を受けますか?
クリティカルなファイル書き込みには ImageMagick バリアントプロセッサーが必要なため、libvips のアプリケーションはそれには影響されません。デコーダー脆弱性はプロセッサーに関係なく適用されます。動画・音声の添付ファイルは既定で添付時に ffprobe で解析され、テンポラリファイル名の修正はその経路を対象に含みます。
アプリケーションは ImageMagick で PDF や PostScript をレンダリングしています。どうなりますか?
同梱ポリシーは Ghostscript 基盤の全コーダーと gs デリゲートを拒否します。アプリケーションは、ホストの policy.xml で使用するデリゲートとコーダーを再許可しなければ、更新後にレンダリングが動かなくなります。
このリリースの他の 19 件のセキュリティ問題は何ですか?
同じリリースは、Parameters#each_key の Strong Parameters バイパス、Action Dispatch RemoteIp の IP 詐称(8.1 のみ)、safe_constantize のサービス拒否という高深刻度 3 件を修正します。残る 16 件は中または低深刻度で、クロスサイトスクリプティング(XSS)、サービス拒否、セッション処理の修正を含みます。oss-security のアナウンスが各アドバイザリにリンクしています。
なぜ CVE が割り当てられていないのですか?
Rails チームは両方の脆弱性をリポジトリのセキュリティアドバイザリとして公開し、2026 年 11 月 4 日時点でどちらにも CVE ID がありません。同日時点で GitHub Advisory Database にも登録されていないため、CVE やこのデータベースに依存する依存関係スキャナーは検出しない可能性があります。Gemfile.lock を修正済みバージョンと直接照合してください。
Rails の系列が 7.2 以前です。どうすればよいですか?
サポート対象外のため、その系列への修正は提供されません。最低でも 8.0.5.2 にアップグレードし、8.0 からの移行を計画してください。8.0 のセキュリティサポートは 2026 年 11 月 7 日に終了します。
攻撃者より先に、晒された Rails アプリケーションを見つける
信頼できないユーザーからのアップロードを受け付ける Rails アプリケーションから先に修正すべきです。Ostorlab の Web Agentic Deep Scan は Web アプリケーションと API の脆弱性をスキャンし、信頼できないユーザーに開かれたアップロード窓口を見つける助けになります。
参考文献
- GHSA-f3w6-w445-fwh9、Rails セキュリティアドバイザリ、「Possible arbitrary file write and read in Active Storage image analysis」:https://github.com/rails/rails/security/advisories/GHSA-f3w6-w445-fwh9(2026 年 11 月 4 日確認)
- GHSA-v924-7rp8-4mxh、Rails セキュリティアドバイザリ、「Possible arbitrary file read and remote code execution in Active Storage video previews, analysis and image processing」:https://github.com/rails/rails/security/advisories/GHSA-v924-7rp8-4mxh(2026 年 11 月 4 日確認)
- Rails セキュリティリリースのアナウンス、8.0.5.2 と 8.1.4.1 で 21 件を修正:https://www.openwall.com/lists/oss-security/2026/11/04/2(2026 年 11 月 4 日確認)
- 修正コミット 468aa9a93fc98f5476b6821770f4ccfcb7f7d328、「Ship an ImageMagick security policy for every MiniMagick process」(8.1):https://github.com/rails/rails/commit/468aa9a93fc98f5476b6821770f4ccfcb7f7d328(2026 年 11 月 4 日確認)
- 修正コミット 72136ff39153bc8d63ecbc899993848eb3d6573e、「Active Storage: tempfile extension must match the blob's content type」(8.1):https://github.com/rails/rails/commit/72136ff39153bc8d63ecbc899993848eb3d6573e(2026 年 11 月 4 日確認)
- 修正コミット ea8c40121ce53a3d0255cd4eb6d13bfe3bc01776、「Ship an ImageMagick security policy for every MiniMagick process」(8.0):https://github.com/rails/rails/commit/ea8c40121ce53a3d0255cd4eb6d13bfe3bc01776(2026 年 11 月 4 日確認)
- 修正コミット 8106938fb0a595f11006dd1497cd409e27d7d636、「Active Storage: tempfile extension must match the blob's content type」(8.0):https://github.com/rails/rails/commit/8106938fb0a595f11006dd1497cd409e27d7d636(2026 年 11 月 4 日確認)
- v8.1.4.1 時点の Active Storage CHANGELOG:https://github.com/rails/rails/blob/v8.1.4.1/activestorage/CHANGELOG.md(2026 年 11 月 4 日確認)
- Rails 8.0.5.2 リリース:https://github.com/rails/rails/releases/tag/v8.0.5.2(2026 年 11 月 4 日確認)
- Rails 8.1.4.1 リリース:https://github.com/rails/rails/releases/tag/v8.1.4.1(2026 年 11 月 4 日確認)
- activestorage gem のダウンロード数:https://rubygems.org/gems/activestorage(2026 年 11 月 4 日確認)
- Rails メンテナンスポリシー:https://rubyonrails.org/maintenance(2026 年 11 月 4 日確認)
- ImageMagick セキュリティポリシーの文書:https://imagemagick.org/security-policy/(2026 年 11 月 4 日確認)
- Debian 12 が同梱する ImageMagick の policy.xml:https://sources.debian.org/src/imagemagick/8:6.9.11.60+dfsg-1.6+deb12u11/config/policy.xml/(2026 年 11 月 4 日確認)