Security· Security Disclosure

Rails' November 2026 Active Storage File Write and Read: GHSA-f3w6-w445-fwh9

Rails 8.1.4.1 and 8.0.5.2 fix a Critical (CVSS 9.8) Active Storage flaw: an uploaded image can make ImageMagick write, and read, files on the server.

Atlas Security
Security Advisories
15 min read · 3,169 words
Trevor Fannin@trevorfanninFounder, AtlasSecurity alerts and CVE breakdowns, plus infrastructure and general tech.Followon X (opens in a new tab)

Overview

Rails released 8.1.4.1 and 8.0.5.2 on the evening of November 3, 2026 (US Central; November 4 UTC), fixing 21 security issues. The headline one is GHSA-f3w6-w445-fwh9 (opens in a new tab), "Possible arbitrary file write and read in Active Storage image analysis," which Rails rates Critical, CVSS 9.8. In an application that processes images with ImageMagick, an uploaded file can make ImageMagick write arbitrary files on the server, and, when attachments are stored with the Disk service, read any file the application can read. A sibling advisory rated High, GHSA-v924-7rp8-4mxh (opens in a new tab), covers file read and possible code execution through video previews. Neither has a CVE ID as of 10:45 AM CST on November 4. Rails' release announcement (opens in a new tab): "We strongly recommend upgrading as soon as possible."

Why it's urgent: the attack needs an upload and nothing else. Attaching the file is enough, with no variant, preview, or analyze call in the application, and an unauthenticated attacker can do it wherever the app accepts uploads from them, such as a profile-picture field open to anyone who signs up. Rails also says the one attack chain reported to it may not be the only one. The file read can reach secret_key_base and the credentials in config/credentials.yml.enc, which Rails says "may in turn allow escalation to remote code execution." And Rails 8.0's security support ends on November 7, four days after this release. See the timeline.

Key facts

FieldDetail
AdvisoriesGHSA-f3w6-w445-fwh9 (opens in a new tab), "Possible arbitrary file write and read in Active Storage image analysis." Sibling: GHSA-v924-7rp8-4mxh (opens in a new tab), "Possible arbitrary file read and remote code execution in Active Storage video previews, analysis and image processing." Both are Rails' own repository advisories
SeverityGHSA-f3w6-w445-fwh9: Critical, CVSS 3.0 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). GHSA-v924-7rp8-4mxh: High, CVSS 3.1 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H). Both ratings are Rails'
WeaknessCWE-1188, "Initialization of a Resource with an Insecure Default" (GHSA-f3w6-w445-fwh9); CWE-646, "Reliance on File Name or Extension of Externally-Supplied File" (GHSA-v924-7rp8-4mxh)
ImpactArbitrary file write; arbitrary file read on the Disk service; possible escalation to code execution or to the systems whose credentials the app holds
Fixed inactivestorage 8.1.4.1 and 8.0.5.2, pushed to RubyGems at 8:47 PM and 8:34 PM CST on November 3, 2026
No official fixRails 7.2 and every older line: none is supported, and the advisory lists every activestorage below 8.0.5.2 as affected
CVE recordsNone yet, for any of the release's 21 advisories, as of 10:45 AM CST on November 4. Rails' earlier advisories received CVE IDs from GitHub, a CVE Numbering Authority, on the day they were published or the next
CreditHackerOne researcher ryotak reported GHSA-f3w6-w445-fwh9, and pirikara reported GHSA-v924-7rp8-4mxh, per the advisories

Who is affected

Release lineStatus on Nov 3, 2026Fixed inSecurity support until
8.1Supported8.1.4.1Oct 10, 2027
8.0Supported8.0.5.2Nov 7, 2026
7.2 and olderEnd of lifeno fix—

A Rails version alone doesn't make an application vulnerable to GHSA-f3w6-w445-fwh9. Rails says an application is affected only if it meets all three of these:

  • It processes Active Storage images with ImageMagick, which is config.active_storage.variant_processor = :mini_magick. That's "the default for applications on load_defaults 6.1 or earlier"; from load_defaults 7.0 the default is libvips, which this advisory doesn't involve.
  • Its ImageMagick security policy doesn't already deny the coders involved. Rails: "The policies that Debian and Ubuntu package do not."
  • It accepts file uploads from untrusted users.

We checked the packaged policies on November 4. None of them denies MSL, the scripting coder Rails' fix denies first, or the gs delegate:

DistributionImageMagickWhat its policy.xml denies
Debian 12 "bookworm"6.9.11-60URL fetches, @ indirection, and the PostScript, PDF, and XPS coders
Debian 13 "trixie"7.1.1-43URL fetches and @ indirection
Ubuntu 24.046.9.12-98URL fetches and @ indirection

The sibling advisory reaches further: it affects any app that accepts untrusted uploads and analyzes video or audio, which Active Storage does on attach by default, generates video previews, or processes images with ImageMagick. That includes apps on libvips.

Builds outside the table

  • Debian and Ubuntu package Rails themselves. Debian 12 ships rails 6.1.7.10, Debian 13 ships 7.2.2.2, Ubuntu 24.04 ships 6.1.7.3 in its universe repository, and Ubuntu 26.04 and 26.10 ship 7.2.3 and 7.2.3.2. All are below the fixed versions. Debian's tracker (opens in a new tab) lists all 21 advisories under temporary IDs, GHSA-f3w6-w445-fwh9 as TEMP-0000000-33AFA7, and marks every Debian release vulnerable as of 10:45 AM CST on November 4.
  • The full ruby Docker images include ImageMagick. ruby:<version> builds on buildpack-deps, which installs Debian's imagemagick with Debian's policy; the -slim images don't. The Dockerfile that rails new generates installs libvips, not ImageMagick, so a generated app gets ImageMagick only if someone added it.
  • GraphicsMagick doesn't read ImageMagick policies, so neither the fix's policy nor the workaround below covers an app that runs it.

How the vulnerability works

When a file is attached, Active Storage analyzes it automatically, usually in a background job, to record metadata such as an image's dimensions. In an app whose processor is :mini_magick, the image analyzer calls ImageMagick.

ImageMagick handles each file format through a module it calls a coder, and it picks the coder from what the file contains. Rails explains that "some coders act on files named inside the image rather than on the image itself," and that Active Storage "constrained none of ImageMagick's coders." An attacker who can upload a crafted file can therefore reach a coder that writes files on the server. Rails ties the file read to the Disk service; the write doesn't depend on it.

The attacker needs no account if the app takes uploads from the public. What they get runs as the application's user: they can write wherever that user can write, and on the Disk service read what it can read, including secret_key_base, the master key, and everything config/credentials.yml.enc holds. secret_key_base is the key Rails signs and encrypts its cookies and messages with. ImageMagick's own security policy guide (opens in a new tab) describes how a policy restricts the coders and resources it may use.

GHSA-v924-7rp8-4mxh: video previews and analysis

Active Storage hands uploads to ffprobe, ffmpeg, and ImageMagick under a temporary file name that keeps the uploaded file's extension, and those tools pick a decoder from the extension when the content doesn't identify its own format. So, per Rails, "an attacker who chooses the filename and declares the content type of an upload chooses which decoder processes it." An FFmpeg built with AviSynth support could then disclose files readable by the app through the preview image, or load a native library the attacker also uploaded, "possibly leading to remote code execution in the FFmpeg process." That attack needs an FFmpeg built with --enable-avisynth and the AviSynthPlus runtime. Per Rails, "Upstream FFmpeg and the common Linux distribution and Homebrew packages do not enable it; the GPL builds distributed for Windows and Linux from ffmpeg.org do." Rails adds that other decoders chosen by extension "may be reachable without AviSynth."

The fixed releases keep the extension only when it matches the blob's recorded content type, and otherwise name the temporary file with no extension.

The fix

The fixed releases ship an ImageMagick security policy inside Active Storage and point every ImageMagick process that MiniMagick starts at it, through MAGICK_CONFIGURE_PATH. The policy has 33 deny rules: the MSL scripting coder, the coders that read or delete files other than the image (TEXT, EPHEMERAL), fetch references (URL, HTTP, HTTPS, FTP, FILE), read a pixel cache (MPC), or display to a screen; every Ghostscript coder and the gs delegate; and @filename indirection. ImageMagick applies every policy file on its search path, so this adds to the host's policy rather than replacing it, and it covers every ImageMagick command MiniMagick runs, not only Active Storage's.

rails/rails · 468aa9a · Nov 3, 2026 (8.1)
active_storage/image_magick/policy.xml
68 lines added, 0 removed
active_storage/image_magick.rb
63 lines added, 0 removed
active_storage/engine.rb
5 lines added, 1 removed
analyzer/image_analyzer/image_magick.rb
3 lines added, 8 removed
transformers/image_magick.rb
2 lines added, 0 removed
CHANGELOG and Active Storage guide
95 lines added, 0 removed
Tests (3 files)
322 lines added, 0 removed
7 files changed558 lines added, 9 removed

The 8.0 commit, ea8c401 (opens in a new tab), adds the same policy and loader in 615 lines, most of them tests. We tested the shipped policy on November 4 by loading it through MAGICK_CONFIGURE_PATH with the ImageMagick that Debian 12, Debian 13, and Ubuntu 24.04 package: on all three, MSL was denied and ImageMagick refused a harmless PostScript test file.

Which applications are exposed

What follows is our reading of the two advisories' requirements, not a confirmed exploit path for any one application.

SetupGHSA-f3w6-w445-fwh9GHSA-v924-7rp8-4mxh
:mini_magick, public uploads, Disk serviceFile write and file readAffected
:mini_magick, public uploads, S3, GCS, or AzureFile writeAffected
:vips, public uploads of video or audioNot affectedAffected; worst with an AviSynth FFmpeg
Uploads only from trusted staffNot affectedNot affected

The requirement that rules most apps in or out is the processor. Apps generated before Rails 7.0 and never moved to newer framework defaults run :mini_magick unless someone changed it, and they're also the apps likeliest to be on an unsupported Rails. Patch those first, and among them, the ones that store attachments on the Disk service, because the file read is what puts secrets at risk.

How to check your systems

Run these in the application's repository, and on the hosts or images that run it. A fixed Rails applies its policy only to the ImageMagick processes MiniMagick starts, so the ImageMagick checks below show the system policy: what an unpatched app runs under, and where the workaround goes. We tested the commands with GNU grep 3.8 against two sample Rails apps, and the ImageMagick and FFmpeg checks in Debian 12, Debian 13, and Ubuntu 24.04 containers.

Check the Rails and mini_magick versions

Shell
grep -E '^    (activestorage|mini_magick) \(' Gemfile.lock

This matches only the resolved versions, not the dependency lines beneath other gems. activestorage below 8.1.4.1 on the 8.1 line, or below 8.0.5.2 otherwise, is affected. If you use :mini_magick, mini_magick must read 5.1.0 or later before you upgrade Rails.

Check the image processor and storage service

Shell
grep -rnE 'load_defaults|variant_processor' config/grep -rnE 'active_storage\.service *=' config/environments/grep -nE -B1 'service: *Disk' config/storage.yml

The first shows your framework defaults and any explicit processor. No variant_processor line and load_defaults 6.1 or lower means :mini_magick. The last two show whether the service your production environment uses is a Disk service; -B1 prints the service's name above its service: Disk line.

Check ImageMagick's system policy

Shell
convert -version | head -1                                # ImageMagick 6magick -version | head -1                                 # ImageMagick 7convert -list policy | grep -B1 -E 'pattern: (MSL|gs)$'   # 6; use magick on 7

A denied coder prints rights: None above its pattern. No output means the system policy allows MSL and the gs delegate, which is what we found on all three distributions. Run it inside your production image, not on your laptop: docker run --rm --entrypoint sh your-image -c 'convert -list policy'.

Check FFmpeg for AviSynth

Shell
ffmpeg -hide_banner -demuxers 2>/dev/null | grep -i avisynth

No output means no AviSynth demuxer. It printed nothing for Debian 13's FFmpeg 7.1.5. We didn't test a build with AviSynth enabled; per Rails, ffmpeg.org's GPL builds for Windows and Linux are the common ones that have it.

How to fix

Update Rails

Update to 8.1.4.1. 8.0.5.2 fixes 8.0, but 8.0's security support ends on November 7, so landing there means another upgrade next week. Rails' patches for 8.1 (opens in a new tab) and 8.0 (opens in a new tab) are there if you can't move gem versions at once. Restart every app server and background worker afterward; Active Storage analysis often runs in a job.

Four changes can break things on upgrade:

  • mini_magick below 5.1 stops the app from booting when the processor is :mini_magick. Rails: "With an older mini_magick, such an application raises an exception during boot." mini_magick 5.1.0 shipped in January 2025, so bump it in the same change.
  • PostScript and PDF through ImageMagick stop working. An app that renders them has to re-allow the gs delegate and the coders it uses in the host's policy.xml, because a host policy that allows a coder overrides the shipped deny.
  • Some apps don't receive the shipped policy at all. Rails names three: one that replaces MiniMagick.cli_env after boot, clears the environment with MiniMagick.cli_prefix, or installs its own MiniMagick::Shell. They need the rules in the system policy, as in the workaround below.
  • Two more from the same release. Direct uploads to Google Cloud Storage now send an x-goog-content-length-range header, so the bucket's CORS configuration must list it in responseHeader or browser uploads fail. And FFmpeg is now limited to common audio and video formats (config.active_storage.ffmpeg_allowed_formats), so files in other formats stop getting previews and metadata.

Change secrets if you use the Disk service

Upgrading closes the hole but doesn't undo a read that already happened. If attachments are stored with the Disk service, Rails 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 adds: "Do not retain an exposed secret as a fallback." The video advisory asks the same of apps whose FFmpeg has AviSynth. Changing secret_key_base signs everyone out and invalidates signed and encrypted cookies, signed global IDs, and Active Storage URLs, so plan the rotation as a deploy of its own.

If you can't patch immediately

Rails' workaround is to copy the shipped policy's rules into ImageMagick's system policy. At a minimum, deny the MSL coder, the Ghostscript coders, and the gs delegate. Add these lines just before </policymap> in /etc/ImageMagick-6/policy.xml (Debian 12, Ubuntu 24.04) or /etc/ImageMagick-7/policy.xml (Debian 13):

XML
1<policy domain="coder" rights="none" pattern="MSL"/>2<policy domain="delegate" rights="none" pattern="gs"/>3<policy domain="coder" rights="none" pattern="{PS,PS2,PS3,EPS,EPS2,EPS3}"/>4<policy domain="coder" rights="none" pattern="{EPI,EPSF,EPSI,EPT,EPT2,EPT3}"/>5<policy domain="coder" rights="none" pattern="{PDF,AI,EPDF,PDFA,POCKETMOD,XPS,PCL}"/>

These are Rails' minimum rules, with its one long Ghostscript pattern split across three lines. We tested them on all three distributions on November 4: afterward, the policy check listed MSL and gs as denied and ImageMagick refused a harmless PostScript file, while ordinary PNG and JPEG conversion still worked where we checked it, on Debian 13 and Ubuntu 24.04. For the full set, copy every rule from the shipped policy.xml (opens in a new tab). In containers, make the change in the image, or the next deploy undoes it.

End-of-life versions

Rails gives each minor release two years of security fixes from its first release. Only 8.1 and 8.0 are on its supported list (opens in a new tab), and Rails ships no fixed release for 7.2 or older. Its policy for unsupported series: "We may provide backports of the fixes and publish them to git, however there will be no new versions released." The advisory's patches are for 8.1 and 8.0 only.

For an app on 7.2 or older, the system-policy workaround above is the fix you can apply today; it works the same whatever the Rails version, because it changes ImageMagick, not Rails. Pair it with the FFmpeg workaround if the app handles video or audio, then plan the move to 8.1. Debian's and Ubuntu's packaged Rails are on these lines too.

Timeline

All times are US Central: CST (UTC−6).

  • Fix
  • Advisory or rating
  1. Nov 3
    1. 9:01–9:09 PMRails publishes its 21 GitHub advisories, GHSA-f3w6-w445-fwh9 last, rated Critical

    2. 8:58 PMRails posts the release to the oss-security list

    3. 8:34–8:47 PMThe 8.0.5.2 and 8.1.4.1 gems are published to RubyGems

    4. 8:30 PMRails announces 8.0.5.2 and 8.1.4.1, fixing 21 security issues

    5. 2:10 PMRails' 8.1 fix commit for GHSA-f3w6-w445-fwh9 is dated, followed by the 8.0 commit at 4:06 PM

Other vulnerabilities fixed in this release

The release fixed 19 more issues. Titles and ratings are Rails'; "8.1 only" marks the four that don't reach 8.0. Each advisory links patches for both lines.

AdvisorySeverityTitleLines
GHSA-wm3x-v3qw-4jh3 (opens in a new tab)High · 7.5Possible Strong Parameters bypass in Parameters#each_key in Action Pack8.0, 8.1
GHSA-8474-xrp6-wh69 (opens in a new tab)High · 7.5Possible DoS vulnerability in Active Support safe_constantize8.0, 8.1
GHSA-2gff-2mmg-m73p (opens in a new tab)High · 7.4Possible IP spoofing in Action Dispatch RemoteIp8.1 only
GHSA-x6mj-8jx9-qhqv (opens in a new tab)Medium · 6.8Possible sensitive session information leak in Active Storage proxy mode8.0, 8.1
GHSA-2p2f-4rq4-gjwc (opens in a new tab)Medium · 6.1Possible XSS vulnerability in Action View text helpers8.0, 8.1
GHSA-v6rj-xm57-3p59 (opens in a new tab)Medium · 6.1Possible XSS vulnerability in Action View highlight helper8.0, 8.1
GHSA-rq8q-p985-fjq7 (opens in a new tab)Medium · 6.1Possible XSS vulnerability in Action View strip_tags8.0, 8.1
GHSA-rwvh-fw6r-pwvp (opens in a new tab)Medium · 5.9Possible DoS vulnerability in Action Controller Live streaming8.0, 8.1
GHSA-4v2w-w6g6-f8f8 (opens in a new tab)Medium · 5.3Possible DoS vulnerability in Active Storage proxy mode via storage errors during streaming8.0, 8.1
GHSA-hfr4-8rjc-97m2 (opens in a new tab)Medium · 5.3Possible circumvention of file size limits in Active Storage direct uploads to Google Cloud Storage8.0, 8.1
GHSA-r9jg-fmfx-2gv6 (opens in a new tab)Medium · 4.8Possible cache poisoning in Action Pack content negotiation8.0, 8.1
GHSA-68p9-83h6-5wpj (opens in a new tab)Medium · 4.7Possible XSS vulnerability in Action View tag helpers8.0, 8.1
GHSA-3w93-6hmw-whh4 (opens in a new tab)Medium · 4.7Unsigned Content-Type in Active Storage GCS direct uploads with cache_control8.0, 8.1
GHSA-2w9f-fxwj-w2qf (opens in a new tab)Medium · 4.7Possible XSS vulnerability in Active Support MessagePack serializer8.1 only
GHSA-p2pm-g2h6-7j5j (opens in a new tab)Medium · 4.3Possible DoS vulnerability in Active Storage filename handling8.0, 8.1
GHSA-2586-8ghr-69fj (opens in a new tab)Medium · 4.2Possible restoration of destroyed sessions in Action Dispatch CacheStore8.0, 8.1
GHSA-3f4q-8x5m-76v8 (opens in a new tab)Low · 3.7Possible local file disclosure in Active Storage video previews and analysis8.0, 8.1
GHSA-5957-c7qm-m469 (opens in a new tab)Low · 3.7Possible signature replay in Action Mailbox Mailgun ingress8.0, 8.1
GHSA-gmj8-hvj3-49mw (opens in a new tab)Low · 3.1Missing SameSite attribute on session cookies from Action Pack session stores8.0, 8.1

Updates to this post

We'll revise this post and mark it updated when any of these change: CVE IDs or an NVD score for these advisories; Debian or Ubuntu tracking them or shipping fixed rails packages; a public proof of concept or a report of exploitation; a change to Rails' advisories; and Rails 8.0's end of security support on November 7.

Get help

An outside scan can't read your Gemfile.lock, but it can see much of what surrounds it. Our free security audit fingerprints your stack, framework included, with versions where they show, checks every version it can read against its vendor's support window, and looks for files that should never be public, such as .env files and version-control folders, which hold the same kind of secrets this bug can read.

Atlas Service
Free Security Audit
Non-destructive checks of your verified domains and public IPs, and a PDF report with every finding ranked and a fix for each, within 3 business days of verification.

Sources

Atlas Security
Security Advisories

The Atlas security byline: write-ups of vulnerabilities in widely deployed software — what changed, who is exposed, and what to check — verified against primary sources.

Continue reading

More from the Atlas Meridian

Security
12 min read

APT's November 2026 Download Verification Bypass: CVE-2026-109518

An APT flaw lets an on-path attacker swap a verified package and run code as root on Debian, Ubuntu, and derivatives. Debian's fix is out; update APT now.

Atlas Security
Security Advisories
View category
Security
20 min read

WordPress's October 2026 Upgrade RCE and Stored XSS Fixes: WordPress 7.1.4

WordPress 7.1.4 fixes 22 vulnerabilities, including an RCE during core updates and stored XSS, with no CVEs. Who's exposed, how to check, and what to block.

Atlas Security
Security Advisories
View category
Security
26 min read

PHP's October 2026 Critical RCEs: CVE-2026-109618 and CVE-2026-109619

PHP fixed two critical unauthenticated RCEs in 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Attackers chain them with a Linux kernel bug to get root: patch both now.

Atlas Security
Security Advisories
View category
Engage · Atlas Engineering

Reading is one thing. Shipping is another.

If this writeup resonates with what you're building, let's talk. We'll connect you directly with an engineer to assist.