Resumen
No todas las vulnerabilidades graves son un RCE espectacular. Esta es "solo" saltarse un ajuste de privacidad, y sin embargo está detrás de una de las mayores filtraciones de datos de Twitter. El fallo permitía obtener el ID de una cuenta (que es prácticamente conocer su usuario) a partir de un número de teléfono o un correo electrónico, aunque la persona hubiera desactivado la opción de que la encuentren así. Estaba en el proceso de autorización del cliente de Android, concretamente en la comprobación de duplicación de cuentas del flujo de inicio de sesión.
Los identificadores reales (token de invitado, bearer, email de prueba, ID) aparecen [REDACTADO]; el email usado era una cuenta de prueba del propio investigador.
Pasos de reproducción
La idea es abusar de un flujo pensado para otra cosa: el "¿esta cuenta ya existe?" del login.
- Se crea un LoginFlow con un
POSTahttps://api.twitter.com/1.1/onboarding/task.json?flow_name=login. La respuesta trae unflow_token. - Se envía un segundo
POSTahttps://api.twitter.com/1.1/onboarding/task.jsoncon eseflow_tokeny, como identificador, el teléfono o email de la víctima:
{"flow_token":"[REDACTADO]","subtask_inputs":[{"enter_text":{"suggestion_id":null,"text":"[EMAIL_DE_PRUEBA]","link":"next_link"},"subtask_id":"LoginEnterUserIdentifier"}]}
En la respuesta aparece el subtask AccountDuplicationCheck con un campo user_id: el identificador de la cuenta ligada a ese email o teléfono. Y todo esto con la descubribilidad desactivada en los ajustes de esa cuenta.
Impacto
Cualquiera, sin autenticarse, podía cruzar teléfonos y correos con cuentas de Twitter y hacerlo a escala: automatizando estas dos peticiones se puede enumerar una porción enorme de la base de usuarios —incluidas cuentas suspendidas— y construir una base de datos de "teléfono/email → cuenta". Eso no es una molestia técnica: es una pérdida de privacidad masiva, munición perfecta para acoso dirigido o para vender esos cruces. De hecho, este es el fallo que alimentó la filtración de millones de cuentas.
Remediación
Dos cosas. La concreta: los flujos de comprobación de duplicados no deben revelar la existencia ni el identificador de una cuenta; tienen que responder igual exista o no. Y la de fondo: un ajuste de privacidad solo sirve si se aplica en el backend y en todos los puntos de la API. Si la interfaz respeta la preferencia pero un endpoint la ignora, la casilla que marcó el usuario es pura decoración.