Saltar al contenido principal

OAuth PKCE - Autorización segura para clientes públicos

Lectura de 2 min aprox.

PKCE (Proof Key for Code Exchange, pronunciado «pixy») es una extensión de seguridad añadida al flujo de código de autorización de OAuth 2.0. Se estandarizó como RFC 7636 en 2015. Diseñado originalmente para clientes públicos como las aplicaciones móviles que no pueden almacenar de forma segura un client_secret, su eficacia ha llevado a que OAuth 2.1 avance hacia hacerlo obligatorio para todos los tipos de cliente.

Qué es un ataque de interceptación de código de autorización

Para entender la amenaza que PKCE resuelve, primero hay que conocer cómo funciona el ataque. En el flujo de código de autorización de OAuth 2.0, después de que el usuario inicia sesión en el servidor de autorización, el código de autorización se devuelve al cliente a través de la URI de redirección. En los sistemas operativos móviles, la redirección usa esquemas de URL personalizados (p. ej., myapp://), pero si una aplicación maliciosa registra el mismo esquema de URL, puede interceptar el código de autorización.

La app legítima envía la solicitud de autorización
El usuario inicia sesión y da su consentimiento
La app maliciosa intercepta el código de autorización
Obtiene tokens con el código interceptado

Las SPA (aplicaciones de una sola página) presentan un riesgo similar, porque el código de autorización puede filtrarse a través del historial del navegador, la cabecera de referente o las extensiones del navegador.

Cómo funcionan code_verifier y code_challenge

PKCE garantiza criptográficamente que «solo la parte que envió la solicitud de autorización puede obtener el token». El mecanismo es simple y utiliza dos valores.

ElementoCuándo se generaFunción
code_verifierGenerado por el cliente antes de la solicitud de autorizaciónUna cadena aleatoria de 43-128 caracteres. Un secreto que solo el cliente conserva
code_challengeDerivado de code_verifierLa codificación Base64URL del hash SHA-256. Se incluye en la solicitud de autorización
Generar y guardar code_verifier
Adjuntar code_challenge a la solicitud de autorización
Recibir el código de autorización
Solicitar el token con code_verifier + código de autorización
El servidor verifica → emite el token

Aunque un atacante intercepte el código de autorización, no puede obtener un token sin el code_verifier. Como code_verifier no se puede deducir a la inversa a partir de code_challenge (la propiedad unidireccional de SHA-256), interceptar la solicitud de autorización no sirve de nada.

Por qué es necesario para los clientes públicos

En el OAuth 2.0 tradicional, los clientes confidenciales (aplicaciones del lado del servidor) podían proteger el endpoint de tokens con un client_secret. Sin embargo, como el código fuente de las SPA y las aplicaciones móviles está en manos del usuario, no se puede incrustar un client_secret de forma segura. PKCE resuelve este problema y permite demostrar al propietario legítimo de un código de autorización incluso sin un client_secret.

PKCE también es eficaz como medida contra el CSRF. A diferencia del parámetro state, PKCE realiza una verificación criptográfica, lo que ofrece una protección más robusta. Combinarlo con la gestión de los tokens de sesión mejora la seguridad de todo el flujo de autenticación.

Su obligatoriedad en OAuth 2.1

En OAuth 2.1 (en borrador a fecha de 2025), PKCE pasa a ser obligatorio para todos los tipos de cliente. Incluso los clientes confidenciales deben usar PKCE. Esto se basa en la idea de la «defensa en profundidad» (defensa por capas). Aunque se filtre un client_secret, PKCE puede seguir evitando la interceptación del código de autorización. Cuando se usa OpenID Connect, también se recomienda encarecidamente combinarlo con PKCE.

Errores de implementación comunes

  • Usar plain como code_challenge_method. Como plain envía el propio code_verifier como code_challenge, no sirve de nada si se intercepta. Usa siempre S256 (SHA-256)
  • Guardar el code_verifier en el almacenamiento local en lugar del almacenamiento de sesión. Esto aumenta el riesgo de que lo lea un ataque XSS
  • Entropía insuficiente en el code_verifier. Usa un generador de números aleatorios criptográficamente seguro (getRandomValues de la Web Crypto API)

Leer también los artículos sobre las trampas de los permisos de OAuth y la gestión de claves de API te dará una imagen más clara del diseño de seguridad de todo el flujo de autorización. Saber cuándo usar en su lugar una clave de API también es un punto de decisión importante en la práctica.libros sobre seguridad de OAuth (Amazon) también son recomendables para un aprendizaje sistemático.

Términos relacionados

¿Te resultó útil este artículo?

XHatena