Neutron, nuestro motor de IA, obtuvo un 97.1% en el benchmark CyberGym de UC Berkeley. Más información

Análisis a fondo

Análisis a fondo

RCE en Rails Active Storage, corregido en 8.1.4.1 (GHSA-f3w6-w445-fwh9)

Rails Active Storage antes de 8.0.5.2 y 8.1.4.1 deja que una subida maliciosa haga leer o escribir archivos a ImageMagick o FFmpeg, con posible RCE; actualice.

TL;DR

  • Un archivo malicioso subido a una aplicación Rails que procesa adjuntos con ImageMagick puede permitir a un atacante sin autenticar escribir archivos arbitrarios en el servidor. El equipo de Rails divulgó la falla el 4 de noviembre de 2026.
  • Las versiones de Active Storage anteriores a 8.0.5.2 y la serie 8.1 anterior a 8.1.4.1 están afectadas. Una segunda falla de la misma serie de versiones deja que un nombre de archivo subido elija qué decodificador de FFmpeg o ImageMagick se ejecuta.
  • El equipo de Rails califica la falla de escritura de archivos como crítica (CVSS v3.0 9.8) y la del decodificador como alta (CVSS v3.1 8.8). No hay CVE asignado, y ninguna de las dos fallas figura en el catálogo Known Exploited Vulnerabilities (KEV) de CISA al 4 de noviembre de 2026.
  • Actualice activestorage a 8.0.5.2 o 8.1.4.1 ahora, y lea las notas de migración: el correctivo incluye una política de seguridad de ImageMagick que exige mini_magick 5.1 o posterior. Vea «¿Cómo corregirlo?».

¿Está afectado?

Para la falla crítica de escritura de archivos, GHSA-f3w6-w445-fwh9, deben cumplirse todas estas condiciones:

  • Su aplicación procesa los adjuntos de Active Storage con ImageMagick. Es config.active_storage.variant_processor = :mini_magick, el valor por omisión de las aplicaciones con load_defaults 6.1 o anterior.
  • Su equipo ejecuta ImageMagick bajo una política de seguridad que no niega de antemano los codificadores implicados. Revise en su policy.xml los codificadores MSL, MVG y los que dependen de Ghostscript. La política que empaqueta Debian 12 niega los codificadores de Ghostscript y URL, pero no tiene ninguna regla MSL y su única regla MVG está comentada, así que no bloquea la cadena reportada.
  • Su aplicación acepta subidas de archivos de usuarios no confiables.

Para la falla del decodificador, GHSA-v924-7rp8-4mxh, deben cumplirse todas estas condiciones:

  • Su aplicación acepta subidas de usuarios no confiables.
  • Analiza adjuntos de video o audio, lo que Active Storage hace al adjuntar por omisión, genera vistas previas de video, o procesa imágenes con ImageMagick.

La ruta AviSynth de la falla del decodificador exige un FFmpeg compilado con --enable-avisynth y el runtime AviSynthPlus. El FFmpeg oficial y los paquetes habituales de las distribuciones Linux y de Homebrew no lo activan. Las compilaciones GPL distribuidas para Windows y Linux desde ffmpeg.org sí lo activan, y otros decodificadores que se seleccionan por la extensión pueden ser alcanzables sin AviSynth.

Rama Versiones afectadas Versión corregida
8.1.x 8.1.0 a 8.1.4 8.1.4.1, publicada el 2026-11-04
8.0.x 8.0.0 a 8.0.5.1 8.0.5.2, publicada el 2026-11-04
7.2 y todas las series anteriores No habrá correctivo; la serie no tiene soporte Actualizar al menos a 8.0.5.2

Las versiones de seguridad de Rails solo cubren las series 8.0 y 8.1, y la serie 8.0 sale del soporte de seguridad el 7 de noviembre de 2026 según la política de mantenimiento. Las aplicaciones en 7.2 o anterior deben tratar esta publicación como la fecha límite para pasar a una serie con soporte. La gema activestorage acumula 561,823,760 descargas en RubyGems al 4 de noviembre de 2026, y la gema rails 811,345,791.

Compruebe qué ejecuta:

# 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

¿Cómo corregirlo?

  1. Lleve la aplicación a una versión corregida. Fije la gema rails en 8.1.4.1, o 8.0.5.2 en la serie 8.0:
# Gemfile
gem "rails", "~> 8.1.4.1"

# then
bundle update rails
  1. Lea las notas de migración antes de desplegar. Las versiones corregidas aplican una política de seguridad de ImageMagick a cada proceso ImageMagick que lanza MiniMagick, lo que exige mini_magick 5.1 o posterior. Una aplicación con un mini_magick más antiguo lanza una excepción durante el arranque.
  2. Recree los contenedores de la aplicación si despliega en contenedores. Descargar una imagen nueva sin recrear el contenedor en ejecución deja el código antiguo en su sitio.
  3. Si su aplicación renderiza PostScript o PDF mediante ImageMagick, vuelva a permitir el delegado gs y los codificadores que usa en el policy.xml del equipo, porque la política incluida los niega. Una política del equipo que permite un codificador prevalece sobre la denegación de la política incluida.
  4. Lleve las reglas de la política incluida a la política del sistema de ImageMagick si la política incluida no puede llegar a su aplicación. Es el caso cuando la aplicación:
    • reemplaza MiniMagick.cli_env después del arranque, vacía el entorno con MiniMagick.cli_prefix o instala su propio MiniMagick::Shell;
    • usa GraphicsMagick, que no lee las políticas de ImageMagick.

Para las aplicaciones que no puedan actualizar todavía, la solución provisional del aviso es copiar las reglas de la política incluida en la política del sistema de ImageMagick. El archivo incluido es activestorage/lib/active_storage/image_magick/policy.xml, y una ruta del sistema habitual es /etc/ImageMagick-7/policy.xml. Como mínimo, niegue el codificador MSL, los codificadores Ghostscript y el delegado 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}"/>

Para la falla del decodificador, las aplicaciones que no puedan actualizar pueden impedir que Active Storage ejecute FFmpeg sobre los archivos subidos, adaptado del aviso. Esto cierra la ruta de FFmpeg, pero no los decodificadores de ImageMagick que se eligen por la extensión:

# 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]

¿Cuál es la causa raíz?

Dos propiedades de herramientas externas coincidieron con dos valores por omisión de Active Storage.

Para la falla crítica, ImageMagick elige un codificador a partir del contenido del archivo que recibe. Algunos codificadores actúan luego sobre archivos nombrados dentro de la imagen en lugar de sobre la imagen misma. El codificador MSL es la interfaz de scripts XML de ImageMagick: lee y escribe archivos nombrados dentro de la imagen. Otros leen o borran un archivo distinto de la imagen, o pasan el archivo al delegado Ghostscript.

Active Storage no imponía ninguna restricción a los codificadores de ImageMagick antes de esta versión. El analizador de ImageMagick se ejecuta cuando se adjunta un archivo, y adjuntar la subida basta por tanto para alcanzar un codificador. No se requiere ninguna llamada a variant, preview ni analyze.

El commit del correctivo para 8.1, 468aa9a93fc98f5476b6821770f4ccfcb7f7d328 («Ship an ImageMagick security policy for every MiniMagick process», 3 de noviembre de 2026), añade la política y la conecta a través del engine:

# activestorage/lib/active_storage/engine.rb at 8.1.4.1
if ActiveStorage::MINIMAGICK_AVAILABLE && !ActiveStorage::MINIMAGICK_UNSECURABLE
  ActiveStorage::ImageMagick.apply_policy
end

Para la falla alta, ActiveStorage::Blob#open escribe un blob en un archivo temporal cuyo nombre lleva la extensión del nombre del archivo subido, y luego entrega esa ruta a ffprobe, ffmpeg e ImageMagick. La línea vulnerable, en 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 es decisión de quien sube el archivo. FFmpeg elige su demuxer AviSynth por la sola extensión .avs, e ImageMagick selecciona codificadores y delegados desde la extensión de la misma forma.

¿Cómo se explota?

Para la falla crítica:

  1. El atacante sube un archivo malicioso a una aplicación afectada. El archivo solo tiene que adjuntarse; el analizador se ejecuta al adjuntar, y no se requiere ninguna llamada a variant, preview ni analyze.
  2. ImageMagick elige un codificador a partir del contenido del archivo. En la cadena reportada, un SVG subido alcanzó el codificador de scripts MSL, que lee y escribe los archivos que nombra su script.
  3. El codificador escribe en el servidor archivos elegidos por el atacante. Cuando los adjuntos se almacenan con el servicio Disk, la misma clase de codificadores puede leer archivos arbitrarios legibles por el proceso de la aplicación.
  4. Esos archivos suelen incluir secret_key_base y credenciales de sistemas externos. El aviso indica que esto puede permitir escalar a ejecución remota de código o un movimiento lateral, y que se reportó una cadena de ataque concreta aunque pueden existir otras.

Para la falla alta, las pruebas del correctivo documentan los nombres del ataque:

  1. El atacante sube un archivo llamado attack.avs y declara su tipo de contenido video/mp4. El blob se analiza al adjuntarse, y Active Storage entrega el archivo temporal a ffprobe y ffmpeg.
  2. Como el nombre del archivo temporal termina en .avs, un FFmpeg compilado con soporte AviSynth evalúa el archivo como un script AviSynth.
  3. El script importa archivos legibles por el proceso de la aplicación y los divulga mediante la imagen de vista previa. También puede cargar una biblioteca nativa subida por el atacante, lo que podría llevar a ejecución remota de código en el proceso de FFmpeg.
  4. Otros decodificadores que FFmpeg o ImageMagick eligen por la extensión pueden ser alcanzables sin AviSynth. Las pruebas también cubren evil.mp4, una subida declarada image/png cuyo contenido es una lista de reproducción que nombra un archivo local. Su extensión .mp4 podría llevar a ImageMagick a delegarlo en FFmpeg.

¿Cómo fluye el ataque?

Una subida sin autenticar llega a una herramienta externa que toma sus instrucciones de la subida, y la herramienta actúa luego sobre archivos que el atacante nombra.

flowchart LR A["Subida no confiable"] --> B["Adjuntar el archivo
ejecuta el analizador"] B --> C["ImageMagick elige un codificador
por el contenido del archivo"] C --> D["Ninguna política restringe
los codificadores"] D --> E["El codificador MSL actúa sobre archivos
nombrados en la imagen"] E --> F["Escritura de archivos arbitrarios
en el servidor"] F --> G["Servicio Disk: lectura de archivos secretos,
posible escalada a ejecución de código"]

¿Qué puede hacer un atacante?

La falla crítica puede dar a quien sube un archivo, sin autenticación, escrituras de archivos arbitrarios en el servidor. El equipo de Rails le asigna CVSS v3.0 9.8, CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Deben darse tres condiciones a la vez: un procesador de variantes ImageMagick, una política del equipo que no niegue ya los codificadores implicados y subidas de usuarios no confiables.

El codificador MSL y los codificadores similares que escriben archivos también leen archivos cuando los adjuntos usan el servicio Disk, lo que suele exponer secret_key_base, la clave maestra y credenciales de sistemas externos. El equipo de Rails afirma que esto puede permitir escalar a ejecución remota de código o un movimiento lateral hacia esos sistemas.

La falla alta puede divulgar archivos legibles por el proceso de la aplicación a través de una imagen de vista previa generada. El equipo de Rails le asigna CVSS v3.1 8.8, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H, que supone un atacante con privilegios bajos en la aplicación.

Para la falla alta, tanto la divulgación de archivos como la ejecución de código exigen un FFmpeg compilado con soporte AviSynth. Otros decodificadores elegidos por la extensión pueden ser alcanzables sin AviSynth, pero el aviso no les atribuye ningún impacto concreto.

¿Por qué funciona la corrección?

El correctivo de la falla crítica restringe cada proceso ImageMagick que lanza MiniMagick, no solo el del analizador. La política incluida niega:

  • el codificador MSL y los codificadores que leen o borran archivos distintos de la imagen;
  • las referencias remotas y locales, y la presentación en pantalla;
  • todos los codificadores respaldados por Ghostscript, junto con el delegado gs;
  • la indirección @filename.

Como ImageMagick aplica cada policy.xml de su ruta de búsqueda, la política incluida se añade a la del equipo en lugar de reemplazarla.

El correctivo de la falla alta impide que el nombre del archivo subido elija el decodificador. El archivo temporal conserva la extensión solo cuando Marcel asocia esa extensión al tipo de contenido registrado del blob, y no lleva ninguna en caso contrario. El commit del correctivo, 72136ff39153bc8d63ecbc899993848eb3d6573e («Active Storage: tempfile extension must match the blob's content type»), sustituye la extensión sin filtrar por una elección validada:

--- 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)

Los archivos cuya extensión subida contradice su tipo de contenido se siguen procesando, y la herramienta externa detecta entonces su formato a partir del contenido. Una subida de formulario cuyo archivo temporal de Rack no supera la misma comprobación se copia a un archivo temporal con el nombre correcto antes de procesarse.

El correctivo de la falla crítica reduce la superficie de ataque sin demostrar que no exista otra cadena. El aviso indica que se reportó una cadena de ataque y que el equipo de Rails no supone que sea la única. Algunas aplicaciones nunca reciben la política incluida; vea «¿Cómo corregirlo?».

¿Cómo sé si fui comprometido?

Rails no publica indicadores para ninguna de las dos fallas. Un intento fallido puede no dejar rastro.

Para la falla crítica, revise el equipo en busca de archivos que el usuario de la aplicación no haya creado, en particular en rutas servidas por el web. Si su aplicación cumplía las condiciones y almacenaba los adjuntos con el servicio Disk antes de actualizar, trate cada secreto legible por el proceso de la aplicación como expuesto. El aviso nombra secret_key_base, la clave maestra, todo lo que contiene config/credentials.yml.enc, las credenciales de almacenamiento y base de datos, y los tokens de servicios de terceros.

Para la falla alta, una aplicación que ejecutaba un FFmpeg con soporte AviSynth debe tratar cada secreto legible por el proceso de la aplicación como expuesto, para el mismo conjunto. Cambiar secret_key_base expira las sesiones activas e invalida las cookies firmadas y cifradas, los identificadores globales firmados y las URL de Active Storage.

Cronología

El correctivo del archivo temporal se redactó 53 días antes de que salieran las versiones coordinadas.

El correctivo del archivo temporal de Rails se redactó el 12 de septiembre y la publicación coordinada salió el 4 de noviembre.
Figura 1: del primer commit de correctivo a la publicación coordinada. Fuente: commits de correctivo y versiones de Rails en GitHub, consultados el 4 de noviembre de 2026

  • 2026-09-12: El correctivo de la extensión del archivo temporal se redactó en la rama 8.1 (commit 72136ff3).
  • 2026-11-03: Se hizo commit del correctivo de la política de seguridad de ImageMagick (commit 468aa9a9, 20:10 UTC).
  • 2026-11-04: Se publicaron Rails 8.0.5.2 (02:31 UTC) y 8.1.4.1 (02:46 UTC) en GitHub.
  • 2026-11-04: El anuncio coordinado de los 21 problemas corregidos se publicó en oss-security (02:58 UTC).
  • 2026-11-04: Se publicaron los dos avisos (GHSA-v924-7rp8-4mxh a las 03:02 UTC, GHSA-f3w6-w445-fwh9 a las 03:09 UTC).

FAQ

¿El correctivo cambia el arranque de mi aplicación?

Una aplicación cuyo procesador de variantes es :mini_magick necesita mini_magick 5.1 o posterior, porque aplicar la política lo exige. Con un mini_magick más antiguo, la aplicación lanza una excepción durante el arranque. Las aplicaciones que usan libvips, el valor por omisión desde load_defaults 7.0, no están sujetas a este requisito.

Uso libvips. ¿Estoy afectado?

La falla crítica de escritura de archivos exige el procesador de variantes ImageMagick, así que una aplicación con libvips no está afectada por ella. La falla del decodificador se aplica con independencia del procesador: los adjuntos de video y audio se analizan con ffprobe al adjuntar por omisión, y el correctivo del archivo temporal cubre esa ruta.

Mi aplicación renderiza PDF o PostScript mediante ImageMagick. ¿Qué hago?

La política incluida niega todos los codificadores respaldados por Ghostscript y el delegado gs. Su aplicación debe volver a permitir el delegado y los codificadores que usa en el policy.xml del equipo, o el renderizado dejará de funcionar tras la actualización.

¿Cuáles son los otros 19 problemas de seguridad de esta versión?

La misma versión corrige tres problemas más de severidad alta: una omisión de Strong Parameters en Parameters#each_key, suplantación de IP en Action Dispatch RemoteIp (solo 8.1) y una denegación de servicio en safe_constantize. Los otros 16 son de severidad media o baja, entre ellos correctivos de cross-site scripting (XSS), de denegación de servicio y de manejo de sesión. El anuncio de oss-security enlaza cada aviso.

¿Por qué no hay CVE asignado?

El equipo de Rails publicó ambas fallas como avisos de seguridad del repositorio, y ninguna lleva identificador CVE al 4 de noviembre de 2026. Tampoco figura ninguna en la GitHub Advisory Database en esa fecha, así que los escáneres de dependencias que se basan en los CVE o en esa base pueden no señalarlas. Compare su Gemfile.lock directamente con las versiones corregidas.

Mi serie de Rails es 7.2 o anterior. ¿Qué hago?

No habrá correctivo para su serie, porque no tiene soporte. Actualice al menos a 8.0.5.2, y planifique salir de 8.0: su soporte de seguridad termina el 7 de noviembre de 2026.

Encuentre sus aplicaciones Rails expuestas antes de que lo haga un atacante

Las aplicaciones Rails que aceptan subidas de usuarios no confiables son las primeras que hay que corregir. El Web Agentic Deep Scan de Ostorlab analiza sus aplicaciones web y API en busca de vulnerabilidades, lo que le ayuda a encontrar los puntos de subida expuestos a usuarios no confiables.

Referencias

  • GHSA-f3w6-w445-fwh9, aviso de seguridad de Rails, «Possible arbitrary file write and read in Active Storage image analysis»: https://github.com/rails/rails/security/advisories/GHSA-f3w6-w445-fwh9 (consultado el 4 de noviembre de 2026)
  • GHSA-v924-7rp8-4mxh, aviso de seguridad de 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 (consultado el 4 de noviembre de 2026)
  • Anuncio de las versiones de seguridad de Rails, 21 problemas corregidos en 8.0.5.2 y 8.1.4.1: https://www.openwall.com/lists/oss-security/2026/11/04/2 (consultado el 4 de noviembre de 2026)
  • Commit de correctivo 468aa9a93fc98f5476b6821770f4ccfcb7f7d328, «Ship an ImageMagick security policy for every MiniMagick process» (8.1): https://github.com/rails/rails/commit/468aa9a93fc98f5476b6821770f4ccfcb7f7d328 (consultado el 4 de noviembre de 2026)
  • Commit de correctivo 72136ff39153bc8d63ecbc899993848eb3d6573e, «Active Storage: tempfile extension must match the blob's content type» (8.1): https://github.com/rails/rails/commit/72136ff39153bc8d63ecbc899993848eb3d6573e (consultado el 4 de noviembre de 2026)
  • Commit de correctivo ea8c40121ce53a3d0255cd4eb6d13bfe3bc01776, «Ship an ImageMagick security policy for every MiniMagick process» (8.0): https://github.com/rails/rails/commit/ea8c40121ce53a3d0255cd4eb6d13bfe3bc01776 (consultado el 4 de noviembre de 2026)
  • Commit de correctivo 8106938fb0a595f11006dd1497cd409e27d7d636, «Active Storage: tempfile extension must match the blob's content type» (8.0): https://github.com/rails/rails/commit/8106938fb0a595f11006dd1497cd409e27d7d636 (consultado el 4 de noviembre de 2026)
  • CHANGELOG de Active Storage en v8.1.4.1: https://github.com/rails/rails/blob/v8.1.4.1/activestorage/CHANGELOG.md (consultado el 4 de noviembre de 2026)
  • Versión Rails 8.0.5.2: https://github.com/rails/rails/releases/tag/v8.0.5.2 (consultada el 4 de noviembre de 2026)
  • Versión Rails 8.1.4.1: https://github.com/rails/rails/releases/tag/v8.1.4.1 (consultada el 4 de noviembre de 2026)
  • Descargas de la gema activestorage: https://rubygems.org/gems/activestorage (consultadas el 4 de noviembre de 2026)
  • Política de mantenimiento de Rails: https://rubyonrails.org/maintenance (consultada el 4 de noviembre de 2026)
  • Documentación de la política de seguridad de ImageMagick: https://imagemagick.org/security-policy/ (consultada el 4 de noviembre de 2026)
  • policy.xml de ImageMagick empaquetado por Debian 12: https://sources.debian.org/src/imagemagick/8:6.9.11.60+dfsg-1.6+deb12u11/config/policy.xml/ (consultado el 4 de noviembre de 2026)