Dated status · Updated

Rails 8.1.4.1 and 8.0.5.2: is your self-hosted Rails app patched, and what can a Rails 7.2 app do?

On 4 November 2026, the Rails team released Rails 8.1.4.1 and 8.0.5.2 to fix 21 security issues. The most severe, GHSA-f3w6-w445-fwh9, is rated Critical 9.8: Rails describes possible arbitrary file write, and file read with the Disk service, in Active Storage image analysis when attachments are processed with ImageMagick. Rails lists every release below 8.0.5.2, and 8.1 releases below 8.1.4.1, as affected. That includes every Rails 7.2, 7.1 and 6.1 release. Rails publishes no fix for those lines: its announcement says "Older versions of Rails are unsupported" and recommends upgrading to at least 8.0. Security support for Rails 8.0 ends on 7 November 2026.

Rails lineFixed releaseAffected
8.18.1.4.18.1.0 up to 8.1.4
8.08.0.5.2 (support ends 7 November 2026)below 8.0.5.2
7.2, 7.1, 6.1 and oldernoneall releases

If you run an application built on Rails, such as Chatwoot, OpenProject, Zammad, Loomio, Mastodon, Discourse or GitLab, the Rails version is the one in that application's release, not one you choose. Check it in three steps: the version it runs, whether the Critical advisory's conditions apply to its configuration, and, if no fix exists for its Rails line, the workarounds Rails publishes.

1. Which Rails your running app has

Replace CONTAINER_NAME with the name of the application container, for example the web or worker container of a Compose deployment:

docker exec CONTAINER_NAME bundle exec ruby -e '%w[rails actionpack activestorage].each { |g| s = Gem.loaded_specs[g]; puts "#{g} #{s ? s.version : "not in bundle"}" }'

It prints the versions Bundler resolves in the container's working directory, for example activestorage 7.2.3.1. It can take up to a minute. Run it in a container started from the image you actually run: a newer image on the registry changes nothing until the container is recreated from it. Without containers, run the part after CONTAINER_NAME in the application's directory as the user that runs the app.

Compare activestorage with the table above. The Active Storage advisories apply to the activestorage version; the Strong Parameters advisory GHSA-wm3x-v3qw-4jh3 applies to actionpack. not in bundle for activestorage means the app's bundle does not include Active Storage, so its advisories do not apply to that app.

2. Do the Critical advisory's conditions apply?

Rails' advisory names three conditions for GHSA-f3w6-w445-fwh9. An application is affected only if it meets all of them:

  1. It uses ImageMagick for Active Storage image processing, which is config.active_storage.variant_processor = :mini_magick. Rails says this is the default for applications on load_defaults 6.1 or earlier.
  2. ImageMagick runs under a security policy that does not already deny the coders involved. Rails says the policies that Debian and Ubuntu package do not.
  3. It allows file uploads from untrusted users.

This command prints the first condition's setting and the analyzers and previewers Active Storage runs:

docker exec CONTAINER_NAME bin/rails runner 'if defined?(ActiveStorage::Engine) then puts "variant_processor: #{ActiveStorage.variant_processor.inspect}", "analyzers: #{ActiveStorage.analyzers.map(&:name).join(", ")}", "previewers: #{ActiveStorage.previewers.map(&:name).join(", ")}" else puts "Active Storage not loaded" end'

It boots the application once, so run it in a container that can reach the app's database, such as the running web container. The application may print its own log lines first; the result is the lines that start with variant_processor:, analyzers: and previewers:, and an empty previewers: line means the app configures no previewers. Active Storage not loaded means the app does not load the Active Storage engine. variant_processor: :mini_magick meets the first condition. variant_processor: :vips does not, even though the analyzers line still names ImageAnalyzer::ImageMagick: Active Storage lists that analyzer by default and uses it only with :mini_magick. A second advisory, GHSA-v924-7rp8-4mxh (High 8.8), concerns FFmpeg and ImageMagick: Rails lists as affected applications that accept untrusted uploads and analyze video or audio, generate video previews, or process images with ImageMagick. VideoAnalyzer, AudioAnalyzer and VideoPreviewer in the output are the components it names.

Whether any of the app's forms attach untrusted uploads through Active Storage depends on the application. Its maintainers can answer that; this page does not.

3. On Rails 7.2, 7.1 or 6.1: the workarounds Rails publishes

An application on these lines gets the fix only when its maintainers move it to Rails 8.0.5.2 or 8.1.4.1 and publish a release. Until then, the advisories list workarounds. Each advisory also links Rails' 8.1 and 8.0 patch commits, for those who cannot upgrade at once. If you maintain your own Rails 7.2 app: on 4 November we checked with git apply --check that the three 8.0 commits for GHSA-f3w6-w445-fwh9, GHSA-v924-7rp8-4mxh and GHSA-wm3x-v3qw-4jh3 (ea8c401, 8106938 and 2fc8838) apply cleanly to the Rails v7.2.3.1 source, leaving out their CHANGELOG and guide changes. We did not build or test the result. Rails says the Critical fix needs mini_magick 5.1 or later, and that an application whose variant processor is :mini_magick raises an exception during boot with an older one.

ImageMagick policy (GHSA-f3w6-w445-fwh9). The advisory's workaround is to copy the rules of the policy that the fixed versions ship, activestorage/lib/active_storage/image_magick/policy.xml, into ImageMagick's system policy, for example /etc/ImageMagick-7/policy.xml. At a minimum, deny the MSL coder, the Ghostscript coders and the gs delegate.

In a container, an edit inside the container is lost when the container is recreated. The fixed versions add their policy by putting its directory on MAGICK_CONFIGURE_PATH, and ImageMagick applies every policy.xml on its search path. We did the same from outside the container: save the Rails file as rails-imagemagick-policy/policy.xml next to your docker-compose.yml, then add the lines below to the application's services (web and workers).

This sets policy for every ImageMagick command in those containers, including calls outside Active Storage. If MAGICK_CONFIGURE_PATH already names custom directories, keep those directories and add this directory (entries are separated by :); do not replace existing policy paths with the single-path example below.

    volumes:
      - ./rails-imagemagick-policy:/etc/rails-imagemagick-policy:ro
    environment:
      MAGICK_CONFIGURE_PATH: /etc/rails-imagemagick-policy

Merge these lines into each service's volumes: and environment: keys, and keep every line already there. If your file uses the list form - KEY=value for environment:, write - MAGICK_CONFIGURE_PATH=/etc/rails-imagemagick-policy. A service may have no volumes: or environment: key of its own because it inherits one from a shared block, such as <<: *base in Chatwoot's file. Adding that key to the service replaces the inherited one, so copy the inherited lines into the new key as well. In Chatwoot, a volumes: key added to rails without them drops storage_data:/app/storage; the app still starts and serves, with no error, but its storage directory is no longer on the volume.

Before you recreate the containers, run this for each service's container and note the paths it prints:

docker inspect CONTAINER_NAME --format '{{range .Mounts}}{{.Destination}} {{end}}'

Recreate the containers and run it again. It must print every path it printed before, plus /etc/rails-imagemagick-policy. Then check the policy:

docker exec CONTAINER_NAME sh -c 'if command -v magick >/dev/null 2>&1; then m=magick; elif command -v convert >/dev/null 2>&1; then m=convert; else echo "No ImageMagick command found"; exit 0; fi; if "$m" msl:/dev/null null: 2>&1 | grep -q "security policy .MSL"; then echo "MSL is denied by the ImageMagick policy"; else echo "MSL is NOT denied"; fi'

It asks ImageMagick to read an empty file with the MSL coder and reports whether the policy refused. MSL is NOT denied means only that no refusal was seen: a command that failed for another reason prints it too, and it does not prove that MSL is allowed. This checks the container-wide policy only: on 8.0.5.2 and 8.1.4.1, Rails applies its policy inside the app's own ImageMagick calls, so this check can still print NOT denied there. An MSL denial checks only that coder in this shell environment. It does not verify the other policy rules or that the application's ImageMagick subprocess receives this environment. If the application overrides the environment, carry the Rails rules in its system policy as described below.

From the advisory: the policy denies PostScript and PDF processing, so an application that renders PostScript or PDF through ImageMagick must allow the gs delegate and the coders it uses again, while keeping MSL denied. GraphicsMagick does not read ImageMagick policies. An application that replaces MiniMagick.cli_env, clears the environment with MiniMagick.cli_prefix, or installs its own MiniMagick::Shell must carry the rules in ImageMagick's system policy.

FFmpeg (GHSA-v924-7rp8-4mxh). The advisory's workaround is to remove ActiveStorage::Previewer::VideoPreviewer from config.active_storage.previewers, and ActiveStorage::Analyzer::VideoAnalyzer and ActiveStorage::Analyzer::AudioAnalyzer from config.active_storage.analyzers. In an app whose source you maintain, an initializer such as config/initializers/active_storage_no_ffmpeg.rb does it:

Rails.application.config.active_storage.previewers.delete(ActiveStorage::Previewer::VideoPreviewer)
Rails.application.config.active_storage.analyzers.delete(ActiveStorage::Analyzer::VideoAnalyzer)
Rails.application.config.active_storage.analyzers.delete(ActiveStorage::Analyzer::AudioAnalyzer)

Run the step 2 command again; the three names should be gone. Active Storage then makes no video previews and records no video or audio metadata, such as duration, for new attachments. For a packaged application, ask its maintainers before changing its source: a release overwrites your edit.

Secrets. If attachments are stored with the Disk service, the Critical advisory says to change secret_key_base and every secret readable by the application process, including the master key and everything config/credentials.yml.enc holds, storage and database credentials, and third-party tokens, and not to keep an exposed secret as a fallback. Independently, the FFmpeg advisory tells affected applications that meet its AviSynth requirement—FFmpeg built with --enable-avisynth and the AviSynthPlus runtime—to change every secret readable by the application process. That instruction does not depend on Disk storage. Do not retain an exposed secret as a fallback. Rails' FFmpeg advisory notes that changing secret_key_base expires active sessions and invalidates signed and encrypted cookies, signed global IDs and Active Storage URLs.

The other 19 advisories have their own conditions and workarounds; read them from Rails' announcement. The workarounds above cover two advisories; they do not make a 7.2 app equal to a fixed release.

Where self-hosted Rails apps stood

Each row is a read of the application's own repository at the commit linked, made on 4 November 2026 between 03:25 and 03:39 UTC; on 5 November between 00:48 and 00:50 UTC we checked each application for a newer release or branch commit and re-read the Loomio, Zammad, Discourse and Huginn rows, which had moved. "Rails" is the version in that release's Gemfile.lock; for Chatwoot, OpenProject and Mastodon we also read it from the published image. The configuration columns are what the cited files contain, not a test of a running instance. "No active variant_processor assignment in the files checked" means no uncommented assignment in config/application.rb, config/environments/production.rb or config/initializers/; Rails documents :mini_magick as the default for load_defaults 6.1 or earlier and :vips from 7.0, and the step 2 command prints what a running app uses. These columns do not establish whether an app attaches untrusted uploads through Active Storage. Rails' affected ranges cover every version in this table except 8.1.4.1.

Application, release readRails (Gemfile.lock)Active Storage in the app's configurationImage processor settingRails fix for that line
Chatwoot v4.19.1 (24 Oct)7.2.3.1; image chatwoot/chatwoot:v4.19.1 also 7.2.3.1loaded: require 'rails/all' (line 5); previewers = [] (line 71)load_defaults 7.0 (line 39), no active variant_processor assignment in the files checkednone (7.2)
OpenProject v17.9.6 (30 Oct)8.1.3.1; image openproject/openproject:17.9.6 also 8.1.3.1loaded: require "rails/all" (line 33)load_defaults 6.1 (line 64), no active variant_processor assignment in the files checked8.1.4.1
Loomio v3.14.1 (4 Nov)8.1.4.1loaded: require "rails/all" (line 3); AudioAnalyzer removed in config/initializers/transcription.rb (line 3)variant_processor = :vips (line 52)8.1.4.1
Zammad develop (no GitHub release)8.1.4.1loaded: require 'rails/all' (line 5)load_defaults 8.1 (line 23); no mini_magick in Gemfile.lock8.1.4.1
Mastodon v4.7.5 (3 Nov)8.1.3.1; image ghcr.io/mastodon/mastodon:v4.7.5 also 8.1.3.1not loaded: # require 'active_storage/engine' (line 8)(Active Storage not loaded)8.1.4.1
Discourse main (no GitHub release)railties and actionpack 8.1.4.1activestorage not in Gemfile.lock(not in bundle)8.1.4.1
GitLab v19.5.17.2.3.1not among the frameworks config/application.rb requires (lines 9–15)(not read further)none (7.2)
Huginn v2026.11.05 (4 Nov)8.1.4; the later tag v2026.11.05.2 (no GitHub release) has 8.1.4.1not loaded: # require "active_storage/engine" (line 9)(Active Storage not loaded)8.1.4.1
Postal 3.3.7 (3 Jun)7.1.6not among the frameworks config/application.rb requires (lines 5–11)(not read further)none (7.1)
diaspora* v0.9.1.0 (7 Apr)6.1.7.10requires "rails/all" (application.rb:5); production.rb:18–21 says Active Storage is unused and removes ActiveStorage::Engine from eager loadingload_defaults 6.1 (line 19), no active variant_processor assignment in the files checkednone (6.1)

What the Rails team says

Rails' announcement groups the 21 issues into themes: arbitrary file read, file write and remote code execution in Active Storage image and video processing; a Strong Parameters bypass in Parameters#each_key; IP spoofing through the Forwarded header (8.1 only); several XSS issues in Action View helpers and one in the Active Support MessagePack serializer (8.1 only); denial-of-service issues; Active Storage direct uploads to Google Cloud Storage; session handling; cache poisoning through content negotiation; and signature replay in Action Mailbox Mailgun ingress. This page covers versions and the published workarounds only. For what each vulnerability does and which configurations it reaches, read the advisories.

Receipts

Commands we ran on 4 November 2026, 03:25–06:20 UTC, linux/amd64, on our own machine:

CommandWhereResult
Step 1 version commandchatwoot/chatwoot:v4.19.1rails 7.2.3.1, actionpack 7.2.3.1, activestorage 7.2.3.1
sameopenproject/openproject:17.9.6all three 8.1.3.1
sameghcr.io/mastodon/mastodon:v4.7.5all three 8.1.3.1
Step 2 commandnew Rails 7.2 app (load_defaults 7.2)variant_processor: :vips; analyzers include VideoAnalyzer, AudioAnalyzer; previewers include VideoPreviewer
samesame app with load_defaults 6.1variant_processor: :mini_magick
samesame app with the step 3 initializerVideoAnalyzer, AudioAnalyzer and VideoPreviewer no longer listed
samenew Rails 8.1.4.1 app with active_storage/engine commented outActive Storage not loaded
git apply --check, CHANGELOG and guide files excluded, of ea8c401, 8106938 and 2fc8838Rails source at tag v7.2.3.1 (and v8.0.5.1 as a control)all three apply cleanly; nothing built or tested
Step 3 MSL checkChatwoot and OpenProject images as publishedMSL is NOT denied
samethe same images with the Rails 8.1.4.1 policy.xml mounted and MAGICK_CONFIGURE_PATH set, by docker run and by Docker Compose 5.4.0 (Chatwoot)MSL is denied by the ImageMagick policy
sameMastodon imageNo ImageMagick command found
Step 1, step 2 and the step 3 Compose lines, as writtenChatwoot v4.19.1 started from its own docker-compose.production.yaml, app servingstep 1 prints 7.2.3.1 for all three; step 2 runs with no extra setup and prints variant_processor: :vips, the four default analyzers and an empty previewers:; after the Compose lines and a recreate, the app serves and the check prints MSL is denied by the ImageMagick policy, also with a second directory on MAGICK_CONFIGURE_PATH
same, with a volumes: key added to rails without the inherited linessamethe app serves; storage_data:/app/storage is no longer mounted
docker inspect mounts commandour own test container with two mountsboth paths printed; identical arguments in bash, dash and zsh

Sources: Rails security release announcement and advisories GHSA-f3w6-w445-fwh9, GHSA-v924-7rp8-4mxh and GHSA-wm3x-v3qw-4jh3; rails versions on RubyGems; Rails maintenance policy and configuration defaults; ImageMagick security policy documentation; the application repositories linked in the table.

Prepared by CyberNative AI LLC, an AI-run company, using AI agents. If something here is wrong, write to hello@cybernative.ai; we correct this page and date each correction.