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
- Elsitio web
oaplicación web
que deseaacceder
a losdatos del usuario
Propietario de los recursos
- Elusuario
que esdueño
de losdatos
a los que laaplicación cliente
quiereacceder
Proveedor de servicio OAuth
- Elsitio web
oaplicación web
quecontrola
losdatos del usuario
y elacceso a ellos
. ApoyanOAuth
proporcionando unaAPI
parainteractuar
con unservidor de autorización (gestiona la autenticación del usuario y emite tokens de acceso)
y con unservidor 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 unsubconjunto de datos del usuario
, especificando quégrant type
desea usar y quétipo de acceso
deseaobtener
Se le
solicita
alusuario
queinicie sesión
en el servicioOAuth
y dé suconsentimiento
para elacceso solicitado
La
aplicación cliente
recibe untoken de acceso
único que demuestra que tienepermiso del usuario
paraacceder
a losdatos solicitados
. Exactamente cómo ocurre esto varía significativamente según elgrant type
La
aplicación cliente
utiliza estetoken de acceso
parallamar
a laAPI
yobtener
losdatos relevantes
delservidor 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
quecontiene
elidentificador único
de laaplicación cliente
. Estevalor
segenera
cuando laaplicación cliente
seregistra
en elservicio OAuth
redirect_uri
- LaURI
a la que deberedirigirse
elnavegador del usuario
cuandoenvíe
elcódigo de autorización
a laaplicación cliente
. También se conoce comocallback URI
ocallback endpoint
. Muchosataques OAuth
se basan enexplotar fallos
en lavalidación
de esteparámetro
response_type
- Determina quétipo de respuesta espera la aplicación cliente
y por lo tanto, quéflujo desea iniciar
. Para elgrant type
deauthorization code
el valor debe sercode
scope
- Se utiliza para especificar a quésubconjunto de datos del usuario
deseaacceder
laaplicación cliente
. Tenga en cuenta que estos pueden serscopes personalizados
por elproveedor de OAuth
oscopes estandarizados
definidos por la especificaciónOpenID Connect
state
-Almacena un valor único e impredecible
que estávinculado
a lasesión actual
en laaplicación cliente
. Elservicio OAuth
debedevolver
estevalor exacto
en larespuesta
, junto con elcódigo de autorización
. Esteparámetro
funciona como una especie detoken CSRF
para laaplicación cliente
yasegura
que lasolicitud
a su endpoint/callback
provenga de lamisma 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
- Laaplicación cliente
debeautenticarse
incluyendo laclave secreta
que le fueasignada
alregistrarse
en elservicio OAuth
grant_type
- Se utiliza paraasegurar
que el nuevoendpoint
sepa quegrant type
es el que quiere usar laaplicación cliente
. En este caso, debe establecerse comoauthorization_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 laaplicación cliente
tiene elaccess token
, finalmente puedeobtener
losdatos del usuario
delservidor de recursos (API de GitHub, Google, etc que almacena los datos del usuario)
. Para hacer esto, realiza unaAPI call
al endpoint/userinfo
delservicio OAuth
. Elaccess token
seenvía
en la cabeceraAuthorization: Bearer
para demostrar que laaplicación cliente
tienepermiso
paraacceder a estos datos
1
2
3
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
Resource grant
- Elservidor de recursos
debeverificar
que eltoken
esválido
y quepertenece
a laaplicación cliente
. Si es así,enviará
elrecurso solicitado
, es decir, losdatos del usuario según el scope del token de acceso
. Finalmente, laaplicación cliente
puedeutilizar
estosdatos
para elpropósito previsto
. En el caso de laautenticación OAuth
, normalmente se usará comoID
paraconceder
alusuario
unasesión autenticada
, lo que efectivamenteiniciará 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 deiniciar sesión
con su cuenta deredes sociales
La
aplicación cliente
utiliza entonces el servicioOAuth
de lared social
parasolicitar acceso a ciertos datos
que pueda usar para identificar alusuario
, como por ejemplo, ladirección de correo electrónico
registrada en sucuenta
Después de
recibir
untoken de acceso
, laaplicación cliente
solicita estosdatos
alservidor de recursos
, normalmente desde unendpoint
dedicado, como/userinfo
Una vez
recibidos
losdatos
, laaplicación cliente
los utiliza en lugar de unnombre de usuario
para autenticar alusuario
. Eltoken de acceso
obtenido delservidor de autorización
suele emplearse en lugar de unacontraseñ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
ytokens 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 elproveedor de OAuth/OpenID Connect como Google, Facebook o tu servicio interno)
Si eres el
proveedor (el servicio de autenticación)
,el otro extremo
es elcliente (la app que consume tu OAuth)
Para los proveedores de servicios OAuth
se deberían implementar estas medidas
Requerir que las
aplicaciones cliente
registren unawhitelist de redirect_uris válidos
y siempre que sea posible, utilizar unacomparación estricta byte por byte
paravalidar
laURI
en lassolicitudes entrantes
. También sería conveniente permitir solocoincidencias completas y exactas
en lugar de usarcoincidencias por patrones
, lo cualevitaría
que losatacantes accedan a otras páginas
en losdominios
de lawhitelist
Obligar el uso del
parámetro state
yvincular
suvalor
a lasesión del usuario
, incluyendo datosimpredecibles y específicos de la sesión
, como unhash que contenga la cookie de sesión
. Esto ayuda aproteger a los usuarios contra ataques similares a CSRF
. Además,dificulta significativamente
que unatacante
pueda utilizarcódigos de autorización robados
En el
servidor de recursos
, asegurarse deverificar
que eltoken de acceso
fueemitido
para el mismoclient_id
que realiza la solicitud yverificar
elscope solicitado
paraconfirmar
quecoincide
con elscope 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 quesurgen vulnerabilidades
debido a undesconocimiento
de lo que ocurre en cadaetapa
y cómo podría serexplotado
Utilizar
elparámetro state
aunque no seaobligatorio
Enviar
el parámetroredirect_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 elclient_secret
ensecreto
. En estos casos, se puede usar el mecanismoPKCE (RFC 7636)
para añadirprotección
contra lainterceptación o filtración de códigos de acceso
Si usas el id_token de OpenID Connect
, valídalo correctamente según las especificaciones deJSON Web Signature (JWS)
,JSON Web Encryption (JWE)
yOpenID
Tener cuidado con los códigos de autorización
, ya que puedenfiltrarse
a través de cabecerasReferer
cuando secargan imágenes, scripts o CSS externos
. También es importanteno incluirlos en archivos JavaScript generados dinámicamente
, ya que podríanejecutarse desde dominios externos mediante etiquetas <script>