¿Qué es PKCE: de los conceptos básicos a la comprensión profunda
Este artículo explica cómo PKCE (Proof Key for Code Exchange) asegura el flujo de código de autorización de OAuth 2.0 al prevenir que aplicaciones maliciosas intercepten códigos de autorización, llevándote desde conceptos básicos hasta una comprensión completa.
Proof Key for Code Exchange (PKCE) es una extensión del flujo de Código de Autorización, originalmente fue diseñado para asegurar el flujo de código de autorización en aplicaciones móviles, y ahora se recomienda su uso en aplicaciones de una sola página también. A partir de OAuth 2.1, PKCE es obligatorio para todos los tipos de clientes, incluyendo clientes públicos y clientes confidenciales (privados).
En este artículo, te ayudaremos a entender por qué se creó PKCE y cómo protege tus aplicaciones, brindándote una comprensión profunda de PKCE.
¿Por qué se necesita PKCE?
En el flujo de código de autorización de OAuth 2.0, los usuarios solicitan iniciar sesión a través de una aplicación. El servidor de autenticación dirige a los usuarios a una página de autenticación. Tras la autenticación del usuario, el servidor devuelve un código de autorización a la aplicación, que luego usa este código para solicitar un token de acceso del servidor de autenticación.
Este flujo tiene un riesgo significativo de seguridad: el código de autorización puede ser interceptado por programas maliciosos. Esto es particularmente preocupante en dispositivos móviles, donde otras aplicaciones pueden registrar el mismo URI de redirección e interceptar el código de autorización.
El proceso de interceptación se muestra en el siguiente diagrama:
Paso (1): La aplicación realiza una solicitud de autenticación a través de una API segura que no puede ser interceptada. En este paso, el solicitante también proporciona un URI de redirección.
Paso (2): La solicitud luego se reenvía al servidor de autorización de OAuth 2.0. Debido a que OAuth requiere el uso de TLS, esta comunicación está protegida por TLS y no puede ser interceptada.
Paso (3): El servidor de autorización devuelve el código de autorización.
Paso (4.a): el código de autorización se devuelve al solicitante a través del URI de redirección que se proporcionó en el paso (1). En este paso, si la aplicación maliciosa se ha registrado como un manejador para el URI de redirección, entonces la aplicación maliciosa puede interceptar el código de autorización. Con el código de autorización, el atacante puede solicitar y obtener un token de acceso en los pasos (5.a) y (6.a), respectivamente.
Como se muestra arriba, en el flujo de código de autorización de OAuth 2.0, si se intercepta el código de autorización, los atacantes pueden usarlo para obtener tokens de acceso. Por lo tanto, necesitamos un mecanismo para prevenir la interceptación del código de autorización, lo que llevó a la creación de PKCE.
¿Cómo funciona PKCE?
Como se mencionó anteriormente, si queremos prevenir ser atacados, necesitamos asegurarnos de que solo la aplicación que inició la solicitud pueda solicitar y obtener el token de acceso. Aquí es donde PKCE entra en juego.
PKCE resuelve este problema introduciendo un concepto de "llave de prueba".
Al solicitar un código de autorización, la aplicación primero genera un verificador de código al azar y lo almacena localmente. Luego convierte este verificador de código en un desafío de código utilizando algoritmos específicos. La aplicación envía tanto el desafío de código como el método de desafío de código al servidor de autenticación durante la solicitud del código de autorización.
El verificador de código es una cadena generada aleatoriamente, y el desafío de código se deriva del verificador de código a través de una conversión. Se apoyan dos métodos de conversión:
plain
: Usa el verificador de código directamente como el desafío de código
S256
: Aplica hashing SHA-256 al verificador de código, seguido de codificación Base64URL. Dado que la salida del hash no puede ser revertida para obtener el verificador de código, y porque el métodoplain
podría ser vulnerable a ataques de intermediarios durante la transmisión, se recomienda encarecidamente usarS256
por razones de seguridad.
Después de la autenticación del usuario, el servidor de autenticación devuelve el código de autorización a la aplicación. Al solicitar un token de acceso, la aplicación envía tanto el código de autorización como el verificador de código al servidor de autenticación. El servidor transforma el "verificador de código" usando el "método de desafío de código" recibido previamente y compara el resultado con el "desafío de código" recibido previamente para verificar la posesión del cliente del "verificador de código".
Paso (1-3): La aplicación crea y registra un secreto llamado "verificador de código" y deriva una versión transformada "desafío de código", que se envía en la Solicitud de Autorización de OAuth 2.0 junto con el método de transformación "método de desafío de código".
Paso (3-6): El Servidor de Autorización responde como de costumbre pero registra "desafío de código" y el "método de desafío de código".
Paso (7.a): La aplicación luego envía el código de autorización al punto de token como de costumbre, pero incluye el secreto "verificador de código" generado en el paso (1).
Paso (8.a-9.a): El servidor de autorización transforma "verificador de código" en "desafío de código" y lo compara con "desafío de código" del paso (1-3). Se niega el acceso si no son iguales.
En este caso, aunque la aplicación maliciosa haya interceptado el código de autorización en el paso (6.b), no puede canjearlo por un token de acceso, ya que no posee el secreto "verificador_de_código", y porque el "verificador de código" se envía a través de TLS, no puede ser interceptado.
Resumen
Este artículo explica cómo funciona PKCE y por qué es necesario para proteger el flujo de código de autorización. Al agregar un mecanismo de llave de prueba, PKCE evita que aplicaciones maliciosas intercepten y usen indebidamente códigos de autorización. Espero que esta explicación te ayude a entender PKCE en profundidad.