Entrada

OAuth Lab 1

OAuth Lab 1

Skills

  • Authentication bypass via OAuth implicit flow

Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio utiliza un servicio OAuth para permitir que los usuarios inicien sesión con sus cuentas de redes sociales. Una validación defectuosa por parte del cliente hace posible que un atacante inicie sesión en las cuentas de otros usuarios sin conocer sus contraseñas

Para resolver el laboratorio, debemos iniciar sesión en la cuenta de Carlos, su dirección de correo electrónico es carlos@carlos-montoya.net. Podemos iniciar sesión en nuestra cuenta usando las credenciales wiener:peter


Resolución

Al acceder a la web vemos esto

Cuando pulsamos sobre My account accedemos a /my-account y nos hace un redirect a /social-login donde nos muestra esto

Posteriormente nos redirige a este panel de login, donde nos podemos loguear con las credenciales wiener:peter

Posteriormente nos redirige a esta otra ventana donde nos solicita permiso para acceder a nuestro perfil e email

OAuth es un framework comúnmente utilizado que permite a los sitios web y aplicaciones web solicitar un acceso limitado a la cuenta de un usuario en otra aplicación. Lo más importante es que OAuth permite que el usuario conceda este acceso sin exponer sus credenciales de inicio de sesión a la aplicación que realiza la solicitud. Esto significa que los usuarios pueden ajustar qué datos desean compartir en lugar de tener que entregar el control total de su cuenta a un tercero

El proceso básico de OAuth se utiliza ampliamente para integrar funcionalidades de terceros que requieren acceso a ciertos datos de la cuenta del usuario. Por ejemplo, una aplicación puede usar OAuth para solicitar acceso a tu lista de contactos del correo electrónico y así sugerir personas con las que conectar. Sin embargo, este mismo mecanismo también se utiliza para ofrecer servicios de autenticación de terceros, permitiendo que los usuarios inicien sesión con una cuenta que ya tienen en otro sitio web

Aunque OAuth 2.0 es el estándar actual, algunos sitios web aún utilizan la versión legacy 1a. OAuth 2.0 fue creado desde cero en lugar de ser desarrollado directamente a partir de OAuth 1.0, como resultado de esto, ambos son muy diferentes. En estos laboratorios cada vez que hacemos referencia a OAuth nos referimos a OAuth 2.0

OAuth 2.0 fue desarrollado originalmente como una forma de compartir acceso a datos específicos entre aplicaciones. Funciona definiendo una serie de interacciones entre tres partes distintas, una aplicación cliente, un propietario de los recursos y un proveedor de servicios OAuth

  • Aplicación cliente - El sitio web o aplicación web que desea acceder a los datos del usuario

  • Propietario de los recursos - El usuario que es dueño de los datos a los que la aplicación cliente quiere acceder

  • Proveedor de servicio OAuth - El sitio web o aplicación web que controla los datos del usuario y el acceso a ellos. Apoyan OAuth proporcionando una API para interactuar con un servidor de autorización (gestiona la autenticación del usuario y emite tokens de acceso) y con un servidor de recursos (aloja los datos protegidos del usuario y los comparte si el token es válido)

Existen numerosas formas diferentes de implementar el proceso de OAuth. Estas se conocen como los flows o grant types de OAuth. Nos enfocaremos en los grant types de authorization code e implicit, ya que son los más comunes. De manera general, ambos grant types involucran las siguientes etapas

  • La aplicación cliente solicita acceso a un subconjunto de datos del usuario, especificando qué grant type desea usar y qué tipo de acceso desea obtener

  • Se le solicita al usuario que inicie sesión en el servicio OAuth y dé su consentimiento para el acceso solicitado

  • La aplicación cliente recibe un token de acceso único que demuestra que tiene permiso del usuario para acceder a los datos solicitados. Exactamente cómo ocurre esto varía significativamente según el grant type

  • La aplicación cliente utiliza este token de acceso para llamar a la API y obtener los datos relevantes del servidor de recursos

El grant type de OAuth determina la secuencia exacta de los pasos involucrados en el proceso de OAuth. El grant type también afecta cómo la aplicación cliente se comunica con el servicio OAuth en cada etapa, incluyendo cómo se envía el token de acceso. Por esta razón, los grant types también reciben el nombre OAuth flows

Un servicio OAuth debe estar configurado para soportar un grant type en particular antes de que una aplicación cliente pueda iniciar el flujo correspondiente. La aplicación cliente especifica qué grant type desea usar en la solicitud de autorización inicial que envía al servicio OAuth

Existen varios grant types, cada uno con diferentes niveles de complejidad y consideraciones de seguridad. Nos centraremos en los grant types más comunes, el authorization code y el implicit

Para cualquier grant type de OAuth, la aplicación cliente debe especificar qué datos desea acceder y qué tipo de operaciones desea realizar. Esto lo hace utilizando el parámetro scope de la solicitud de autorización que envía al servicio OAuth

Para un OAuth básico, los scopes a los que una aplicación cliente puede solicitar acceso son únicos para cada servicio OAuth. Como el nombre del scope es solo una cadena de texto arbitraria, el formato puede variar dependiendo del proveedor. Algunos incluso usan una URI completa como nombre del scope, similar a un endpoint de API REST. Por ejemplo, al solicitar acceso de solo lectura a la lista de contactos de un usuario, el nombre del scope podría adoptar cualquiera de las siguientes formas dependiendo del servicio OAuth que se utilice

1
2
3
4
scope=contacts
scope=contacts.read
scope=contact-list-r
scope=https://oauth-authorization-server.com/auth/scopes/user/contacts.readonly

Sin embargo, cuando OAuth se utiliza para autenticación, a menudo se emplean los scopes estandarizados de OpenID Connect en su lugar. Por ejemplo, el scope openid profile otorgará a la aplicación cliente acceso de lectura a un conjunto predefinido de información básica del usuario, como su dirección de correo electrónico, nombre de usuario, entre otros. Hablaremos más sobre OpenID Connect en el siguiente laboratorio

Authorization code grant type - La aplicación cliente y el servicio OAuth primero utilizan redirecciones para intercambiar una serie de solicitudes HTTP basadas en el navegador que inician el flujo. Se le pregunta al usuario si consiente el acceso solicitado. Si acepta, la aplicación cliente recibe un código de autorización. Luego, la aplicación cliente lleva a cabo un intercambio de este código con el servicio OAuth y recibe un token de acceso, que puede usar para llamar a la API y obtener datos relevantes del usuario

Toda la comunicación que ocurre después del intercambio del código/token se envía de servidor a servidor a través de un canal seguro preconfigurado y, por lo tanto, es invisible para el usuario final. Este canal seguro se establece cuando la aplicación cliente se registra por primera vez con el servicio OAuth. En este momento, también se genera una clave secreta, que la aplicación cliente debe usar para autenticar sus solicitudes entre servidores

Dado que los datos más sensibles, es decir, el token de acceso y los datos del usuario, no se envían a través del navegador, este grant type es probablemente el más seguro. Las aplicaciones del lado del servidor deberían usar siempre estos grant types si es posible

Authorization request - La aplicación cliente envía una solicitud al servicio OAuth en el endpoint /authorization pidiendo permiso para acceder a datos específicos del usuario. Es importante tener en cuenta que el mapeo del endpoint puede variar entre proveedores, en los laboratorios de portswigger se usa el endpoint /auth para este propósito. Sin embargo, siempre debemos poder identificar el endpoint basado en los parámetros usados esta la solicitud

1
2
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=code&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com

La solicitud anterior incluye los siguientes parámetros destacados, que normalmente se proporcionan en la query

  • client_id - Parámetro obligatorio que contiene el identificador único de la aplicación cliente. Este valor se genera cuando la aplicación cliente se registra en el servicio OAuth

  • redirect_uri - La URI a la que debe redirigirse el navegador del usuario cuando envíe el código de autorización a la aplicación cliente. También se conoce como callback URI o callback endpoint. Muchos ataques OAuth se basan en explotar fallos en la validación de este parámetro

  • response_type - Determina qué tipo de respuesta espera la aplicación cliente y por lo tanto, qué flujo desea iniciar. Para el grant type de authorization code el valor debe ser code

  • scope - Se utiliza para especificar a qué subconjunto de datos del usuario desea acceder la aplicación cliente. Tenga en cuenta que estos pueden ser scopes personalizados por el proveedor de OAuth o scopes estandarizados definidos por la especificación OpenID Connect

  • state - Almacena un valor único e impredecible que está vinculado a la sesión actual en la aplicación cliente. El servicio OAuth debe devolver este valor exacto en la respuesta, junto con el código de autorización. Este parámetro funciona como una especie de token CSRF para la aplicación cliente y asegura que la solicitud a su endpoint /callback provenga de la misma persona que inició el flujo de OAuth

User login and consent - Cuando el servidor de autorización recibe la solicitud inicial, redirigirá al usuario a una página de inicio de sesión, donde se le pedirá que ingrese a su cuenta con el proveedor de OAuth (Google, Apple, GitHub)

Luego, se le mostrará una lista de datos a los que la aplicación cliente quiere acceder. Esto se basa en los scopes que han sido definidos en la authorization request. El usuario puede elegir si quiere dar o no su consentimiento para este acceso

Es importante destacar que, una vez que el usuario ha aprobado un scope determinado para una aplicación cliente, este paso se completará automáticamente siempre que el usuario aún tenga una sesión válida con el servicio de OAuth. En otras palabras, la primera vez que el usuario seleccione Iniciar sesión con Google/Facebook/GitHub, tendrá que ingresar manualmente y dar su consentimiento, pero si más tarde vuelve a la aplicación cliente, a menudo podrá iniciar sesión nuevamente con un solo click

Authorization code grant type - Si el usuario ha aceptado el acceso solicitado, su navegador será redirigido al endpoint /callback que fue especificado en el parámetro redirect_uri de la authorization request. La solicitud GET resultante contendrá el código de autorización como un parámetro de la query. Dependiendo de la configuración, también podría enviar el parámetro state con el mismo valor que en la authorization request

1
2
GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com

Access token request - Una vez que la aplicación cliente ha recibido el código de autorización, debe intercambiarlo por un token de acceso. Para hacer esto, envía una solicitud POST de servidor a servidor al endpoint /token del servicio OAuth. A partir de este punto, toda la comunicación ocurre a través de un canal seguro y por lo tanto, generalmente la solicitud no puede ser observada o controlada por un atacante

1
2
3
4
POST /token HTTP/1.1
Host: oauth-authorization-server.com
…
client_id=12345&client_secret=SECRET&redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8

Además del client_id y el authorization_code, también hay estos dos nuevos parámetros

  • client_secret - La aplicación cliente debe autenticarse incluyendo la clave secreta que le fue asignada al registrarse en el servicio OAuth

  • grant_type - Se utiliza para asegurar que el nuevo endpoint sepa que grant type es el que quiere usar la aplicación cliente. En este caso, debe establecerse como authorization_code

Access token grant - El servicio OAuth se encargará de validar la solicitud del access token. Si todo es correcto, el servidor otorgará a la aplicación cliente un access token con los scopes solicitados

1
2
3
4
5
6
7
{
    "access_token": "z0y9x8w7v6u5",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "openid profile",
    …
}
  • API call - Ahora que la aplicación cliente tiene el access token, finalmente puede obtener los datos del usuario del servidor de recursos (API de GitHub, Google, etc que almacena los datos del usuario). Para hacer esto, realiza una API call al endpoint /userinfo del servicio OAuth. El access token se envía en la cabecera Authorization: Bearer para demostrar que la aplicación cliente tiene permiso para acceder a estos datos
1
2
3
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
  • Resource grant - El servidor de recursos debe verificar que el token es válido y que pertenece a la aplicación cliente. Si es así, enviará el recurso solicitado, es decir, los datos del usuario según el scope del token de acceso. Finalmente, la aplicación cliente puede utilizar estos datos para el propósito previsto. En el caso de la autenticación OAuth, normalmente se usará como ID para conceder al usuario una sesión autenticada, lo que efectivamente iniciará su sesión
1
2
3
4
5
{
    "username": "carlos",
    "email": "carlos@carlos-montoya.net",
    …
}

Implicit grant type - El implicit grant type es mucho más simple, en lugar de obtener primero un código de autorización y luego intercambiarlo por un token de acceso, la aplicación cliente recibe el token de acceso inmediatamente después de que el usuario dé su consentimiento

Puede que te preguntes por qué las aplicaciones cliente no siempre usan el implicit grant type, la respuesta es relativamente simple, es mucho menos seguro. Cuando se usa el implicit grant type, toda la comunicación ocurre a través de redireccionamientos del navegador, es decir, no hay un canal seguro en segundo plano como en el authorization code grant type. Esto significa que el token de acceso y los datos del usuario están más expuestos a posibles ataques

El implicit grant type es más adecuado para aplicaciones de una sola página y aplicaciones nativas de escritorio que no pueden almacenar fácilmente el client_secret en el back-end y por lo tanto, no se benefician tanto del authorization code grant type

Authorization request - El implicit grant type comienza de manera muy similar al authorization code grant type. La única diferencia importante es que el parámetro response_type debe establecerse como token

1
2
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=token&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com

User login and consent - El usuario inicia sesión y decide si otorga o no los permisos solicitados. Este proceso es exactamente igual en ambos grant types

Access token grant - Si el usuario otorga su consentimiento para el acceso solicitado, aquí es donde las cosas comienzan a diferir. El servicio OAuth redirigirá el navegador del usuario al redirect_uri especificado en la authorization request. Sin embargo, en lugar de enviar un parámetro en la query con un código de autorización, enviará el token de acceso y otros datos específicos del token como un fragmento de URL

Dado que el token de acceso se envía en un fragmento de URL, nunca se envía directamente a la aplicación cliente. En su lugar, la aplicación cliente debe utilizar un script adecuado para extraer el fragmento y almacenarlo

1
2
GET /callback#access_token=z0y9x8w7v6u5&token_type=Bearer&expires_in=5000&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com

API call - Una vez que la aplicación cliente ha extraído el token de acceso del fragmento de URL, puede usarlo para hacer llamadas API al endpoint /userinfo del servicio OAuth. A diferencia del authorization code grant type, esto también ocurre a través del navegador

1
2
3
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5

Resource grant - El servidor de recursos debe verificar que el token es válido y que pertenece a la aplicación cliente. Si es así, enviará el recurso solicitado, es decir, los datos del usuario según el scope asociado al token de acceso

La aplicación cliente finalmente puede utilizar estos datos para su propósito previsto. En el caso de la autenticación con OAuth, normalmente se usará como un ID para otorgar al usuario una sesión autenticada, iniciando así sesión

1
2
3
4
{
    "username": "carlos",
    "email": "carlos@carlos-montoya.net"
}

Aunque originalmente no fue diseñado para este propósito, OAuth ha evolucionado hasta convertirse también en un método de autenticación de usuarios. Por ejemplo, en vez de crearnos una cuenta en un sitio web proporcionando un correo electrónico y contraseña podemos hacerlo empleando una cuenta de Google, Facebook GitHub etc. Estas opciones es muy probable que estén basadas en OAuth 2.0

En los mecanismos de autenticación con OAuth, los flujos básicos de OAuth siguen siendo prácticamente los mismos, la principal diferencia está en cómo la aplicación cliente utiliza los datos que recibe. Desde la perspectiva del usuario final, el resultado de la autenticación con OAuth se asemeja en gran medida al inicio de sesión único (SSO) basado en Security Assertion Markup Language (SAML). En estos materiales, nos centraremos exclusivamente en las vulnerabilidades de este tipo que son similares al SSO

La autenticación con OAuth generalmente se implementa de la siguiente manera

  • El usuario elige la opción de iniciar sesión con su cuenta de redes sociales

  • La aplicación cliente utiliza entonces el servicio OAuth de la red social para solicitar acceso a ciertos datos que pueda usar para identificar al usuario, como por ejemplo, la dirección de correo electrónico registrada en su cuenta

  • Después de recibir un token de acceso, la aplicación cliente solicita estos datos al servidor de recursos, normalmente desde un endpoint dedicado, como /userinfo

  • Una vez recibidos los datos, la aplicación cliente los utiliza en lugar de un nombre de usuario para autenticar al usuario. El token de acceso obtenido del servidor de autorización suele emplearse en lugar de una contraseña tradicional

Las vulnerabilidades en la autenticación OAuth surgen en parte porque la especificación de OAuth es relativamente vaga y flexible por diseño. Aunque hay varios componentes obligatorios que son necesarios para la funcionalidad básica de cada grant type, la gran mayoría de la implementación es opcional. Esto incluye muchas configuraciones necesarias para mantener seguros los datos de los usuarios. En resumen, hay muchas oportunidades para que se lleven a cabo malas prácticas

Otro de los problemas con clave de OAuth es la falta general de funciones de seguridad integradas. La seguridad depende casi por completo de que los desarrolladores utilicen la combinación correcta de opciones de configuración e implementen sus propias medidas de seguridad adicionales, como una validación de entrada robusta

Dependiendo del grant type, los datos altamente sensibles también se envían a través del navegador, lo que presenta diversas oportunidades para que un atacante los intercepte

Reconocer cuándo una aplicación utiliza autenticación OAuth es relativamente sencillo, si vemos una opción para iniciar sesión con nuestra cuenta de otro sitio web (Google, Facebook, GitHub etc) es un fuerte indicio de que se está usando OAuth

La forma más confiable de identificar la autenticación OAuth es redirigir tu tráfico a través de Burpsuite y revisar los mensajes HTTP correspondientes cuando usas esta opción de inicio de sesión. Independientemente del grant type que se emplee, la primera solicitud del flujo siempre será una petición al endpoint /authorization, que contiene varios parámetros de consulta específicos para OAuth. En particular, debemos buscar los parámetros client_id, redirect_uri y response_type. Este es un ejemplo de una solicitud de autorización

1
2
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=token&scope=openid%20profile&state=ae13d489bd00e3c2 HTTP/1.1
Host: oauth-authorization-server.com

Realizar un reconocimiento básico del servicio OAuth utilizado puede orientarnos en la dirección correcta para identificar vulnerabilidades

Si se utiliza un servicio OAuth externo, deberíamos poder identificar el proveedor específico a partir del nombre de host al que se envía la solicitud de autorización. Por ejemplo, si el host es accounts.google.com podemos saber que el proveedor es Google

Dado que estos servicios ofrecen una API pública, suele haber documentación detallada disponible que proporciona información útil, como los nombres exactos de los endpoints y qué opciones de configuración se están utilizando. Si el proveedor es Google podemos consultar la documentación de OAuth en https://developers.google.com/identity/protocols/oauth2

Una vez sepamos el nombre de host del servidor de autorización, siempre debemos intentar enviar una solicitud GET a estos endpoints estándar

1
2
/.well-known/oauth-authorization-server  
/.well-known/openid-configuration  

Estos suelen devolver un archivo de configuración JSON con información clave, como detalles sobre funciones adicionales que podrían estar soportadas. En ocasiones, esto puede revelar una superficie de ataque más amplia o características admitidas que no se mencionan en la documentación

Las aplicaciones cliente suelen utilizar servicios OAuth reconocidos y altamente robustos, que están bien protegidos contra exploits conocidos. Sin embargo, su propia implementación puede ser menos segura

Las vulnerabilidades pueden surgir tanto en la implementación de OAuth por parte de la aplicación cliente como en la configuración del propio servicio OAuth. Algunas de las vulnerabilidades más comunes son las siguientes

Vulnerabilidades en la aplicación cliente

  • Implementación incorrecta del grant type

  • Protección CSRF defectuosa

Vulnerabilidades en el servicio OAuth

  • Leaks de de códigos de autorización y tokens de acceso

  • Validación del scope errónea

  • Registrar usuarios sin verificar sus datos

Como ya hemos mencionado, la especificación de OAuth está poco definida. Esto es especialmente cierto en lo que respecta a la implementación por parte de la aplicación cliente. Un flujo de OAuth involucra muchos componentes dinámicos, con numerosos parámetros opcionales y ajustes de configuración en cada grant type, lo que significa que hay amplio margen para configuraciones incorrectas

Implementación incorrecta del grant type - Debido a los peligros que implica enviar tokens de acceso a través del navegador, el implicit grant type se recomienda principalmente para aplicaciones de una sola página (SPA). Sin embargo, también se utiliza con frecuencia en aplicaciones web clásicas de tipo cliente-servidor debido a su relativa simplicidad

En este flujo, el token de acceso se envía desde el servicio OAuth a la aplicación cliente a través del navegador del usuario como un fragmento de la URL y luego, la aplicación cliente accede al token mediante JavaScript. El problema es que, si la aplicación desea mantener la sesión después de que el usuario cierre la página, necesita almacenar en algún lugar los datos del usuario actual (normalmente un ID de usuario y el token de acceso)

Para solucionar este problema, la aplicación cliente a menudo envía estos datos al servidor en una solicitud POST y luego asigna al usuario una cookie de sesión, haciendo que el usuario se loguee. Esta solicitud es aproximadamente equivalente al envío de un formulario que podría enviarse como parte de un inicio de sesión tradicional basado en contraseñas. Sin embargo, en este escenario, el servidor no tiene secretos ni contraseñas para comparar con los datos enviados, lo que significa que confía implícitamente en ellos

En el implicit grant type, esta solicitud POST queda expuesta al atacantes a través del navegador. Como resultado, este comportamiento puede conducir a una vulnerabilidad grave si la aplicación cliente no verifica correctamente que el token de acceso coincida con los demás datos de la solicitud. En este caso, un atacante puede simplemente modificar los parámetros enviados al servidor para hacerse pasar por cualquier usuario

Si nos dirigimos a la extensión Logger ++ de Burpsuite vemos todo el flujo de peticiones

Podemos determinar el grant type observando la petición a /auth. En este caso el parámetro response_type tiene el valor token lo cual quiere decir que estamos ante un implicit grant type. Además de esto también podemos ver el nombre de host del servidor de autorización, en este caso es oauth-0a97004f04bdd3a98266d60502d800fe.oauth-server.net

Si tenemos el nombre de host del servidor de autorización podemos enumerar estos endpoints para obtener información que puede resultarnos útil, es recomendable hacer esto porque puede revelar una superficie de ataque más amplia o características admitidas que no se mencionan en la documentación. En este caso es la única opción debido a que Portswigger no cuenta con una API pública y por lo tanto, tampoco cuenta con documentación de la que obtener información interesante

1
2
/.well-known/oauth-authorization-server  
/.well-known/openid-configuration  

Si hacemos una petición GET a /.well-known/oauth-authorization-server vemos que no existe

Sin embargo, si hacemos una petición GET a /.well-known/openid-configuration obtenemos información valiosa

Si nos fijamos en la petición hecha a /authenticate vemos que se están enviando tres campos

Cambiamos nuestro email por carlos@carlos-montoya.net

Pulsamos click dererecho > Request in browser > In original session

Si accedemos a My account vemos que hemos accedido a la cuenta del usuario carlos

Para prevenir vulnerabilidades en la autenticación OAuth, es fundamental que tanto el proveedor de OAuth como la aplicación cliente implementen una validación robusta de los datos clave, especialmente del parámetro redirect_uri. La especificación de OAuth ofrece muy poca protección integrada, por lo que depende de los desarrolladores asegurar que el flujo de OAuth sea lo más seguro posible

Es importante destacar que las vulnerabilidades pueden surgir tanto del lado de la aplicación cliente como del propio servicio de OAuth. Incluso si tu implementación es sólida, todo depende de que la aplicación del otro extremo sea igualmente robusta. Esto significa que

  • Si eres el la aplicación cliente, el otro extremo es el proveedor de OAuth/OpenID Connect como Google, Facebook o tu servicio interno)

  • Si eres el proveedor (el servicio de autenticación), el otro extremo es el cliente (la app que consume tu OAuth)

Para los proveedores de servicios OAuth se deberían implementar estas medidas

  • Requerir que las aplicaciones cliente registren una whitelist de redirect_uris válidos y siempre que sea posible, utilizar una comparación estricta byte por byte para validar la URI en las solicitudes entrantes. También sería conveniente permitir solo coincidencias completas y exactas en lugar de usar coincidencias por patrones, lo cual evitaría que los atacantes accedan a otras páginas en los dominios de la whitelist

  • Obligar el uso del parámetro state y vincular su valor a la sesión del usuario, incluyendo datos impredecibles y específicos de la sesión, como un hash que contenga la cookie de sesión. Esto ayuda a proteger a los usuarios contra ataques similares a CSRF. Además, dificulta significativamente que un atacante pueda utilizar códigos de autorización robados

  • En el servidor de recursos, asegurarse de verificar que el token de acceso fue emitido para el mismo client_id que realiza la solicitud y verificar el scope solicitado para confirmar que coincide con el scope para el cual se emitió originalmente el token

Para aplicaciones cliente OAuth se deberían implementar estas medidas

  • Comprender completamente cómo funciona OAuth antes de implementarlo. Hay situaciones en las que surgen vulnerabilidades debido a un desconocimiento de lo que ocurre en cada etapa y cómo podría ser explotado

  • Utilizar el parámetro state aunque no sea obligatorio

  • Enviar el parámetro redirect_uri no solo al endpoint /authorization, sino también al endpoint /token

  • En aplicaciones móviles o de escritorio nativas a menudo no es posible mantener el client_secret en secreto. En estos casos, se puede usar el mecanismo PKCE (RFC 7636) para añadir protección contra la interceptación o filtración de códigos de acceso

  • Si usas el id_token de OpenID Connect, valídalo correctamente según las especificaciones de JSON Web Signature (JWS), JSON Web Encryption (JWE) y OpenID

  • Tener cuidado con los códigos de autorización, ya que pueden filtrarse a través de cabeceras Referer cuando se cargan imágenes, scripts o CSS externos. También es importante no incluirlos en archivos JavaScript generados dinámicamente, ya que podrían ejecutarse desde dominios externos mediante etiquetas <script>

Esta entrada está licenciada bajo CC BY 4.0 por el autor.