Alguien sube una foto. El avatar de su perfil, el adjunto de un ticket, la imagen de un producto en tu portal de clientes. Tu aplicación hace lo que lleva tres años haciendo: generar la miniatura. Y en ese gesto —el más banal que existe en una web— un atacante sin usuario ni contraseña se lleva el contenido de ficheros del servidor, empezando por las variables de entorno del proceso: la clave que firma las sesiones, la de la base de datos, las del almacenamiento en la nube. Eso es CVE-2026-66066, un 9,5 publicado el 29 de julio. Lo que nos parece interesante no es la nota. Es dónde está el fallo: ni en el código que encargaste, ni exactamente en Rails, sino en qué formatos considera seguro leer una biblioteca de C que nadie de tu empresa eligió, ni sabe que corre, ni sabría nombrar. Una biblioteca que, además, desde 2022 publica cuáles de sus operaciones no ha verificado contra entradas hostiles, y trae de serie un interruptor para bloquearlas.
Los hechos, sin adornos
Tal como los publica el aviso oficial de Rails. Antes de opinar, los datos:
- CVE-2026-66066, publicada el 29 de julio de 2026. CVSS 4.0 de 9,5, crítica. Categoría: lectura de ficheros arbitrarios y posible ejecución remota de código en el procesamiento de variantes de Active Storage.
- Versiones afectadas:
activestorageanterior a 7.2.3.2, la rama 8.0 anterior a 8.0.5.1 y la rama 8.1 anterior a 8.1.3.1. Corregido en esas tres. Rails 6.x solo entra si Active Storage está configurado fuera de sus valores por defecto —y ahí llega el detalle que deja tirado a quien esté en esa rama: Rails no ha publicado versiones corregidas para nada anterior a la 7.2, así que en 6.x no hay parche, solo mitigación o migración. - Hacen falta tres condiciones a la vez, según los investigadores: que la aplicación procese variantes de imagen con libvips, que acepte subidas de imágenes de usuarios no confiables —por funcionalidad propia o por subida directa— y que el libvips instalado esté enlazado contra ciertas bibliotecas de terceros. Con el procesador ImageMagick (MiniMagick) esta no aplica.
- Cuidado con la segunda condición. Rapid7 avisa de que la cadena documentada necesita que la ruta de subida directa de Active Storage sea alcanzable, y esa ruta está presente por defecto en cuanto Active Storage está montado, aunque la interfaz de tu aplicación no use subidas directas. Dicho de otro modo: «nosotros no dejamos subir imágenes» puede ser cierto en la pantalla y falso en el enrutador.
- Qué consigue el atacante: la divulgación del contenido de ficheros arbitrarios accesibles en el sistema de ficheros con el usuario del proceso, incluidas sus variables de entorno —donde suelen vivir
secret_key_base, la clave maestra, las credenciales de base de datos, las del almacenamiento y tokens de terceros—. De ahí, la escalada a ejecución de código y a movimiento lateral hacia otros sistemas. - Lo reportaron los investigadores 0xacb, s3np41k1r1t0 y castilho, de Ethiack, y RyotaK, de GMO Flatt Security. La divulgación completa estaba prevista para el 28 de agosto como muy tarde; aparecieron pruebas de concepto públicas antes de tiempo y Rails acabó publicando los detalles y una herramienta forense a finales de julio, en un repositorio propio.
Un detalle que cambia el tamaño del problema: desde Rails 7.0 el procesador de variantes por defecto es Vips —en 6.x era ImageMagick—, y libvips es además el procesador por defecto en las imágenes Docker oficiales de Rails y en los montajes de Debian y Ubuntu. La configuración vulnerable no es una rareza que alguien activó a propósito: es lo que viene de serie. Con un matiz que conviene comprobar antes de dar nada por hecho: ese valor por defecto va atado a config.load_defaults y no al número de versión de la gema, así que una aplicación migrada a 7.2 que todavía declare load_defaults 6.1 sigue usando ImageMagick.
La etiqueta ya estaba puesta
Aquí está la parte que merece leerse dos veces, y es la razón por la que le dedicamos un artículo entero a un CVE de un framework que quizá ni uses. Lo cuenta el propio aviso: libvips lee y escribe formatos a través de loaders y savers, muchos de ellos respaldados por bibliotecas de terceros, y marca algunas de esas operaciones como «unfuzzed» —sin fuzzing, es decir, no sometidas a pruebas con entradas hostiles y por tanto no seguras para contenido no confiable—. Lo que falló es que Active Storage no las desactivaba.
Y ese mecanismo no es de este verano: llega con libvips 8.13, publicada el 28 de mayo de 2022, cuyo anuncio explicaba que con la variable VIPS_BLOCK_UNTRUSTED se impide ejecutar cualquier operación etiquetada como no confiable, para poder desplegar «con la confianza de que no se está exponiendo código sin fuzzear a datos de internet». Cuatro años. La información de seguridad existía: publicada, en el sitio correcto, con el nombre correcto, marcada operación por operación por quien mejor conocía el código, y con el interruptor puesto. Lo que no existía era la decisión de accionarlo en el eslabón siguiente. Esto no es un desbordamiento de memoria exótico que nadie podía prever; es una etiqueta de advertencia que la capa de arriba no consumió. Y la distinción importa, porque las etiquetas se pueden leer y los desbordamientos no se pueden adivinar.
Por si queda duda de que esta lectura no es nuestra manía: la categoría que le han asignado al fallo es CWE-1188, «inicialización de un recurso con un valor por defecto inseguro». No «lectura de fichero fuera de rango», no «validación insuficiente de la entrada». El nombre oficial del problema apunta al valor por defecto.
Ahora cuenta los eslabones de la cadena de decisiones que acaba en tu servidor. Tu empresa encargó una aplicación. Quien la hizo eligió Rails. Rails eligió Active Storage. Active Storage eligió libvips como procesador por defecto. Y libvips llama a bibliotecas de terceros distintas para cada formato de imagen. Cinco decisiones, y tu empresa solo tomó la primera. La superficie de ataque de tu aplicación la decidieron cuatro proyectos que no conoces, con buen criterio y de buena fe, resolviendo problemas que no eran el tuyo.
Nada de esto es un reproche: ni libvips ni Rails lo hicieron mal aquí. libvips etiquetó lo que no había verificado, que es exactamente lo que uno espera de una biblioteca seria. Rails parcheó tres ramas a la vez, dio una mitigación provisional que no requiere tocar código y, cuando le forzaron el calendario con exploits públicos, publicó los detalles y una herramienta forense en lugar de callar. Eso es hacerlo bien. El problema no está en ningún eslabón: está en que nadie es responsable de la unión entre dos.
¿Te afecta? Se sabe en diez minutos
Antes del susto, la comprobación. Puede perfectamente que esta no vaya contigo, y decirlo es parte del trabajo: un aviso crítico que no aplica a tu caso, tratado como si aplicara, te gasta la semana y el crédito. Cuatro comprobaciones, ejecutadas dentro de la máquina o el contenedor que sirve producción ahora mismo —con docker exec o kubectl exec si hace falta—, no en el portátil de quien programó ni en la rama principal del repositorio:
# 1) Versión REAL de activestorage en el entorno que sirve producción
bundle list | grep -i activestorage
grep "^ activestorage " Gemfile.lock
# 2) Procesador de variantes configurado: vips (afectado) o mini_magick (no)
grep -rn "variant_processor" config/
# 3) De qué versión de defaults tira la app (decide el valor por defecto de arriba)
grep -rn "load_defaults" config/application.rb
# 4) Versión de libvips REAL. Si el binario no existe, pregunta a la biblioteca
vips --version 2>/dev/null || bundle exec ruby -e 'require "vips"; puts Vips::LIBRARY_VERSION'
Dos trampas en esas cuatro líneas, y las dos empujan hacia el falso «no me afecta». La primera: si la comprobación 2 no devuelve nada, no estás a salvo, estás en el valor por defecto —y con load_defaults en 7.0 o posterior ese valor por defecto es Vips—. La segunda: que vips no exista como comando no significa que no tengas libvips. El binario va en un paquete aparte (libvips-tools en Debian y Ubuntu) y ruby-vips habla directamente con la biblioteca, así que la imagen típica de una aplicación Rails tiene libvips y no tiene vips. De ahí la segunda mitad de la línea 4.
La última pregunta la contesta un humano, no un comando: ¿puede alguien de fuera subir una imagen? Un formulario de contacto con adjunto, el avatar de un área privada, el portal donde los clientes suben albaranes. Y recuerda lo de la ruta de subida directa: la respuesta correcta no es la de la pantalla, es la del enrutador. Un aviso honesto para cerrar: estas comprobaciones te dicen qué tienes, no si ya han entrado. Para lo segundo está la herramienta forense que publicó Rails, y hacen falta registros que muchas aplicaciones no guardan.
Lo que puedes desplegar hoy no es el parche
Todos los titulares dicen «actualiza ya», y tienen razón en el fondo. En el orden, no del todo. Porque en una aplicación de negocio hecha a medida, actualizar el framework y cambiar una variable de entorno no cuestan lo mismo ni tardan lo mismo, y quien decide tiene que saberlo:
- Hoy: la mitigación provisional. El aviso propone bloquear las operaciones no verificadas de dos maneras, y la diferencia entre ellas no es cosmética. La variable de entorno
VIPS_BLOCK_UNTRUSTEDes un cambio en el entorno de ejecución: se despliega sin tocar el código de la aplicación, que es justo lo que hace falta cuando el código lo mantiene otro. La llamadaVips.block_untrusted(true)hace lo mismo pero va en un initializer, o sea que sí es tocar código y sí pasa por el ciclo de release. Ambas requieren libvips 8.13 o superior; la segunda, además, ruby-vips 2.2.1 o superior. - Esta semana: el parche de verdad. Subir
activestoragea 7.2.3.2, 8.0.5.1 o 8.1.3.1, y comprobar que libvips en la imagen del contenedor es 8.13 o superior. Rapid7 lo dice sin rodeos y merece subrayarse porque es el error que más veremos: actualizar Rails o Active Storage por sí solo no basta si la versión de libvips instalada es antigua. Si tienes pruebas automáticas y despliegue reproducible, es una tarde. Si la aplicación se despliega a mano desde 2022 y no hay suite de pruebas, no es una tarde: es un proyecto pequeño, y conviene llamarlo por su nombre en vez de prometer el viernes. - Con calendario: rotar. Va en su propio apartado más abajo, porque es la parte que casi nadie hace y no por pereza.
Una advertencia sobre el punto uno que apenas hemos visto en las coberturas: bloquear las operaciones no verificadas puede hacer que deje de procesarse algún formato raro que hoy sí procesas. Eso no es un efecto secundario molesto, es una decisión que hay que tomar con los ojos abiertos —y nuestra respuesta es fácil: preferimos que falle una miniatura a que alguien lea el entorno del proceso—. Pero pruébalo antes en preproducción y mira los registros el primer día.
Rotar es la parte cara. Por eso no se hace
El aviso es explícito: hay que cambiar todos los secretos que el proceso podía leer. secret_key_base, las claves maestras, las credenciales de servicios y de base de datos, los tokens de terceros. Es lo correcto y es lo que menos se cumple, por una razón muy práctica que casi nunca se menciona: secret_key_base es lo que firma y cifra las cookies de sesión de una aplicación Rails. Cambiarlo no es editar una línea: es decidir qué pasa con todas las sesiones abiertas de todos los usuarios en ese momento.
Y el resto de credenciales suele vivir en más sitios de los que dice el inventario: en el sistema que despliega, en el gestor de contraseñas del proveedor que hizo la aplicación, en un fichero de configuración del portátil de alguien que ya no está. De la máquina que despliega ya escribimos hace nada, cuando a TeamCity le cayó su propio 9,8: si tienes un servidor de CI/CD, buena parte de lo que hay que rotar hoy está también ahí dentro, y rotar en un sitio y no en el otro es no haber rotado.
No tenemos un dato de cuántas aplicaciones Rails corren en pymes españolas ni de qué porcentaje va a rotar algo este mes. No lo hemos medido y no nos lo vamos a inventar. Lo que sí vemos, cuando nos sentamos a mirarlo con alguien, es que la pregunta «¿en cuánto tiempo podrías cambiar todas las credenciales de esta aplicación?» casi nunca tiene una respuesta en horas o días; tiene una pausa larga y una mueca. Y ahí está la medida honesta de tu exposición: no es «¿estamos parcheados?», es cuánto tardarías en rotar. Ese número te dice lo que te costaría una fuga, la de este CVE o la del siguiente.
Dónde acaba tu contrato de mantenimiento
Aquí el tema deja de ser de Rails. Un contrato de mantenimiento informático normal cubre servidores, copias, antivirus, la red y el puesto de trabajo. Y se detiene, con toda naturalidad, justo donde empieza la aplicación de negocio: porque «la aplicación es del proveedor que la hizo». El proveedor que la hizo, por su parte, entregó, facturó y cerró el proyecto hace tres años. Resultado: el único software de la casa que atiende peticiones de Internet, procesa ficheros de desconocidos y tiene las credenciales de la base de datos es lo único que no está en ningún calendario de parcheo.
No es mala fe de nadie. Es un hueco de contrato, y se cierra escribiéndolo. Cuando hacemos este inventario con un cliente, en la columna de «aplicaciones» ponemos cinco cosas, y ninguna es glamurosa:
- Qué aplicaciones hay, sobre qué corren y quién escribió cada una.
- Qué versión exacta corre hoy, en producción. No la del repositorio: la de la imagen que está sirviendo peticiones. Ya explicamos por qué esa distinción no es una manía nuestra cuando contamos que «latest» no es una versión.
- Qué entra desde fuera: formularios, subidas de ficheros, integraciones, webhooks.
- Qué credenciales puede leer el proceso y desde dónde se rotan.
- Quién se entera de un aviso como este, por qué canal y en cuántos días.
Eso es, en la práctica, lo que hacemos en datos y aplicaciones: tratar la aplicación de negocio como un sistema en producción y no como un entregable cerrado, con la misma disciplina aburrida que se le pide a un servidor. Y decirlo con honestidad: nosotros no desarrollamos en Rails, así que no venimos a venderte una migración. La parte de decidir qué se parchea primero, con qué exposición real y con qué credenciales dentro, es ciberseguridad del montón, de la que no sale en los folletos.
Un 9,5 no es tu riesgo. Pero aquí hay exploit público
Lo dijimos con los 622 parches de un solo martes de julio y lo repetimos aquí porque no ha cambiado: el CVSS es una etiqueta de gravedad técnica en el peor caso, no una medida de tu riesgo. Mide qué pasa si se dan las condiciones, no si tú las das. Por eso la comprobación de diez minutos va antes que el susto.
Y aquí toca ser preciso, porque los titulares mezclan dos cosas que no son la misma. Explotación real, que se sepa, no hay: Rapid7 decía el 30 de julio no tener constancia de ninguna, y esto no está en el catálogo KEV de CISA. Lo que sí ha caducado es el «sin exploit público»: circula código que dice explotarlo, aunque —matiz del propio Rapid7— no está claro cuánto se parece a la cadena completa que los investigadores entregaron en privado a Rails. Y el mismo Rapid7 ha verificado la escalada a ejecución remota y ha propuesto un módulo de Metasploit para ella.
Esa distinción no es un tecnicismo: es la diferencia entre tener días y tener semanas. Los investigadores se habían guardado la cadena técnica hasta finales de agosto precisamente para dar margen, y el margen se evaporó solo. Cuando la condición de entrada es «acepta subidas de imágenes», el módulo de Metasploit convierte una cadena difícil en un botón, y ese es el momento en el que el número de gente capaz de intentarlo se multiplica. No hace falta pintar una explotación masiva que hoy no existe para justificar mirarlo esta semana.
Tres años funcionando sin dar problemas
La frase que más veces hemos oído sobre una aplicación de negocio es esa: «lleva tres años funcionando sin dar problemas». Y es verdad, y es exactamente el motivo por el que nadie la mira. Un servidor que no da problemas igualmente sale en el listado de parches del mes; una aplicación que no da problemas desaparece del radar por completo, porque su única señal de vida era dar problemas.
Nuestra propuesta es más modesta que un plan de seguridad y cabe en una reunión de media hora. Coge la aplicación de la que más depende tu negocio y contesta tres cosas por escrito: qué versión del framework corre hoy en producción, quién decide cuándo se actualiza y cuánto tardaríais en cambiarle todas las contraseñas. Si sale, enhorabuena, no necesitas este artículo. Si no sale —y lo normal es que no salga—, ya tienes las tres primeras líneas del inventario, y las tienes sin que te haya pasado nada. Que es, con diferencia, el momento más barato de escribirlas. Y si prefieres que las tres respuestas las busquemos con vosotros, aquí estamos.
Fuentes (verificadas el 3 de agosto de 2026): los datos de la vulnerabilidad salen del aviso de seguridad oficial de Rails GHSA-xr9x-r78c-5hrm, publicado el 29 de julio de 2026 (CVE-2026-66066; CVSS 4.0 de 9,5; versiones afectadas y corregidas 7.2.3.2, 8.0.5.1 y 8.1.3.1; la explicación de los loaders y savers de libvips respaldados por bibliotecas de terceros y de las operaciones marcadas como «unfuzzed», no seguras para contenido no confiable, que Active Storage no desactivaba; el impacto de lectura de ficheros arbitrarios incluidas las variables de entorno con secret_key_base y credenciales; las mitigaciones VIPS_BLOCK_UNTRUSTED y Vips.block_untrusted(true) con libvips 8.13 o superior y ruby-vips 2.2.1 o superior; la petición de cambiar todos los secretos; y el crédito a 0xacb, s3np41k1r1t0 y castilho, de Ethiack, y a RyotaK, de GMO Flatt Security). El calendario de divulgación —detalles previstos para el 28 de agosto como muy tarde, pruebas de concepto públicas antes de tiempo y publicación anticipada de los detalles y de la herramienta forense— y el matiz de que Rails 6.x solo entra si Active Storage está configurado fuera de sus valores por defecto, de la cobertura de BleepingComputer del 1 de agosto de 2026. Que solo afecta al procesador Vips y no a las aplicaciones que usan Magick, y las tres condiciones (libvips, subidas de usuarios no confiables por funcionalidad o subida directa, y un libvips enlazado contra ciertas bibliotecas de terceros), las precisa la nota de los investigadores de Ethiack, que retuvieron a propósito la cadena técnica y el PoC. Del análisis de Rapid7 tomamos la clasificación CWE-1188 («inicialización de un recurso con un valor por defecto inseguro»), que a 30 de julio de 2026 no tenía constancia de explotación en la práctica, que existe código público que dice explotarlo pero no está claro cuánto se parece a la cadena completa entregada en privado a Rails, que la ruta de subida directa de Active Storage debe ser alcanzable y está presente por defecto aunque la interfaz de la aplicación no use subidas directas, que Rails no ha publicado versiones corregidas para las ramas anteriores a la 7.2, que actualizar Rails o Active Storage por sí solo no basta con un libvips antiguo, y la verificación de la escalada a ejecución remota con el módulo propuesto para Metasploit. Que config.active_storage.variant_processor pasó a :vips por defecto en Rails 7.0 (era :mini_magick en 6.x), atado a config.load_defaults, está en la guía de configuración de Rails; que libvips es el procesador por defecto en las imágenes Docker oficiales de Rails y en Debian y Ubuntu, en BleepingComputer. El mecanismo de bloqueo y su fecha —VIPS_BLOCK_UNTRUSTED introducido en libvips 8.13, publicada el 28 de mayo de 2022—, incluida la cita sobre desplegar «con la confianza de que no se está exponiendo código sin fuzzear a datos de internet», salen del anuncio de la propia libvips. Son criterio y opinión nuestros, no de las fuentes: que lo relevante de este caso es que la advertencia («unfuzzed») ya estaba publicada y lo que faltaba era consumirla en el eslabón siguiente; la cuenta de las cinco decisiones de la cadena de dependencias; el orden mitigar hoy / parchear esta semana / rotar con calendario, y el aviso de que bloquear operaciones no verificadas puede romper el procesamiento de algún formato; que la medida honesta de la exposición es cuánto tardarías en rotar y no si estás parcheado; y la lectura del hueco entre el contrato de mantenimiento y el proveedor que desarrolló la aplicación, con la lista de cinco puntos del inventario. No hemos contado cuántas aplicaciones Rails hay en producción en pymes españolas, ni cuántas rotarán credenciales, ni tenemos incidentes propios de este CVE: no lo hemos medido y no lo inventamos. everyWAN no desarrolla en Ruby on Rails. Foto de portada: «Man Working in Photographic Laboratory», State Government Photographer, Wikimedia Commons, CC0 1.0.
¿Quién parchea tus aplicaciones de negocio?
Levantamos el inventario de tus aplicaciones de negocio: versión real en producción, qué entra desde fuera, qué credenciales alcanza cada proceso y en cuánto tiempo se pueden rotar. Somos agnósticos de fabricante y no desarrollamos en Rails: no hay migración que vendarte al final del informe.
Hablar con everyWAN