Reports
ALTA[OTROS]#827052

Leer cualquier fichero del servidor de GitLab moviendo una incidencia entre proyectos

Al copiar los adjuntos de una incidencia a otro proyecto, GitLab no validaba la ruta: con ../ se podía traer /etc/passwd o cualquier otro fichero del servidor.

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

Hay vulnerabilidades que no están en una línea de código llamativa, sino en una suposición. Aquí la suposición era: "el nombre del fichero que voy a copiar siempre apuntará a un adjunto legítimo". GitLab, al mover una incidencia de un proyecto a otro, copiaba también sus ficheros adjuntos mediante un componente llamado UploadsRewriter. El problema es que ese componente no validaba a qué fichero apuntaba realmente la referencia, y con un poco de ../ se le podía pedir cualquier cosa del disco.

Pasos de reproducción

El patrón que buscaba las referencias a adjuntos era este:

MARKDOWN_PATTERN = %r{\!?\[.*?\]\(/uploads/(?<secret>[0-9a-f]{32})/(?<file>.*?)\)}.freeze

Fíjate en que file se captura con .*?: acepta literalmente cualquier cosa. Ahí no hay ninguna restricción de ruta, así que basta con incluir un recorrido de directorios. La reproducción es tan directa como suena:

  1. Crear dos proyectos.
  2. Añadir en el primero una incidencia cuya descripción incluya una referencia de adjunto manipulada:
- ![a](/uploads/11111111111111111111111111111111/imagen-normal.png)
+ ![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../etc/passwd)
  1. Mover la incidencia al segundo proyecto.
  2. GitLab copia el fichero de destino —/etc/passwd en el ejemplo— como adjunto del proyecto, donde ya se puede leer tranquilamente.

Impacto

Con esto se podía leer cualquier fichero al que tuviera acceso el proceso de GitLab: tokens, ficheros de configuración, claves privadas, datos de otros usuarios… Y una lectura arbitraria de ficheros rara vez se queda en "solo lectura": suele ser el primer peldaño para robar credenciales con las que escalar a algo más serio.

Remediación

La corrección consiste en validar y resolver la ruta antes de tocar el disco, confinándola al directorio de uploads que se espera, de modo que ningún ../ pueda salir de ahí. La moraleja es la de siempre con el path traversal: una expresión regular que "captura" un nombre de fichero no lo está validando; el control tiene que hacerse sobre la ruta ya resuelta, no sobre lo que el usuario escribió.