Un XSS en los logs de build de SourceHut permitía tomar el control de cuentas
Un log de build manipulado podía ejecutar código en el navegador de un usuario de SourceHut. ansi2html 1.9.4 corrige el fallo, CVE-2026-92973, que afectaba a las versiones 1.7.0 a 1.9.3.
3 min de lectura

Un investigador de seguridad ha revelado un fallo que permitía a un log de build manipulado tomar el control de cuentas de SourceHut. El error estaba en ansi2html, una biblioteca de Python que convierte la salida de color de un terminal en HTML, y se rastrea como CVE-2026-92973. Cualquier proyecto que muestre logs no fiables con ansi2html en las versiones 1.7.0 a 1.9.3 tiene la misma exposición.
SourceHut es una forja de software alojada, un servicio para repositorios Git, listas de correo e integración continua. Su servicio de CI, builds.sr.ht, ejecuta trabajos y muestra sus logs en el navegador. El investigador, que publica como Arusekk, describió el ataque el 23 de septiembre de 2026.
Cómo un log de build se convirtió en un ataque
El ataque usó cross-site scripting, o XSS. Consiste en lograr que un sitio web ejecute el JavaScript de un atacante en el navegador de un visitante, con la sesión iniciada de ese visitante.
Los terminales entienden secuencias de escape, códigos ocultos mezclados en la salida de texto. La mayoría definen colores. Un tipo, OSC 8, convierte un fragmento de texto en un hipervínculo en el que se puede hacer clic. ansi2html traduce estos códigos a HTML para que un log se vea igual en una página web.
Según el artículo, ansi2html no escapaba correctamente el destino del enlace en las secuencias OSC 8. Un trabajo podía imprimir una secuencia cuyo "enlace" escapaba del atributo HTML y añadía otros nuevos, entre ellos un manejador de eventos que ejecuta código. Cualquiera que abriera la página de log de ese trabajo lo ejecutaba.
Qué podía hacer un atacante
El script inyectado podía leer el token CSRF de la página, escribe el investigador. Un token CSRF es el secreto que usa un sitio para confirmar que una petición viene de verdad de la propia sesión del usuario. Con él, el script podía enviar trabajos de build en nombre de la víctima y llegar a sus claves de despliegue, las credenciales que usan los trabajos para subir código o publicar versiones.
| Software afectado | Versiones vulnerables |
|---|---|
| ansi2html | Desde 1.7.0 hasta 1.9.4, sin incluirla |
| builds.sr.ht | Desde 0.40.0 hasta 0.105.1, sin incluirla |
El artículo no informa de ninguna explotación documentada en el mundo real.
La cronología de la divulgación
SourceHut actuó rápido. La corrección de la biblioteca original tardó un mes más, y la divulgación pública esperó hasta que ambas estuvieron disponibles.
| Fecha (2026) | Evento |
|---|---|
| 1 de agosto | Error reportado |
| 4 de agosto | Mitigación desplegada en builds.sr.ht |
| 2 de septiembre | Publicado ansi2html 1.9.4 con la corrección |
| 17 de septiembre | Asignado CVE-2026-92973 |
| 23 de septiembre | Publicado el artículo público |
Las notas de la versión 1.9.4 de ansi2html en GitHub recogen la corrección como "osc8: ensure proper escaping", pull request 263. Arusekk escribió el parche y el mantenedor hartwork lo aprobó.
Por qué auditar la dependencia no bastaba
El investigador plantea algo que va más allá de este error. El fallo está en código que cambia de una versión a otra, así que una revisión puntual no puede detectarlo. "Note how even carefully auditing ansi2html would not save SourceHut, unless redone on every bump", dice el artículo.
Una dependencia que era segura cuando la revisaste puede incorporar una función nueva más adelante. Una actualización de versión corriente trae entonces esa función, y cualquier error que contenga, directamente a tu producto.
SourceHut ha sido noticia este año por sus normas de contribución, incluida su prohibición del código y los tickets asistidos por LLM. Esta divulgación recuerda que el propio código del servicio tiene una cadena de suministro como el de cualquiera.
Qué significa esto para los desarrolladores
Actualiza ansi2html a la versión 1.9.4 o posterior dondequiera que lo uses. Revisa tus lockfiles e imágenes de contenedor, no solo tus dependencias directas, porque la biblioteca suele llegar como dependencia de una herramienta de pruebas o de CI. Ejecutar pip show ansi2html dentro de cada entorno te indica la versión que realmente distribuyes.
Trata la salida de build como entrada hostil. Un log de CI contiene lo que el código de una pull request haya decidido imprimir. Si tu propio panel muestra los logs como HTML, comprueba que cada valor de atributo esté escapado. Añade una Content Security Policy que bloquee los manejadores de eventos en línea, para que un escape olvidado no se convierta en ejecución de código.
Revisa a qué podría llegar una sesión robada. Aquí, una sola visita a una página daba el poder de iniciar trabajos y leer claves de despliegue. Limita las claves de despliegue a repositorios individuales y rota las que no puedas justificar.
Por último, vuelve a leer los changelogs cuando una biblioteca de renderizado o de análisis añada una función. El soporte para nuevas secuencias de escape, nuevo marcado o un nuevo manejo de enlaces son justo los cambios que merecen una segunda mirada.
Fuentes
- SourceHut account takeover via build logs - arusekk.pl
- ansi2html v1.9.4 - GitHub
Artículos relacionados

Node.js 22.23.3 LTS corrige un error use-after-free en HTTP/2
Node.js 22.23.3 LTS, publicado el 23 de septiembre, corrige un error use-after-free en HTTP/2, añade soporte de SharedArrayBuffer a Node-API y pasa a OpenSSL 3.5.8.

Radicle hasta 1.10.3 envía repos privados en texto plano
Todas las versiones de Radicle hasta 1.10.3 envían los datos de los repositorios sin cifrar y dejan que un atacante imite a un par de confianza. Aún no hay arreglo.

Gzip 1.15 corrige una carrera que borraba el archivo equivocado
Gzip 1.15 reúne 119 commits de 75 semanas de trabajo. Corrige una carrera que podía borrar el archivo equivocado y un desbordamiento de búfer al descomprimir .lzh.