Reports
ALTA[XSS]#1398305

Dos formas de colar XSS en los comentarios de GitLab saltándose el saneamiento

Encadenando un fallo en el servidor (data-sourcepos) y otro en el cliente (el elemento gl-emoji) se conseguía ejecutar JavaScript a cualquiera que abriera un comentario.

Resumen
Resumen en castellano de un reporte público, no una traducción literal. El código y los comandos se mantienen como en el original.

Resumen

Los saneadores de HTML son una carrera armamentística, y este reporte lo ilustra bien: no encontró un agujero, sino dos, uno a cada lado. En el servidor, el SyntaxHighlightFilter de GitLab construía HTML metiendo dentro un atributo sin sanear; en el cliente, el elemento personalizado gl-emoji permitía burlar la directiva de saneamiento del framework. Combinándolos se conseguía un XSS almacenado en los comentarios de las incidencias (y en otras páginas con notas).

Pasos de reproducción

El primero de los dos fallos está en cómo se genera el bloque de código resaltado. Fíjate en que data-sourcepos se concatena en el HTML tal cual:

sourcepos = node.parent.attr('data-sourcepos')
sourcepos_attr = sourcepos ? "data-sourcepos=\"#{sourcepos}\"" : ""
highlighted = %(<pre #{sourcepos_attr} class="#{css_classes}" ... ><code>#{code}</code></pre>)

Como ese atributo no se escapa, un data-sourcepos manipulado cierra la etiqueta e inyecta atributos nuevos. El segundo fallo permite, desde el elemento gl-emoji, colar un manejador de evento (por ejemplo un onload) que el saneamiento del cliente deja pasar. Uniendo ambas piezas, la reproducción es:

  1. Levantar una instancia de GitLab autogestionada (self-managed).
  2. Crear una incidencia.
  3. Pegar en el comentario una carga que abusa de data-sourcepos y de gl-emoji para ejecutar alert(document.location.href).

Un matiz importante que el propio autor señala: GitLab SaaS (gitlab.com) no era explotable por sí solo, porque este reporte no incluía un bypass de la CSP; el impacto se demostró sobre instancias autogestionadas.

Impacto

Cualquiera capaz de comentar en una incidencia podía ejecutar JavaScript en el navegador de quien la abriera. Y no se limita a las incidencias: afecta a otras páginas donde se publican notas, como los snippets. En una herramienta colaborativa como GitLab, eso es un XSS que se propaga solo entre quienes trabajan sobre el mismo proyecto.

Remediación

Escapar el valor de data-sourcepos (y en general cualquier atributo) antes de incrustarlo en el HTML, y no permitir atributos arbitrarios en elementos como gl-emoji. La lección transversal: tener un saneador en el servidor y otro en el cliente no basta si cada uno da por hecho que el otro ya limpió el dato. Hay que escapar en el punto exacto donde se construye el HTML, no confiar en que alguien lo hizo antes.