Los investigadores de la empresa de seguridad SALT acaban de publicar una interesante descripción de cómo encontraron un fallo de autenticación, conocido como CVE-2023-28131, en el conjunto de herramientas de construcción de aplicaciones en línea llamado Expo.
La buena noticia es que Expo respondió rápidamente al informe de error de SALT, presentando una solución a las pocas horas de la revelación responsable de SALT.
Afortunadamente, la solución no dependía de que los clientes descargaran nada, porque el parche se implementó dentro del servicio en la nube de Expo, y no requería parches en ninguna aplicación preinstalada o código del lado del cliente.
El aviso de Expo, no solo explicaba lo ocurrido y cómo lo solucionó la empresa, sino que también ofrecía consejos de programación a sus clientes sobre cómo evitar este tipo de posibles vulnerabilidades en otros servicios en línea.
SALT esperó tres meses antes de publicar su informe, en lugar de apresurarse a publicarlo con fines publicitarios tan pronto como pudo, dando así a los usuarios de Expo la oportunidad de digerir la respuesta de Expo y actuar en consecuencia.
Una explicación sencilla
El proceso de autenticación problemático se explica detalladamente en el informe de SALT, por lo que aquí ofreceremos una descripción muy simple de lo que falló en el servicio OAUTH de Expo.
OAUTH, abreviatura de Open Authorization Framework (Marco de Autorización Abierto), es un proceso que permite acceder a datos privados en un servicio en línea (como editar tu perfil, añadir un nuevo artículo en un blog o aprobar que un servicio web haga publicaciones en las redes sociales por ti), sin tener que establecer nunca una contraseña con ese servicio ni iniciar sesión directamente en él.
Cuando ves servicios web que te ofrecen la opción de iniciar sesión con Google o Facebook, por ejemplo, casi siempre están utilizando OAUTH en segundo plano, para que no tengas que crear un nuevo nombre de usuario y una nueva contraseña en otro sitio web, o dar tu número de teléfono a otro servicio online.
En sentido estricto, te autentificas indirectamente, solo poniendo tus credenciales de Google o Facebook en uno de esos sitios.
A algunos usuarios no les gusta porque no quieren autenticarse en Google o Facebook solo para demostrar su identidad en otros sitios no relacionados. A otros les gusta porque suponen que sitios como Facebook y Google tienen más experiencia en gestionar el proceso de inicio de sesión, almacenar los hashes de las contraseñas de forma segura y hacer 2FA, que una pequeña tienda web que ha intentado crear sus propios procesos de seguridad criptográfica.
Autenticación externalizada
Simplificando mucho, un inicio de sesión al estilo OAUTH, a través de tu cuenta de Facebook a un sitio llamado ejemplo.com, es algo así:
- La web ejemplo.com le dice a tu aplicación o navegador: “Hola, X, ve y obtén de Facebook un token de acceso para este sitio”.
- Tú visitas una URL especial de Facebook, iniciando sesión si aún no lo has hecho y dices: “Dame un token de acceso para ejemplo.com”.
- Si Facebook está seguro de que eres quien dices ser, responde: “Hola, X, aquí tienes tu token de acceso”.
- Entregas el token de acceso a ejemplo.com, que puede ponerse en contacto con el propio Facebook para validar el token.
Ten en cuenta que solo Facebook ve tu contraseña de Facebook y tu código 2FA, si es necesario, por lo que el servicio de Facebook actúa como intermediario de autenticación entre tú y ejemplo.com.
Entre bastidores, hay una validación final, como ésta:
- La web ejemplo.com dice a Facebook: “¿Has emitido este token y validado al usuario X?”.
- Si Facebook está de acuerdo, le dice a ejemplo.com: “Sí, consideramos que este usuario está autenticado”.
Secuencia subvertible
El fallo que los investigadores de SALT encontraron en el código de Expo puede activarse subvirtiendo maliciosamente el manejo que hace Expo de lo que podríamos llamar el proceso de “intermediación de autenticación”.
Los puntos clave son los siguientes:
- La propia Expo añade una envoltura alrededor del proceso de verificación, de modo que gestiona la autenticación y la validación por ti, pasando en última instancia un token de acceso para el sitio web deseado (ejemplo.com en el intercambio anterior) de vuelta a la aplicación o sitio web desde el que te estás conectando.
- Los parámetros utilizados para gestionar la verificación se empaquetan en una URL que se envía al servicio Expo.
- Uno de estos parámetros se almacena temporalmente en una cookie web que especifica la URL a la que se enviará el token de seguridad mágico final para permitir el acceso.
- Antes de que se envíe el token de seguridad, una ventana emergente te pide que verifiques la URL que se va a autorizar, para que puedas descubrir a cualquiera que intente sustituir el proceso de inicio de sesión por una URL falsa.
- Si apruebas la ventana emergente, Expo te redirige al proceso de verificación de Facebook.
- Si Facebook aprueba la verificación, devuelve un token de acceso al servicio Expo, y Expo lo pasa a la URL que acabas de aprobar en la ventana emergente, denominada returnURL.
- La aplicación o sitio web que escucha en la URL de retorno especificado recibe la llamada de retorno de Expo, adquiere el token de acceso y, por tanto, se autentica como tú.
Por desgracia, los investigadores de SALT descubrieron que podían subvertir el proceso de inicio de sesión utilizando código JavaScript para activar el acceso a la URL de inicio de sesión inicial de Expo, pero luego eliminando la ventana emergente de verificación antes de que tuvieras tiempo de leerla o aprobarla.
En este punto, sin embargo, el servicio de Expo ya había establecido una cookie llamada ru (abreviatura de returnURL) para indicarle dónde volver a llamar con tu token de acceso mágico al final.
Esto significaba que un ciberdelincuente podía engañar al código de Expo para que “recordara” una returnURL como https://roguesite.example, sin que tú vieras nunca el cuadro de diálogo para advertirte de que se estaba produciendo un ataque, y mucho menos que lo aprobaras por error.
A continuación, los investigadores utilizaron un segundo código JavaScript para simular la redirección de Expo al proceso de verificación de Facebook, que tendría éxito automáticamente si (como mucha gente) ya habías iniciado sesión en el propio Facebook.
La verificación de Facebook, a su vez, redirigiría el proceso de inicio de sesión de Expo al propio código JavaScript de Expo que, de forma confiada pero errónea, obtendría la URL de retorno nunca verificada para su devolución de llamada de la cookie mágica ru que estableció al principio, sin tu aprobación ni tu conocimiento.
¿Fallo abierto o fallo cerrado?
Como puedes ver en la descripción anterior, un fallo inadecuado del código de Expo era el origen de la vulnerabilidad.
En la jerga, el código de autenticación debería fallar generalmente en modo cerrado, lo que significa que el proceso no debería tener éxito a menos que se haya señalado algún tipo de aprobación activa.
Suponemos que Expo no pretendía que el sistema fallara abierto, dado que el informe de SALT muestra que su diálogo de aprobación emergente tenía este aspecto:
La aplicación en https://roguesite.example pide que accedas a tu cuenta de Facebook. ¿Confías plenamente en https://roguesite.example y aceptas que lo haga: [No] [Sí]
La respuesta por defecto, como era de esperar, era [No], pero esto solo provocaría que el sistema fallara cerrado si utilizabas el propio código del lado del cliente de Expo para controlar el proceso de verificación.
Al suministrar su propio JavaScript para ejecutar la secuencia de solicitudes de verificación, los investigadores pudieron tratar el diálogo de aprobación como si dijera:
Si no nos dices explícitamente que Quieres bloquear https://roguesite.example para iniciar sesión a través de tu cuenta de Facebook, dejaremos que lo haga: [Permitir] [Bloquear]
La solución, entre otros cambios, fue que el código de inicio de sesión inicial de Expo estableciera esa cookie ru solo después de que hubieras aprobado explícitamente la llamada returnURL, de modo que el código JavaScript de inicio de sesión posterior de Expo fallara si se saltaba la ventana emergente de verificación, en lugar de confiar ciegamente en una URL que nunca habías visto ni aprobado.
En muchos aspectos, este fallo es similar al del Enchufe Inteligente Wemo de Belkin sobre el que escribimos hace dos semanas, aunque la causa principal en el caso de Belkin era un desbordamiento de búfer, no una devolución de llamada web fraudulenta.
El código de Belkin asignaba un búfer de memoria de 68 bytes en su código del lado del servidor, pero se basaba en comprobar en su código del lado del cliente que no intentabas enviar más de 68 bytes, dejando así al servidor a merced de los atacantes que decidían hablar con el servidor utilizando su propio código del lado del cliente que se saltaba el proceso de verificación.
¿Qué hacer?
- Cuando informes y escribas sobre fallos, considera seguir el ejemplo de SALT. Divulga de forma responsable, dando al proveedor un tiempo razonable para solucionar la vulnerabilidad, además de un tiempo razonable para avisar a sus propios usuarios, antes de publicar detalles que permitirían a cualquier otra persona crear un exploit propio.
- Cuando recibas informes de errores, considera seguir el ejemplo de Expo. Responde rápidamente, mantente en contacto con el informador del fallo, parchea la vulnerabilidad tan pronto como puedas, proporciona un informe de investigación útil para tus usuarios y mantén la objetividad. (Resiste las sugerencias de tu equipo de marketing de elogiarte por “tomarte en serio la seguridad” o de desestimar el problema por carecer de importancia. Eso lo decidirán tus usuarios, basándose en la prontitud y pertinencia de tu respuesta, y en su propia evaluación del riesgo).
- Asegúrate de que tu código de autenticación falla cerrado. Asegúrate de que no tienes pasos de verificación o aprobación que puedan neutralizarse simplemente ignorándolos o cancelándolos.
- Nunca asumas que tu propio código del lado del cliente controlará el proceso de verificación. Piensa que los atacantes harán ingeniería inversa de tu protocolo y crearán su propio código cliente para eludir todas las comprobaciones que puedan.
- Cierra la sesión de las cuentas web cuando no las estés utilizando activamente. Muchas personas inician sesión en cuentas como Google, Amazon, Facebook, Apple y otras, y luego permanecen conectadas indefinidamente, porque les resulta cómodo. Cerrar la sesión impide que se realicen muchas acciones (como autenticaciones, publicaciones, me gusta, compartir y muchas más) cuando no las esperas: en su lugar, verás un aviso de inicio de sesión.
No olvides que cerrando la sesión de los servicios web siempre que puedas, y borrando con frecuencia todas las cookies de tu navegador y los datos web almacenados, también reduces la cantidad de información de seguimiento que los sitios pueden recopilar sobre ti mientras navegas.
Al fin y al cabo, si no estás conectado y no te quedan cookies de rastreo de antes, los sitios ya no saben exactamente quién eres ni qué hiciste la última vez que los visitaste.