Reports
BAJA[AUTENTICACIÓN]#4000185

HackerOne Code enviaba a Segment tokens de restablecimiento de contraseña todavía válidos

Al abrir un enlace de restablecimiento de contraseña de HackerOne Code, Segment recibía automáticamente el token completo y sin usar, asociado al mismo identificador anónimo que ya estaba vinculado al email y al ID del usuario.

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

El cliente web de HackerOne Code carga la librería de analítica Segment y llama a analytics.page() en cuanto se carga cada página. En la página de restablecimiento de contraseña eso tenía una consecuencia seria: el token de restablecimiento viaja en la cadena de consulta de la URL, y el cliente no lo eliminaba antes de generar el evento. Por eso, nada más abrir el enlace, y antes de que el usuario enviara el formulario, el token completo de 64 caracteres acababa en Segment.

El token aparecía en cuatro campos del evento de página:

context.page.search
context.page.url
properties.search
properties.url

No era un valor inofensivo de la ruta. El cliente toma la primera clave de la consulta como credencial de restablecimiento y la envía tal cual a la API de cambio de contraseña, así que lo que llegaba a Segment era material de autenticación en uso.

Había además un agravante. En un navegador que ya se había usado antes, el evento con el token llevaba el mismo anonymousId que Segment ya había recibido en un evento identify junto al email y el ID del usuario. Con los dos eventos se podía saber a qué cuenta pertenecía cada token.

El investigador lo comprobó con cuatro tokens nuevos de su propia cuenta de desarrollador. Segment respondió HTTP 200 a todos los envíos, y después cada token sirvió para restablecer la contraseña: el cambio devolvía HTTP 200, la contraseña antigua pasaba a dar HTTP 401 y la nueva, HTTP 200. En la prueba con el navegador ya usado, canjeó el token unos 17 segundos después de que se enviara a Segment.

Como control, abrió /password-reset sin parámetros en un perfil de navegador limpio. El evento de página se seguía enviando, pero los campos de búsqueda iban vacíos y las URL no contenían ningún token.

Todas las pruebas se hicieron sobre una única cuenta de desarrollador propiedad del investigador. No accedió a cuentas, programas, reportes ni datos de clientes, ni tampoco a ningún panel de Segment: Segment solo recibió las peticiones que la propia aplicación generaba de forma automática.

El programa marcó el reporte como resuelto y pagó una recompensa de importe no público. Se envió el 5 de septiembre de 2026 y se divulgó el 24 de septiembre de 2026.

Pasos de reproducción

  1. Crea una cuenta de HackerOne Code o usa una que sea tuya.
  2. Usa un perfil de navegador persistente y abre las herramientas de desarrollo o un proxy de interceptación. El investigador añadió esta cabecera a todas las peticiones hacia HackerOne Code:

`` X-Bug-Bounty: HackerOne-1rhino2 ``

  1. En ese perfil, solicita un restablecimiento de contraseña y complétalo. Cuando termine con éxito, anota el evento identify de Segment que incluye el email de la cuenta, el ID de usuario y el anonymousId.
  2. Solicita un enlace de restablecimiento nuevo para la misma cuenta.
  3. Abre ese enlace en el mismo perfil de navegador, pero todavía no envíes el formulario.
  4. Revisa el evento de página que se envía solo a Segment. El token completo, sin usar, aparece en los cuatro campos indicados arriba. El anonymousId coincide con el del evento identify anterior y el endpoint de ingesta de Segment responde HTTP 200.
  5. Escribe el email de la cuenta y una contraseña nueva, y envía el formulario.
  6. Comprueba que el restablecimiento responde HTTP 200, que un inicio de sesión con la contraseña antigua devuelve HTTP 401 y que uno con la nueva devuelve HTTP 200.
  7. Como control, abre /password-reset sin parámetros en un perfil de navegador limpio. El evento de página se envía igual, pero los campos de búsqueda están vacíos y las URL no llevan token.

Impacto

Un token de restablecimiento válido salía hacia un tercero en cuanto el usuario abría el enlace. Si el navegador ya se había usado antes, ese token quedaba ligado al email y al ID del usuario mediante el anonymousId. Quien pudiera leer esos eventos a tiempo, ya fuera en Segment o en cualquier destino al que Segment reenviara los datos, podía saber a qué cuenta correspondía el token y fijar una contraseña nueva mientras siguiera siendo válido.

La severidad se valoró como baja porque el atacante necesita acceso a esa telemetría durante el tiempo de validez del token.

Referencias

El investigador citó la documentación de Twilio Segment, que explica que la vista Raw del Source Debugger muestra el JSON completo de cada evento recibido y que los eventos de una fuente pueden reenviarse a los destinos conectados:

  • https://www.twilio.com/docs/segment/connections/sources/debugger
  • https://www.twilio.com/docs/segment/guides/filtering-data

También mencionó como antecedentes los reportes #342693 y #787160 de HackerOne, sobre fugas de tokens a través de la cabecera Referer. Este caso es distinto: afecta a otro activo y el token no se filtra por el Referer, sino que la propia aplicación lo mete en un POST de analítica automático al cargar la página.