En los últimos años, el auge del uso de las APIs y el interés por parte de las empresas en incorporar plataformas API Management han dado como resultado un aumento considerable en el volumen de información que se maneja a través de las ellas y, por tanto, un aumento en sus ataques.

Exponer una API supone ofrecer una puerta de acceso a los datos y a la propia organización, entonces, ¿por qué se siguen dejando APIs desprotegidas? Algunas de las típicas respuestas son: "esta API solo la usamos nosotros" ,"no merece la pena protegerla," o "si nadie sabe que existe, no la van a encontrar. Estos argumentos (o, mejor dicho, excusas) se caen por su propio peso. Gartner estima que durante el año 2022 las APIs serán el vector de ataque más frecuente, por lo que resulta clave poner foco en este ámbito.

La estrategia de securización de APIs debe encontrar el equilibrio entre la seguridad y la usabilidad. Una estrategia demasiado compleja disuade a usuarios malintencionados, pero también obstaculiza su uso por parte de usuarios legítimos.

El uso de estándares ayuda a conseguir ese equilibrio, ya que son suficientemente complejos como para disuadir a usuarios maliciosos y, proporcionando la información correcta, permiten el acceso a usuarios autorizados.

Cualquiera que sea la decisión respecto a la seguridad de las APIs en una organización, se debe poner foco en los siguientes aspectos:

No solo el acceso a las APIs necesita control, también encontramos el inconveniente del intercambio de contraseñas. Surge, además, el problema de la delegación de la autorización para acceder a los datos.

OAuth es un estándar que surge como respuesta a esas necesidades. Es un framework de autorización que se ha convertido en el estándar de facto en el uso de APIs. Permite a las aplicaciones un acceso limitado (scopes) a los datos de los usuarios, sin tener que proporcionar las credenciales de dicho usuario, desacoplando la autenticación y la autorización a los datos.

Da soporte a diferentes escenarios de negocio dependiendo del tipo de consumidor que accede a los datos que expone la API: aplicaciones servidor, navegadores, dispositivos IOT, aplicaciones móviles o nativas, etc.

De una manera simplificada, el uso de OAuth es análogo al uso de una tarjeta de acceso a un hotel.

Para obtener la tarjeta de acceso, el primer paso es pasar un proceso de autenticación tras el cual te dan la tarjeta (un access token), posteriormente puedes usar la tarjeta para acceder a los distintos partes del hotel (recursos de la API) a las cuales se tiene permiso para acceder o no dependiendo de la autenticación.

¿Qué es y qué no es OAuth 2.0?

Autenticación vs autorización

Con frecuencia, cuando se habla de seguridad y de OAuth, los conceptos de autenticación y autorización se solapan y son completamente diferentes:

Atendiendo a esos conceptos, OAuth es un framework que permite delegar la autorización de acceso a las APIs, NO es un protocolo de autenticación. Este matiz incluso lo informan en su documentación.

En todo el proceso de uso de este framework no se indica nada sobre la autenticación del cliente, ni información relacionada con él, sólo se habla de la obtención de un token para acceder a un recurso.

Normalmente, en el proceso de autenticación de un usuario hay información de quién es ese usuario, cuándo se autentico y cómo se realizó este proceso de autenticación. Toda esta información no es accesible ni gestionable mediante OAuth, no hay información "útil" del usuario ya que los tokens son opacos y no contienen información sobre la identidad del usuario.

Hay que destacar que importantes empresas como son Facebook y Twitter emplean OAuth, no solo para la autorización, sino como pseudoautenticación habilitando un recurso/me que mediante un token de acceso ofrece información básica de dicho usuario.

Pero también hay que recalcar que en todo el estándar no se requiere la implementación de este recurso en absoluto.

¿Qué diferencia OAuth de JWT?

Lo más importante es comprender que ni son comparables ni son excluyentes:

¿Qué relación tiene OAuth con OpenId Connect?

OpenId es un es un estándar abierto que permite autenticar usuarios mediante peticiones HTTP en formato JSON.

OpenId Connect es un protocolo de autenticación de usuarios que se basa en OpenId y extiende OAuth 2.0 dotándolo de una capa de autenticación de usuarios sin que estos últimos tengan que almacenar y gestionar las contraseñas.

Su framework estandariza la comunicación entre un proveedor de identidades (IDPs) de OpenId y un tercero. Su funcionamiento es muy sencillo: un usuario obtiene una cuenta a través de un proveedor de identidades de OpenID, por ejemplo Google, y el usuario puede usar esa cuenta para acceder a cualquier web (tercero) que acepte la autenticación OpenId, por ejemplo Youtube sería un tercero que acepta la cuenta de Google como login.

Entonces, ¿siempre hay que usar OAuth en el mundo de las APIs?

No siempre, es el método más extendido y el recomendado para la mayoría de casuísticas, pero existen otros métodos de seguridad que son más apropiados en ciertos escenarios de negocio siguiendo el concepto de equilibrio de usabilidad y seguridad que se comentaba al principio.

¿Qué protocolos hay que utilizar?

API Keys

Una API Key es una pieza de código, normalmente una cadena larga de caracteres, que se asigna a un consumidor de una API cuyo valor es único y es utilizada por parte de ese consumidor en cada una de las solicitudes a la API.

Normalmente, en el momento en que un consumidor se registra se generan estas claves que le permiten operar de un modo similar al uso de un usuario y una contraseña de acceso.

Debido a que el valor de una API Key es único, es frecuente utilizar estas claves como método de autenticación de los usuarios.

La ventajas del uso de este tipo de claves son:

Pero este método también tiene sus desventajas y es el menos seguro de los que se recomiendan debido a:

Los casos de uso donde este método sería una opción a considerar son aquellos con comunicaciones de tipo servidor-servidor alojados dentro de infraestructura de la propia organización y si es posible solo para funcionalidades consultivas.

OAuth 2.0

Como se ha explicado previamente OAuth 2.0 es un framework de autorización que permite controlar el acceso por parte de las aplicaciones a los datos de los usuarios sin tener que proporcionar las credenciales.

Como ventajas del uso de este framework se pueden citar:

Es la opción de securización de APIs por defecto en la mayoría de los casos. Es necesario definir en función de la aplicación y datos expuestos qué tipo de flujo de autorización es necesario para proporcionar el token de acceso a los datos por parte de la aplicación.

OpenId Connect

Como se explicó previamente, OpenID Connect es una extensión de OAuth por lo que tiene todas las ventajas citadas anteriormente.

Las ventajas principales de su uso son:

El principal caso de uso de este tipo de seguridad es proporcionar a los usuarios la posibilidad de autenticarse a través de diferentes(proveedores de identidades (IDPs).

¿Qué método elijo: API Key, OAuth 2.0 u OpenId Connect?

¿Qué no hay que utilizar para securizar nuestras APIs?

¿Cuáles son los flujos de OAuth y cuándo los uso?

Conceptos: scopes, tokens y actores

El primer paso para comprender los flujos de OAuth y los escenarios de aplicación de cada uno de ellos es comprender algunos conceptos previos como son: los actores que intervienen en los flujos, qué son los tokens y los scopes de acceso.

Los actores que intervienen en todos los flujos OAuth son:

Los scopes son una lista de identificadores separados por espacios que se utilizan en el proceso de autorización y consentimiento de las APIs en los tokens OAuth, que permiten determinar a qué se solicita acceso por parte de la aplicación y a qué se autoriza acceder por parte del usuario. Por ejemplo: a las fotos, mensajes de usuarios. etc,

Los tokens e identificadores que se manejan dentro de OAuth son:

Flujos o grant types

Los flujos de OAuth también denominados grant types hacen referencia al modo en que una aplicación obtiene un access token que le permite acceder a los datos expuestos a través de una API.

La existencia de estos flujos por parte del estándar surge para dar respuesta a todos los escenarios de negocio que se pueden presentar en el consumo de las APIs atendiendo a tres variables:

Client credentials grant type

Este flujo representa el caso en el que la aplicación pertenece al usuario, por lo que no hay necesidad de que éste se autentique ni ayude de forma alguna al servidor de autenticación a decidir si el acceso para esa aplicación está garantizado, es decir, el access token que envía el servidor se obtiene autenticando sólo a la aplicación, no al usuario.

La principal diferencia con el resto del flujos es que el usuario no interactúa en el proceso, por lo que la aplicación no puede actuar en nombre del usuario, solo en nombre propio.

¿Cómo funciona?

  1. La aplicación envía sus credenciales al servidor de autenticación.
  2. El servidor de autenticación comprueba que los datos enviados por la aplicación en la solicitud pertenecen a la aplicación del usuario y, en caso de ser así, le remite el access token.

El siguiente es un diagrama simplificado del flujo Client Credentials y debajo, en este caso idéntico, el diagrama de la documentación de OAuth.

¿Cuándo se utiliza?

Resource Owner Password grant type

Este flujo se caracteriza por la intervención por parte del usuario proporcionando su usuario y contraseña en la aplicación cliente, no en el servidor de autenticación. Esta situación implica que los dueños del recurso deben confiar plenamente en la aplicación para introducir sus credenciales.

Por ejemplo, en Spotify te solicitan para iniciar sesión las credenciales de Facebook directamente en su aplicación. Si no fuera una aplicación confiable los usuario no pondrían sus datos. Spotify es suficientemente confiable y garantiza que ni guarda ni modifica la contraseña de Facebook.

Pero, ¿no se supone que el hecho de proporcionar las contraseñas era lo que OAuth pretendía evitar? Cierto, pero el uso de este flujo aprovecha el resto de beneficios de OAuth como son el uso de access tokens con una vida útil limitada.

Por ejemplo, si tenemos una aplicación móvil en lugar de almacenar el usuario y contraseña del usuario, la aplicación solicita los datos en el momento de la instalación, de forma posterior solo tiene que hacer uso del access token.

¿Cómo funciona?

El siguiente es un diagrama simplificado del flujo Resource Owner Password Credentials, el diagrama de la documentación de OAuth.

¿Cuándo se utiliza?

Teniendo en cuenta que en este flujo el usuario debe utilizar sus credenciales de forma directa, pero no tiene el control sobre qué uso se va a hacer con ellas, se desaconseja su utilización en la medida de lo posible. Los principales riesgos de este tipo de flujo es que esta solución puede fomentar los malos hábitos de los usuarios al introducir sus credenciales en diferentes aplicaciones y aumentar los ataques de phishing.

Puede verse el detalle de todos estos problemas en la RFC 6819.

Authorization code grant type

Este flujo se caracteriza por la intervención del usuario para autorizar de forma explícita el acceso a sus datos por parte de la aplicación y por el uso de un código proporcionado por el servidor de autenticación para que la aplicación pueda obtener un access token.

¿Cómo funciona?

  1. La aplicación solicita al usuario el consentimiento expreso para acceder a los datos abriendo un navegador al usuario donde explicita los scopes a los que quiere acceder.
  2. El usuario ve a través de la pantalla de autorización del navegador al que se solicita permiso por parte de la aplicación y envía la aprobación del acceso al servidor.
  3. El servidor da al usuario un código de acceso que mediante una redirección llega a la aplicación.
  4. La aplicación solicita acceso al servidor de autenticación enviándole el código obtenido en el paso previo y los datos propios de la aplicación.
  5. Finalmente, el servidor da a la aplicación el access token y el refresh token si aplica.

El siguiente es un diagrama simplificado del flujo Authorization Code y el diagrama correspondiente de la documentación de OAuth.

¿Cuándo se utiliza?

Implicit grant type

Este flujo es una simplificación del flujo de Authorization Code, el usuario también interviene directamente para dar su consentimiento explícito, pero no se hace uso de un código, sino que se utiliza el access token directamente.

Recibe el nombre de implícito porque toda la comunicación reside en el navegador, es decir, no hay un servidor backend.

¿Cómo funciona?

  1. La aplicación solicita al usuario el consentimiento expreso para acceder a los datos abriendo un navegador al usuario donde explicita los scopes a los que quiere acceder.
  2. El usuario ve a través de la pantalla de autorización del navegador a qué se solicita permiso por parte de la aplicación y envía la aprobación.
  3. El usuario es redirigido con un access token a la aplicación.

El siguiente es un diagrama simplificado del flujo Implicit y debajo el diagrama de la documentación de OAuth.

¿Cuándo se utiliza?

Se trata del flujo de OAuth menos seguro, de forma que su utilización debe limitarse a casos muy concretos e idealmente evitarse. Los principales problemas que presenta son:

Todo esto se traduce en una serie de riesgos que son difícilmente mitigables:

Puede verse el detalle de todos estos problemas en la RFC 6819.

Debido a estos potenciales riesgos de seguridad y a que su uso más generalizado es a través de SPAs, se está trabajando en un nuevo estándar que dé más garantías a través de una RFC específica para aplicaciones basadas en navegador en la que se consideran aplicaciones que tienen backend o no y cómo resolver la obtención del token en cada caso.

¿Qué flujo uso?

Como resumen, conviene tener algunas ideas claras de las partes involucradas en cada flujo:

Teniendo en cuenta lo anterior y las características de cada grant type, el siguiente diagrama de decisión pretende ayudar en la toma de decisión de qué método es el más adecuado para exponer una API en base al tipo de aplicación consumidora.

El diagrama no tiene porqué seguirse al pie de la letra simplemente son consejos, ya que habría que ver cada caso:

Casos de uso y conclusiones

Una parte fundamental del uso y consumo de las APIs es la seguridad y OAuth se ha convertido en en el framework de referencia para autorizar el acceso a las APIs, pero no es el único método, aunque sí el más extendido.

Las API Keys pueden utilizarse para casos específicos en los que la comunicación sea interna a la organización dueña de los datos que se exponen en la API y preferiblemente para operaciones consultivas.

Si se quiere incorporar una capa de autenticación y además hacerlo a través de diferentes IDPs, el método a utilizar es OpenId Connect.

OAuth, por su parte, se convierte en el método por defecto para autorizar el acceso a las APIs y es necesario conocer a fondo para identificar en qué casos utilizar cada flujo. Si se selecciona un grant type inadecuado, los atacantes pueden aprovechar esas vulnerabilidades de seguridad y crear problemas. Un ejemplo claro es utilizar en una aplicación alojada en el cliente una API expuesta mediante Client Credentials. El atacante puede obtener las credenciales simplemente inspeccionando el código fuente y suplantar la aplicación autorizada.

Desde la perspectiva de la aplicación consumidora, teniendo en cuenta dónde reside, su tipología y el grado de confianza, vemos algunos consejos para decidir qué utilizar del grant type:

Referencias

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.