Ataques a OAuth 2.0 y OIDC: los fallos que regalan tu cuenta

Ataques a OAuth 2.0 y OIDC: los fallos que regalan tu cuenta

Los fallos más comunes de OAuth 2.0 y OIDC: validación débil del redirect_uri, problemas con state, ataques contra PKCE, robo y reutilización de tokens, y las medidas de seguridad modernas para prevenirlos.

Cuando una aplicación ofrece “Iniciar sesión con Google”, Microsoft u otro proveedor de identidad, normalmente hay varios protocolos trabajando por debajo. OAuth 2.0 permite delegar acceso a recursos y OpenID Connect (OIDC) añade una capa de identidad que permite a una aplicación saber quién se ha autenticado.

El resultado parece sencillo para el usuario: pulsar un botón, autenticarse y volver a la aplicación. Por debajo, sin embargo, intervienen redirecciones, códigos temporales, tokens, identificadores de cliente, estados de sesión, claves criptográficas y varias fronteras de confianza.

Un error en cualquiera de esas relaciones puede convertir un flujo legítimo de autenticación en robo de códigos, inyección de sesiones, reutilización de tokens o incluso acceso a la cuenta de otra persona. Y muchas veces el problema no está en OAuth como protocolo, sino en cómo la aplicación lo ha integrado.

En esta guía vamos a revisar los fallos que merece la pena buscar en una auditoría OAuth/OIDC, qué protege realmente PKCE, por qué state y nonce no son exactamente lo mismo, cómo se valida un ID Token y qué está cambiando con OAuth 2.1.

Nota: los dominios y flujos de los ejemplos son ilustrativos. Cualquier prueba debe realizarse únicamente sobre aplicaciones propias o sistemas para los que exista autorización.

En esta guía


OAuth y OIDC en 60 segundos

OAuth 2.0 es un framework de autorización. Permite que una aplicación obtenga acceso limitado a determinados recursos sin necesitar las credenciales del usuario.

OpenID Connect añade una capa de autenticación sobre OAuth 2.0. Es la parte que permite responder a la pregunta “¿quién es este usuario?” y proporciona, entre otras cosas, el ID Token.

En un Authorization Code Flow moderno, simplificando bastante, ocurre esto:

1. Usuario → aplicación
   "Quiero iniciar sesión"

2. Aplicación → Authorization Server
   client_id + redirect_uri + state/nonce + code_challenge...

3. Authorization Server → usuario
   autenticación + consentimiento

4. Authorization Server → redirect_uri
   authorization code

5. Aplicación → Token Endpoint
   authorization code + code_verifier

6. Token Endpoint → aplicación
   access token + ID token + opcionalmente refresh token

El navegador ve el código de autorización durante la redirección, pero el intercambio por tokens se realiza posteriormente contra el token endpoint. PKCE añade además una prueba que vincula ese código con la instancia del cliente que inició la operación.

Elemento Para qué sirve Error habitual
authorization code Credencial temporal que se intercambia por tokens. Permitir que sea interceptado, inyectado o canjeado fuera de su transacción.
access token Autoriza acceso a un Resource Server. Tratarlo como si fuera una prueba universal de identidad o aceptarlo para una audiencia incorrecta.
ID Token En OIDC contiene información verificable sobre la autenticación y el usuario. No validar firma, issuer, audience, expiración o nonce.
refresh token Permite obtener nuevos access tokens. Permitir replay indefinido si es robado.
Un access token y un ID Token no son intercambiables. El primero está destinado a autorizar llamadas a recursos; el segundo es el artefacto de identidad definido por OpenID Connect.

Fallo 1: validación insuficiente del redirect_uri

El parámetro redirect_uri determina dónde enviará el Authorization Server al navegador después de completar la autorización. En el Authorization Code Flow, esa redirección transporta normalmente el código de autorización.

Esto convierte su validación en una frontera de seguridad crítica.

El problema aparece cuando el servidor utiliza reglas flexibles en lugar de comparar la URI completa registrada: comodines, comprobaciones parciales del hostname, prefijos de cadena o expresiones mal construidas.

# URI registrada
https://app.example.com/oauth/callback

# Una validación incorrecta podría aceptar algo parecido a:
https://app.example.com.attacker.example/oauth/callback
                              ↑ el dominio real ya no es example.com

También aparecen problemas cuando se registran patrones demasiado amplios para permitir múltiples subdominios o rutas. Cuanta más lógica tenga que interpretar el Authorization Server para decidir si una redirección es válida, más posibilidades existen de introducir diferencias entre lo que pretendía el desarrollador y lo que realmente acepta el parser.

La práctica actual de seguridad recogida por RFC 9700 es clara: las redirecciones registradas deben compararse mediante coincidencia exacta de cadena, salvo la excepción específica de puertos dinámicos en determinados redirects loopback de aplicaciones nativas.

¿Y los open redirects?

Una segunda pieza interesante es encontrar una redirección abierta dentro de un dominio que participa en el flujo.

# Endpoint legítimo vulnerable a open redirect
https://app.example.com/redirect?next=https://destination.example

Dependiendo de cómo se haya configurado el cliente OAuth, del tipo de respuesta y de cómo se propaguen los parámetros o fragmentos, un open redirect puede ayudar a sacar credenciales OAuth de la ubicación donde deberían permanecer.

Por eso RFC 9700 no solo exige validar estrictamente los redirect URI: también indica que clientes y Authorization Servers no deberían exponer open redirectors que permitan enviar el navegador a destinos arbitrarios.

No asumas que pertenecer al mismo dominio convierte una URL en segura. En OAuth importa la URI registrada completa y el destino real al que terminará llegando el navegador.

Fallo 2: CSRF, state y sesiones que no quedan vinculadas

Durante un flujo OAuth existen dos operaciones diferentes que deben quedar relacionadas: la petición que inicia la aplicación y la respuesta que vuelve posteriormente al callback.

Tradicionalmente, state se utiliza para unir ambas operaciones y proteger el callback frente a CSRF.

# La aplicación inicia el flujo
state = random_value_bound_to_browser_session

# Después, en el callback
received_state == expected_state
                  ↑ la respuesta pertenece a esta transacción

Un state constante, predecible, reutilizable o no asociado correctamente a la sesión pierde buena parte de su utilidad.

Sin esta vinculación, un atacante puede intentar introducir en el navegador de otra persona una respuesta OAuth perteneciente a una transacción distinta. Dependiendo de la funcionalidad, el resultado puede ser login CSRF, vinculación incorrecta de cuentas u otras formas de confusión de sesión.

¿Entonces state es siempre obligatorio?

Aquí existe un matiz importante. Las recomendaciones actuales no dicen simplemente “siempre debe existir state”.

RFC 9700 permite que un cliente se apoye en la protección CSRF proporcionada por PKCE cuando haya comprobado que el Authorization Server realmente lo soporta y lo hace cumplir. En flujos OpenID Connect, nonce también puede proporcionar protección frente a determinadas formas de CSRF e inyección.

Si no existen esas garantías, debe utilizarse un token CSRF de un solo uso transportado mediante state y vinculado de forma segura al navegador.

Además, si state se utiliza para transportar información de aplicación —por ejemplo, la página a la que volver después del login— esa información también debe protegerse frente a manipulación.

state, nonce y PKCE están relacionados con la integridad de la transacción, pero no son simplemente tres nombres para el mismo control. Cada mecanismo protege propiedades diferentes del flujo.

Fallo 3: PKCE mal implementado y ataques de degradación

PKCE, definido originalmente en RFC 7636, nació para proteger clientes públicos frente a la interceptación del authorization code, pero las buenas prácticas actuales recomiendan utilizarlo mucho más ampliamente.

El cliente crea un code_verifier aleatorio y envía en la petición inicial una transformación de ese valor denominada code_challenge.

# Inicio del flujo
code_verifier  = random_high_entropy_value
code_challenge = BASE64URL(SHA256(code_verifier))

# Authorization request
code_challenge=...
code_challenge_method=S256

# Token request posterior
code=...
code_verifier=...

El Authorization Server conserva la relación entre el código y el challenge. Cuando posteriormente recibe el code_verifier, comprueba que corresponde con el challenge original.

El resultado es importante: robar únicamente el authorization code deja de ser suficiente para canjearlo.

El downgrade de PKCE

Un Authorization Server puede anunciar soporte para PKCE pero implementarlo de manera opcional. Eso introduce una situación delicada si la presencia de code_challenge es lo único que decide si PKCE se aplica o no.

RFC 9700 describe específicamente ataques de degradación relacionados con PKCE. Una de las inconsistencias que el servidor debe detectar es recibir posteriormente un code_verifier para una autorización que nunca tuvo asociado un code_challenge.

# Estado coherente
authorization request: code_challenge = ABC
token request:         code_verifier  = valor_que_produce_ABC
→ validar

# Estado inconsistente
authorization request: sin code_challenge
token request:         code_verifier = XYZ
→ rechazar

No basta, por tanto, con que una plataforma diga que “soporta PKCE”. Hay que comprobar que lo aplica correctamente durante toda la transacción.

Las recomendaciones actuales también utilizan S256 como método seguro para derivar el challenge. El método plain no ofrece las mismas propiedades cuando un atacante puede observar la petición de autorización.


Fallo 4: inyección y reutilización de authorization codes

PKCE también ayuda frente a otro problema: la inyección de authorization codes.

En lugar de intentar simplemente robar un código, el atacante intenta introducir un código obtenido en otra transacción dentro de la sesión legítima de la aplicación.

Sesión A
code_A ↔ challenge_A

Sesión B
code_B ↔ challenge_B

Intento de mezclar las transacciones
sesión B recibe code_A

code_verifier_B no corresponde con challenge_A → rechazo

Para que esto funcione correctamente, el code_verifier debe ser específico de cada operación y quedar vinculado a la sesión que inició el flujo.

Los authorization codes también deberían ser de vida corta, estar asociados al cliente correspondiente y ser de un solo uso. El token endpoint es una segunda frontera de seguridad: no basta con proteger correctamente el endpoint de autorización.

Durante una auditoría merece la pena observar qué ocurre cuando se intenta reutilizar un código ya canjeado, modificar el client_id, cambiar el redirect_uri durante el canje o mezclar artefactos obtenidos en sesiones diferentes.


Fallo 5: validar mal el ID Token

Cuando OpenID Connect entra en juego aparece otro artefacto: el ID Token. Normalmente es un JWT firmado que contiene información sobre el emisor, el usuario, la audiencia y el evento de autenticación.

Recibir un JWT con una estructura correcta no significa que sea válido para nuestra aplicación.

Entre las comprobaciones importantes están:

  • Firma: debe validarse criptográficamente utilizando las claves correspondientes al proveedor esperado.
  • iss: el issuer debe coincidir exactamente con el proveedor en el que confía la aplicación.
  • aud: la aplicación debe encontrarse entre las audiencias para las que fue emitido el token.
  • exp: el token no puede haber expirado.
  • nonce: cuando se ha enviado uno en la petición, debe aparecer y corresponder con la transacción iniciada.
  • azp: en determinados casos con múltiples audiencias también debe comprobarse el Authorized Party.
# Validación conceptual
verify_signature(id_token, expected_provider_keys)

assert id_token.iss == expected_issuer
assert client_id in id_token.aud
assert current_time < id_token.exp
assert id_token.nonce == expected_nonce

Uno de los errores más interesantes aparece cuando una aplicación verifica que un token tiene una firma válida pero no comprueba correctamente su audience.

Un token puede haber sido emitido correctamente por Google, Microsoft u otro proveedor y seguir sin estar destinado a nuestra aplicación. La autenticidad del emisor no sustituye a la validación del destinatario.

“El token es auténtico” y “el token es válido para mi aplicación” son comprobaciones diferentes.

UserInfo también debe relacionarse con la identidad autenticada

Si la aplicación utiliza el endpoint UserInfo de OpenID Connect, existe otra validación importante: el claim sub recibido en la respuesta de UserInfo debe coincidir exactamente con el sub del ID Token utilizado para esa sesión.

De lo contrario, la aplicación podría terminar asociando información de un usuario con la autenticación de otro.


Fallo 6: OAuth mix-up cuando existen varios proveedores

Las aplicaciones que permiten autenticarse contra varios Authorization Servers tienen una frontera adicional que a veces pasa desapercibida: recordar con qué proveedor comenzó cada transacción.

Imagina una aplicación que admite varios proveedores:

Proveedor A → accounts.identity-a.example
Proveedor B → login.identity-b.example

En un mix-up attack, el objetivo es hacer que el cliente confunda el proveedor que inició el proceso y termine enviando un código o credencial al endpoint equivocado.

RFC 9207 introdujo el parámetro iss en la respuesta OAuth precisamente para permitir que el cliente identifique explícitamente qué Authorization Server produjo la respuesta.

Cuando una aplicación interactúa con múltiples Authorization Servers debe comprobar esa identidad.

# El flujo se inició con:
expected_issuer = https://identity-a.example

# La respuesta declara:
iss = https://identity-b.example

→ abortar la transacción

Utilizar redirect URIs diferentes por proveedor puede servir como defensa alternativa en determinadas arquitecturas, pero identificar explícitamente el issuer evita depender únicamente de la estructura de las URLs.


Fallo 7: account linking basado únicamente en email

Uno de los fallos más interesantes no ocurre necesariamente dentro del protocolo, sino en la lógica que la aplicación construye encima.

Supongamos que la aplicación recibe este perfil:

{
  "iss": "https://identity.example",
  "sub": "248289761001",
  "email": "[email protected]",
  "email_verified": true
}

Una implementación rápida podría buscar una cuenta local mediante el email y, si existe, iniciar sesión automáticamente en ella o vincular la nueva identidad.

El problema es que OpenID Connect no define el email como un identificador estable ni único del usuario. Puede cambiar, puede reutilizarse y distintos issuers pueden aplicar políticas diferentes.

OIDC define como identificador estable la combinación:

(iss, sub)

https://identity.example + 248289761001

El sub identifica al sujeto dentro del contexto del issuer y está diseñado precisamente para que el Relying Party pueda diferenciar identidades de forma estable.

Si se quiere vincular una nueva identidad OAuth/OIDC a una cuenta existente, el proceso de account linking debería disponer de controles adicionales: sesión autenticada, reautenticación cuando proceda, confirmación explícita y comprobaciones de propiedad adecuadas.

email_verified=true indica que el proveedor verificó ese email según sus procedimientos. No convierte el email en un identificador universal, inmutable o exclusivo.

Fallo 8: fuga y reutilización de tokens

Incluso con un flujo OAuth correctamente construido, los tokens siguen siendo credenciales. Un access token bearer tradicional puede utilizarlo quien consiga obtenerlo mientras siga siendo válido y el Resource Server lo acepte.

Fuga mediante URLs y Referer

RFC 9700 documenta que información sensible relacionada con una respuesta OAuth puede filtrarse a través de la cabecera Referer, especialmente cuando una página que participa en el flujo carga recursos externos o dirige posteriormente al usuario hacia otra ubicación.

La página de callback debería ser especialmente austera:

  • procesar inmediatamente el authorization code;
  • evitar scripts, analítica, imágenes u otros recursos de terceros innecesarios;
  • evitar que credenciales permanezcan innecesariamente en la URL;
  • aplicar una política de referrer restrictiva cuando corresponda;
  • redirigir posteriormente a una URL limpia.

Tokens dentro del navegador

Otro error habitual es considerar localStorage una frontera de seguridad.

No lo es frente a JavaScript ejecutándose en el mismo origen. Si existe un XSS o se compromete un script que forma parte de la aplicación, ese código puede acceder a los mecanismos de almacenamiento disponibles para la propia aplicación.

RFC 10017, publicado en agosto de 2026 como Best Current Practice para aplicaciones OAuth ejecutadas en navegador, analiza específicamente estas amenazas y diferentes arquitecturas para reducir la exposición de tokens.

Una de ellas es el patrón Backend for Frontend (BFF): el backend actúa como cliente OAuth confidencial, conserva los access y refresh tokens y expone al navegador una sesión basada en cookie. De esta forma los tokens OAuth no tienen que quedar disponibles directamente para el JavaScript de la aplicación.

# Aplicación de navegador manejando tokens directamente
Browser JavaScript → access token → API

# Patrón BFF
Browser → cookie de sesión → BFF → access token → API
                              ↑ token permanece en backend

Las cookies de una arquitectura BFF deben configurarse correctamente —por ejemplo, con Secure y HttpOnly— y el backend sigue necesitando protección frente a CSRF. Cambiar tokens por cookies sin revisar el modelo de amenazas no resuelve automáticamente el problema.

Limitar el daño si el token se roba

Las buenas prácticas actuales combinan varias defensas:

  • audience restriction: el token solo debería poder utilizarse contra el Resource Server para el que fue emitido;
  • scopes mínimos: conceder únicamente los privilegios necesarios;
  • vida limitada: reducir la ventana útil de un token filtrado;
  • sender-constrained tokens: vincular el token al cliente que puede demostrar posesión de una clave.

Entre los mecanismos de sender-constraining se encuentran DPoP y los access tokens vinculados mediante mutual TLS.

Un bearer token tradicional funciona porque quien lo posee puede presentarlo. Con DPoP, además del token, el cliente debe demostrar posesión de la clave privada asociada.

Bearer token tradicional
token robado → potencialmente reutilizable

Token ligado mediante proof-of-possession
token robado + sin clave privada → replay bloqueado

Esto reduce considerablemente determinados escenarios de replay, aunque no convierte en inocuo un XSS capaz de ejecutar acciones dentro del contexto legítimo de la propia aplicación.


Refresh tokens: el objetivo de larga duración

Un access token suele tener una vida relativamente corta. Un refresh token puede permitir obtener nuevos access tokens durante mucho más tiempo, por lo que su compromiso tiene un impacto diferente.

Para clientes públicos, RFC 9700 exige mecanismos capaces de detectar o impedir el replay de refresh tokens mediante estrategias como:

  • sender-constrained refresh tokens, ligados criptográficamente a una instancia del cliente; o
  • refresh token rotation, entregando un refresh token nuevo cada vez que se utiliza el anterior.

Con rotación, el servidor mantiene suficiente información para detectar que un refresh token antiguo vuelve a aparecer.

Uso legítimo
RT1 → access token + RT2
RT1 queda invalidado

RT2 → access token + RT3

RT1 reaparece después
RT1 → token reutilizado: posible compromiso

El servidor no tiene por qué saber inicialmente si quien reutilizó el token fue el atacante o el cliente legítimo, pero puede detectar que existen dos partes intentando utilizar la misma cadena de credenciales e invalidar la autorización asociada.

La gestión de refresh tokens debe considerar además expiración, revocación, inactividad y eventos relevantes como logout o cambios importantes en la relación de autorización.


Qué cambia realmente con OAuth 2.1

Hay que hacer aquí una precisión importante: a septiembre de 2026 OAuth 2.1 todavía es un Internet-Draft del IETF y no un RFC definitivo.

La versión activa en septiembre de 2026 es draft-ietf-oauth-v2-1-16. El objetivo de OAuth 2.1 no es inventar un protocolo completamente diferente, sino consolidar en una especificación moderna muchas de las prácticas de seguridad que la comunidad ha aprendido durante años de despliegues de OAuth 2.0.

Área OAuth 2.0 original Dirección de OAuth 2.1
Authorization Code PKCE fue definido posteriormente como una extensión. PKCE forma parte del funcionamiento normal del Authorization Code Flow.
redirect_uri Las implementaciones históricas han permitido distintos comportamientos. Comparación exacta contra las URIs registradas, con excepciones específicamente definidas.
Implicit Grant Definido en OAuth 2.0. Ya no forma parte del framework.
Resource Owner Password Credentials Incluido en OAuth 2.0. Ya no forma parte del framework.
Refresh tokens en clientes públicos Menos prescriptivo. Se incorporan las protecciones modernas contra replay.

Lo importante desde pentesting es que no hace falta esperar a que OAuth 2.1 se convierta en RFC para exigir muchas de estas propiedades. RFC 9700 ya representa la Best Current Practice de seguridad para despliegues OAuth 2.0.

OAuth 2.1 reduce configuraciones históricamente problemáticas, pero no puede evitar por sí solo errores de implementación como validar mal un ID Token, confundir issuers, diseñar mal el account linking o confiar en información que no demuestra lo que la aplicación cree que demuestra.

Cómo auditar un flujo OAuth/OIDC

Una auditoría útil no debería limitarse a modificar un parámetro aislado. Primero hay que reconstruir la transacción completa y entender qué componente confía en qué otro componente.

Área Qué revisar
Redirect URI Coincidencia exacta, wildcards, subdominios, normalización, rutas y open redirects.
PKCE Uso de S256, obligatoriedad, vinculación por transacción y comportamiento ante parámetros inconsistentes.
CSRF state, nonce, PKCE y su vinculación real a la sesión que inició el flujo.
Authorization code Vida útil, un solo uso, cliente correcto e imposibilidad de inyectarlo en otra sesión.
ID Token Firma, iss, aud, exp, nonce y, cuando corresponda, azp.
UserInfo Correspondencia del sub con la identidad autenticada mediante el ID Token.
Varios proveedores Identificación del issuer y resistencia frente a mix-up.
Account linking Uso de (iss, sub), confianza en email y proceso de vinculación de nuevas identidades.
Access tokens Audience, scopes, duración, almacenamiento, logs y posibilidad de replay.
Refresh tokens Rotación, sender-constraining, expiración, revocación y detección de reutilización.
Callback Scripts externos, analítica, Referer, historial y eliminación rápida de credenciales de la URL.

También conviene analizar las peticiones sin depender de la interfaz. El navegador muestra el camino feliz, pero las propiedades realmente interesantes suelen encontrarse en las relaciones entre Authorization Server, token endpoint, callback, Resource Server y lógica interna de la aplicación.

Una pregunta especialmente útil durante toda la auditoría es:

¿Qué demuestra realmente este valor?

client_id    → identifica al cliente, pero normalmente no es un secreto

access token → concede acceso a determinados recursos

ID Token     → contiene afirmaciones de identidad para una audiencia concreta

state        → puede vincular la respuesta con la transacción del navegador

nonce        → vincula el ID Token con una autenticación iniciada previamente

PKCE         → vincula el authorization code con quien conoce el verifier

iss          → identifica al emisor que produjo la respuesta o token

sub          → identifica al sujeto dentro del contexto de un issuer

Entender esas propiedades ayuda mucho más que memorizar una lista de parámetros.


Qué significa para seguridad ofensiva

OAuth y OpenID Connect aparecen en aplicaciones web, APIs, entornos empresariales, aplicaciones móviles y arquitecturas cloud. Por eso una vulnerabilidad en estos flujos puede atravesar varias capas de una aplicación al mismo tiempo: autenticación, autorización, lógica de negocio y gestión de sesión.

Además, muchas vulnerabilidades no dependen de una carga especialmente compleja. El trabajo está en comprender qué artefacto pertenece a cada transacción, qué servidor debería aceptarlo y qué propiedades tendría que validar antes de confiar en él.

Ese razonamiento empieza con fundamentos como HTTP, sesiones, autenticación y autorización, que trabajamos en el curso Web eXploitation Junior (WXJ), y se profundiza en el curso Web eXploitation Expert (WXE), donde OAuth, OIDC, JWT, APIs, autenticación y lógica de negocio forman parte del análisis avanzado de aplicaciones web.

La diferencia entre encontrar un endpoint OAuth y encontrar una vulnerabilidad real suele estar precisamente ahí: dejar de mirar parámetros aislados y reconstruir la frontera de confianza completa.

¿Quieres aprender a auditar autenticación, APIs y lógica de negocio más allá de los fallos básicos?

En SixHack Academy puedes empezar construyendo una base sólida con Web eXploitation Junior (WXJ) y continuar con Web eXploitation Expert (WXE), donde profundizamos en autenticación moderna, JWT, OAuth/OIDC, APIs y escenarios de explotación web avanzada.


Preguntas frecuentes

¿Qué diferencia hay entre OAuth 2.0 y OpenID Connect?

OAuth 2.0 es principalmente un framework de autorización: permite que una aplicación obtenga acceso limitado a determinados recursos. OpenID Connect añade una capa de identidad sobre OAuth 2.0 y permite autenticar al usuario mediante elementos como el ID Token.

¿PKCE sustituye siempre al parámetro state?

No de forma universal. RFC 9700 permite apoyarse en PKCE como protección frente a CSRF cuando el cliente ha verificado que el Authorization Server soporta PKCE correctamente. state sigue siendo necesario en otras situaciones y continúa siendo útil para mantener estado de aplicación. En OIDC, nonce también tiene un papel importante en la vinculación de la transacción.

¿Para qué sirve PKCE?

Vincula un authorization code con un secreto efímero generado por el cliente. Aunque otra parte obtenga el código, no debería poder canjearlo sin conocer el code_verifier correspondiente. También ayuda a prevenir ataques de inyección de códigos.

¿Es inseguro guardar un access token en localStorage?

localStorage no protege un token frente a JavaScript malicioso ejecutándose en el mismo origen, por ejemplo a través de XSS o de un script comprometido. En aplicaciones sensibles pueden utilizarse arquitecturas como BFF para mantener los tokens fuera del contexto JavaScript del navegador.

¿Una cookie HttpOnly soluciona el problema?

No por sí sola. HttpOnly evita que JavaScript lea directamente la cookie, pero una aplicación que utiliza cookies necesita seguir contemplando CSRF y otros ataques donde código malicioso actúa desde el navegador de la víctima.

¿Qué campos de un ID Token debo validar?

Entre otros controles, deben verificarse su firma, el issuer (iss), la audience (aud), la expiración (exp) y, cuando corresponda, el nonce. En determinados casos también debe validarse azp. La validación exacta depende del flujo y de las características del cliente.

¿Puedo identificar un usuario OIDC únicamente por su email?

No debería utilizarse el email como identificador estable. OpenID Connect establece los Subject Identifiers mediante sub, interpretados dentro del contexto del issuer correspondiente. En la práctica, la combinación iss + sub es la referencia apropiada para identificar una identidad federada. El email puede cambiar o reutilizarse.

¿OAuth 2.1 ya ha sustituido oficialmente a OAuth 2.0?

No. A septiembre de 2026 OAuth 2.1 continúa desarrollándose como Internet-Draft del IETF. Muchas de las medidas que incorpora, sin embargo, ya representan las prácticas modernas de seguridad de OAuth y aparecen en documentos como RFC 9700.

¿Qué son los sender-constrained tokens?

Son tokens cuyo uso está ligado criptográficamente a un determinado cliente o clave. Tecnologías como DPoP y mutual TLS permiten reducir el riesgo de que un access token robado pueda reutilizarse simplemente desde otro sistema.

¿Qué es un OAuth mix-up attack?

Es una clase de ataque que afecta especialmente a clientes que trabajan con varios Authorization Servers. El objetivo es hacer que el cliente confunda qué servidor produjo una respuesta y termine utilizando códigos o credenciales contra el endpoint incorrecto. RFC 9207 define el parámetro iss como una de las principales contramedidas.

¿OAuth es solo relevante para aplicaciones web?

No. OAuth y OIDC aparecen también en aplicaciones móviles, APIs, aplicaciones de escritorio, dispositivos y entornos empresariales. El modelo de amenazas cambia según el tipo de cliente, por lo que existen recomendaciones específicas para aplicaciones nativas y aplicaciones ejecutadas en navegador.


Referencias

← Volver a Artículos