Creo que la mejor manera de entender cómo este patrón de uso de OAuth puede ser inseguro es hablar sobre el propósito de los ámbitos de OAuth.
De acuerdo con su diseño, un alcance de OAuth representa un conjunto de acciones posibles que se pueden realizar en nombre del usuario autenticado. Entonces (como un ejemplo inventado) si su cliente obtiene un alcance de token con el alcance "send_messages"
, entonces puede enviar mensajes en nombre del usuario. En cierto sentido, la definición verdadera de un ámbito es qué acciones le permite realizar un token con ese alcance.
El problema con la forma "Iniciar sesión con FB / Twitter / etc". se implementa es que todos usan un solo ámbito (por ejemplo, "public_profile"
para Facebook).
Según la documentación, este alcance es bastante inofensivo, con esto el cliente puede ver la identidad del usuario actual. Sin embargo, si un sitio web de terceros A.com usa este token para verificar la identidad de un usuario e iniciar sesión en A.com, esencialmente ha expandido la definición del ámbito public_profile
para significar "ver información del perfil público, y también acceder a los recursos de este usuario en A.com ".
Todo lo que necesita en este momento es que un atacante obtenga un token con un alcance public_profile
(por ejemplo, ejecutando otro sitio web con un enlace "Iniciar sesión con Facebook"): este alcance solicitado parece inofensivo según la documentación de Facebook y lo que le muestran al usuario, pero en realidad si el atacante puede pasar eso a A.com, puede acceder a los recursos del usuario.
La solución
La solución que surgió es que A.com verifique que el token se generó específicamente para A.com, es decir, que durante el flujo de inicio de sesión de OAuth, el usuario fue dirigido a A.com en lugar de a otro sitio.
Para hacer esto, el token OAuth generado tiene información adicional asociada, específicamente "a qué sitio web / aplicación se envió este token". La presencia de esta información adicional determina el resultado cuando inspecciona el token (por ejemplo, / debug_token punto final).
(Personalmente creo que esto más o menos constituye un "alcance invisible", y no tendríamos esta confusión si Facebook / etc. hubiera proporcionado ámbitos de inicio de sesión personalizados de terceros, por ejemplo, "third-party:a.com"
, sin embargo, la solución existente es igual de funcional.)
(El flujo "implícito" de OAuth a veces es totalmente culpable en esta situación, que creo que falta la mitad del punto. El problema es que el flujo "implícito" permite que un atacante inserte sus propios tokens de OAuth interceptar la redirección del navegador, pero esto no sería un problema si los ámbitos de OAuth no se redefinieran.)