· 11 min de lectura

Un teléfono sobre un escritorio a oscuras con una foto brillando encima; de ella sale un hilo de luz roja que cruza un rack de servidores hasta una cámara acorazada entreabierta

En julio, tres investigadores de Hacktron subieron una foto al foro de la comunidad de OpenAI. Menos de 72 horas después tenían abierto un pull request en el repositorio interno de la empresa, escrito por el Codex de un empleado. Entre una cosa y otra no hubo contraseñas robadas ni phishing: hubo una librería de imágenes sin parchear y un inicio de sesión que confiaba demasiado.

La noticia se ha contado casi siempre por el lado llamativo, que el exploit lo escribió una IA. Aquí me interesa el otro: las tres piezas que hicieron posible el ataque las tiene también tu servidor, o tu empresa. Así que además de contar qué pasó, lo he comprobado en el mío.

Qué pasó, paso a paso

Lo reconstruyo desde el informe de los propios investigadores, «Hacking OpenAI», y los avisos oficiales de Discourse y Debian.

  1. La foto. El foro de OpenAI (community.openai.com) funciona con Discourse. Discourse valida las imágenes con una librería que no entiende HEIC, el formato por defecto de las fotos del iPhone, así que se las pasa a ImageMagick para convertirlas. ImageMagick, a su vez, usa libheif para leerlas.
  2. El fallo. La libheif de la imagen de Discourse (1.19.7) tenía un desbordamiento de heap al componer imágenes superpuestas. El proyecto lo había corregido el año anterior, pero como un cambio de mantenimiento: sin aviso de seguridad y sin CVE.
  3. Código en el foro. Con ese fallo escribieron un exploit que salta ASLR y el gestor de memoria jemalloc, y consiguieron ejecución de código en el servidor del foro.
  4. El salto a OpenAI. El foro tiene «Iniciar sesión con OpenAI». Desde el foro comprometido pudieron tomar las cuentas de ChatGPT y Codex de empleados que entraban en él.
  5. La prueba. En vez de llevarse código, le pidieron al Codex de un empleado conectado a GitHub que abriera un pull request en el monorepo interno. Acceso de escritura demostrado, y ahí pararon.
Diagrama de cinco pasos: una foto HEIC subida al foro de OpenAI, un desbordamiento en libheif, ejecución de código en el foro, el inicio de sesión compartido con OpenAI, y un pull request abierto con el Codex de un empleado.
Solo el segundo paso es un fallo de memoria. El resto es una cadena de sistemas que confían en el anterior.

Las fechas, según el informe: el exploit funcionó el 25 de julio de madrugada, lo reportaron por Bugcrowd esa misma mañana, y OpenAI confirmó el arreglo unas catorce horas después. Discourse publicó su aviso el 28 de julio (GHSA-vhm9-85gw-x335, CVE-2026-32882, gravedad 8.8), con versiones corregidas y el procesado de imágenes metido en un sandbox. OpenAI pagó 6.500 dólares, con una aclaración: atacar el foro estaba fuera del alcance de su programa, y la recompensa es por el fallo del lado de OpenAI.

Lo que se sabe y lo que no

Antes de sacar lecciones, conviene separar lo confirmado de lo que se repite sin fuente, porque en esta historia hay bastante de lo segundo:

Ese último punto es importante y casi nadie lo cuenta, porque es la parte buena para quien defiende: más abajo vuelvo a él.

Lección 1: sin aviso de seguridad no hay parche

Este es el centro de todo. El arreglo existía desde el año anterior. Pero una distribución Linux no aplica cualquier commit de cualquier proyecto a sus versiones estables: aplica los que están marcados como seguridad. Un arreglo que se publica como «mantenimiento» no se trae a la versión que corres, y tu apt upgrade diario no te protege de un fallo que nadie ha declarado.

Y hay una segunda capa, más sutil: la versión que corres depende de quién compiló la librería. Discourse no usaba la libheif de Debian, llevaba la suya propia dentro de su imagen. Así que aunque Debian la hubiera parcheado, a Discourse no le habría llegado.

Diagrama: el arreglo de libheif llegó a Ubuntu 24.04 y Debian 13 pero Debian 12 sigue marcado vulnerable, y una copia compilada dentro de una imagen, como la de Discourse, no recibe ningún parche de la distribución.
El mismo fallo, cinco destinos. En el paquete de tu distribución depende de ella; dentro de una imagen, de quien la construyó.

Los datos del diagrama los he sacado de las fuentes, no de memoria. El tracker de seguridad de Debian marca CVE-2026-32882 como corregido en Debian 13 (con el aviso DSA-6417-1, del 8 de agosto), pero Debian 12 sigue apareciendo como vulnerable cuando escribo esto. Ubuntu 24.04, en cambio, incluyó el parche el 16 de junio, antes de que empezara la investigación. Mismo fallo, tres calendarios distintos.

Lo comprobé en mi servidor

El servidor de este blog es un Ubuntu 24.04 con WordPress. La pregunta es sencilla: ¿cuántas piezas de esa cadena tengo yo? Primero, si libheif está instalado:

dpkg -l | grep -i heif

Salida en el servidor de itrafa:

ii  libheif-plugin-aomdec:amd64    1.17.6-1ubuntu4.8
ii  libheif-plugin-aomenc:amd64    1.17.6-1ubuntu4.8
ii  libheif-plugin-libde265:amd64  1.17.6-1ubuntu4.8
ii  libheif1:amd64                 1.17.6-1ubuntu4.8

Sí lo está, y no lo instalé yo. ¿Quién lo trajo?

apt-cache rdepends --installed libheif1

Salida en el servidor de itrafa:

libheif1
Reverse Depends:
  libgd3
  libheif-plugin-libde265
  libheif-plugin-aomenc
  libheif-plugin-aomdec
  libgd3
  libheif-plugin-libde265
  libheif-plugin-aomenc
  libheif-plugin-aomdec

libgd3, la librería de imágenes que usa la extensión GD de PHP. Es decir: WordPress tiene a libheif a un paso aunque nunca hayas oído hablar de ella. Esto es lo que quería enseñar, y lo que vale para cualquier servidor: tu superficie de ataque incluye las dependencias de tus dependencias. Luego, si el parche de este caso está en mi versión:

apt-get changelog libheif1 | grep -B3 CVE-2026-32882

Salida en el servidor de itrafa:

  * SECURITY UPDATE: Heap overflow in HeifPixelImage.
    - debian/patches/CVE-2026-32882.patch: Fix overlay image with alpha
      channels with stride different from color channel in
      libheif/pixelimage.cc
    - CVE-2026-32882

Está. Y la otra mitad de la cadena, la que llevaba el HEIC hasta el decodificador, aquí no existe: no hay ImageMagick instalado, ni la extensión Imagick de PHP, y WordPress no tiene ningún editor capaz de abrir HEIC. Lo compruebas así:

php -m | grep -i imagick
wp eval 'echo _wp_image_editor_choose( array( "mime_type" => "image/heic" ) ) ?: "ninguno";'

En mi caso, la primera línea no devuelve nada y la segunda dice ninguno. Si en el tuyo aparece WP_Image_Editor_Imagick, tu WordPress convierte los HEIC que suben tus autores con ImageMagick, y la historia de este artículo te afecta más de lo que parece.

Por último, lo que nadie mira: los contenedores. Cada imagen lleva sus propias librerías, y un apt upgrade en el host no las toca. Este bucle busca libheif dentro de todo lo que tienes corriendo:

for c in $(docker ps --format '{{.Names}}'); do
  echo "--- $c"
  docker exec "$c" sh -c 'find / -name "libheif.so*" 2>/dev/null'
done

En mi servidor solo corre Gotenberg, el conversor de documentos a PDF, y no trae libheif. Pero ese es exactamente el tipo de contenedor donde podría estar: si procesas imágenes dentro de Docker, este es el comando que te dice si estás en la situación de Discourse.

Lección 2: los lectores de imágenes son superficie de ataque

Una web que acepta subidas le entrega archivos de desconocidos a código escrito en C para leer formatos complicados. Eso es lo que hay que reducir:

Si tienes ImageMagick, esta es la línea que prohíbe leer esos formatos, dentro de <policymap> en su policy.xml:

<policy domain="coder" rights="none" pattern="{HEIC,HEIF,AVIF}" />

No me fío de una línea de configuración que no he visto funcionar, así que la probé en un contenedor Debian 13 desechable con ImageMagick 7 (su política está en /etc/ImageMagick-7/policy.xml). Sin la regla, convierte un HEIC de prueba sin problema. Con ella:

Salida en un contenedor Debian 13 de prueba:

convert: attempt to perform an operation not allowed by the security policy `HEIC' @ error/constitute.c/IsCoderAuthorized/454.

Y en el mismo contenedor, un PNG se sigue convirtiendo a JPG sin problema: la regla corta solo lo que le pides. Para ver la política activa usa magick -list policy en ImageMagick 7 o convert -list policy en el 6, y prueba que tu aplicación sigue aceptando las imágenes que sí necesitas antes de darlo por bueno.

Lección 3: el eslabón débil es el que tú invitaste

Sin el inicio de sesión compartido, este ataque habría sido un foro comprometido: grave, pero contenido. El salto a los sistemas de OpenAI existió porque un servicio de terceros, el foro, estaba conectado a la misma identidad que da acceso a lo importante.

Como el mecanismo exacto no se ha publicado, esto es mi lectura, no un hecho confirmado: cada aplicación a la que dejas usar «Iniciar sesión con tu cuenta de empresa» es un sistema en el que confías con tu identidad. Si esa aplicación cae, la pregunta es qué puede hacer quien la controla con lo que ella recibe. En Microsoft 365 esto es muy concreto: revisa qué aplicaciones empresariales tienen consentimiento en tu inquilino y qué permisos tienen, y no mezcles herramientas periféricas, como un foro o un tablero, con la identidad de las cuentas que tocan código o datos sensibles.

Hay un hilo directo con lo que conté sobre el phishing de código de dispositivo: cuando lo que se roba es una sesión o un token ya emitido, el MFA ya pasó. La autenticación fuerte protege la puerta, no lo que sale por ella después.

Lección 4: la seguridad por complejidad se acaba

Los investigadores lo resumen en una frase de su informe: el software se ha beneficiado durante mucho tiempo de una especie de «seguridad por complejidad», y la IA está convirtiendo en cómputo la experiencia escasa que hacía falta para romperla. Según su relato, con un modelo tenían un exploit que solo funcionaba con ASLR desactivado; con la versión siguiente, publicada esa misma noche, tuvieron uno funcional para un Mac local en unas tres horas, y de ahí lo portaron al entorno real del foro.

No hace falta creerse todo el discurso para quedarse con la consecuencia práctica: el tiempo entre un fallo conocido y un exploit usable se está acortando. Un parche que antes podías aplicar «la semana que viene» hoy vale menos. Es la misma conclusión, vista desde el otro lado, que la de mi artículo sobre el coste real en seguridad del código generado por IA.

Qué hacer esta semana

  1. Busca libheif en tus servidores con dpkg -l | grep -i heif y mira quién lo arrastra con apt-cache rdepends --installed libheif1.
  2. Comprueba si tu versión trae el parche con el changelog de tu distribución, no con el número de versión: un 1.17 de Ubuntu puede estar parcheado y un 1.19 compilado a mano no.
  3. Revisa tus contenedores con el bucle de arriba. Lo que llevan dentro no se actualiza solo: hay que reconstruir la imagen.
  4. Si procesas imágenes subidas por usuarios, prohíbe los formatos que no necesitas y aísla el procesado.
  5. Revisa las aplicaciones de terceros con inicio de sesión de tu empresa y qué permisos tienen.

Fuentes

Seguir leyendo en IT Rafa

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *