Possible arbitrary file read and remote code execution in Active Storage video previews, analysis and image processing
Published: November 04, 2026
SECURITY IDENTIFIERS
- GHSA: GHSA-v924-7rp8-4mxh
- Vendor Advisory: https://github.com/rails/rails/security/advisories/GHSA-v924-7rp8-4mxh
GEM
FRAMEWORK
SEVERITY
CVSS v3.x: 8.8 (High)
PATCHED VERSIONS
~> 8.0.5, >= 8.0.5.2
>= 8.1.4.1
DESCRIPTION
Impact
ActiveStorage::Blob#open writes a blob to a tempfile whose name carries the
extension of the uploaded filename, and hands that path to ffprobe
(VideoAnalyzer, AudioAnalyzer), ffmpeg (VideoPreviewer) and
ImageMagick (ImageAnalyzer, the :mini_magick variant processor). These
tools select a decoder from the file extension when the content does not
identify its own format, so 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 treats a file with the .avs extension as an
AviSynth script and evaluates it, which could disclose files readable by the
application process through the preview image, or load a native library the
attacker has also uploaded, possibly leading to remote code execution in the
FFmpeg process. ImageMagick selects its coders and delegates from the
extension in the same way.
Details
The fixed releases keep the uploaded extension on the tempfile only when Marcel maps that extension to the blob's recorded content type, and name the tempfile with no extension otherwise. A form upload whose Rack tempfile fails the same check is copied to a correctly named tempfile before processing. Files whose uploaded extension disagrees with their content type are still processed; the external tool detects their format from the content. The Active Storage CHANGELOG describes the change.
Affected applications
An application is affected if it meets all of these requirements:
- Accepts uploads from untrusted users.
- Analyzes video or audio attachments (which Active Storage does on attach by default), generates video previews, or processes images with ImageMagick.
The AviSynth attack additionally requires an FFmpeg built with
--enable-avisynth and the AviSynthPlus runtime on the host. 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. Other
decoders that FFmpeg or ImageMagick select from the extension may be reachable
without AviSynth.
Mitigation
- Upgrade to a fixed version of
activestorage.
Expire and change secrets
Upgrading closes the vulnerability but does not undo a disclosure that already
occurred. An application that meets the AviSynth requirement above should
treat every secret readable by the application process as potentially exposed
and change it, including secret_key_base, the master key and everything in
config/credentials.yml.enc that it decrypts, the Active Storage service
credentials, database credentials, and tokens for third-party services.
Changing secret_key_base expires active sessions and invalidates signed and
encrypted cookies, signed global IDs and Active Storage URLs. Do not retain an
exposed secret as a fallback.
Workarounds
Applications that cannot upgrade can stop Active Storage from running FFmpeg
on uploaded files by removing ActiveStorage::Previewer::VideoPreviewer from
config.active_storage.previewers, and
ActiveStorage::Analyzer::VideoAnalyzer and
ActiveStorage::Analyzer::AudioAnalyzer from
config.active_storage.analyzers. Running an FFmpeg built without AviSynth
support closes the AviSynth attack but not the extension-selected decoders of
ImageMagick.
Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
- 8.1: https://github.com/rails/rails/commit/72136ff39153bc8d63ecbc899993848eb3d6573e.patch
- 8.0: https://github.com/rails/rails/commit/8106938fb0a595f11006dd1497cd409e27d7d636.patch
Versions affected
- activestorage < 8.0.5.2
- activestorage >= 8.1, < 8.1.4.1
Credit
This issue was responsibly reported by HackerOne researcher pirikara.
RELATED
- https://rubygems.org/gems/activestorage/versions/8.1.4.1
- https://github.com/rails/rails/releases/tag/v8.1.4.1
- https://rubygems.org/gems/activestorage/versions/8.0.5.2
- https://github.com/rails/rails/releases/tag/v8.0.5.2
- https://github.com/rails/rails/commit/72136ff39153bc8d63ecbc899993848eb3d6573e
- https://github.com/rails/rails/commit/8106938fb0a595f11006dd1497cd409e27d7d636
- https://github.com/rails/rails/security/advisories/GHSA-v924-7rp8-4mxh
