Entendiendo ASP.NET Core DataProtection

Entendiendo ASP.NET Core DataProtection


Si construyes aplicaciones web, sitios web o sistemas web basados en ASP .NET/ ASP .NET Core, estás utilizando ASP .NET Core DataProtection, ya sea que lo hagas de forma consciente o inconsciente. Toda aplicación que implemente Razor Pages, las clásicas Web Apps MVC o incluso Blazor Server, usa DataProtection. En este punto puede que te estés preguntando: ¿Qué es DataProtection? DataProtection es una API o pila criptográfica simétrica que sirve para “proteger datos o información”.

Para llevarlo al escenario de la web, un ejemplo clásico de esos datos o información que se quiere proteger sería: “Necesito proteger un estado de ida y vuelta para interactuar con un cliente que no es de mi confianza”. ¿Cuál es ese cliente? El navegador web. ¿Cuál es ese estado? Una cookie segura que maneja datos “sensibles”. Aquí es donde entra DataProtection, ya que un sitio ASP .NET, en su mayoría de usos, genera cookies y usa DataProtection para cifrar el payload de la cookie y para firmar la cookie. De esta manera protege los datos y se asegura de que en las futuras peticiones esa cookie no sea alterada o falsificada.

La filosofía de diseño del API de DataProtection está enfocada en los siguientes principios:

  • Fácil configuración: Como se dijo, el framework lo “agrega” por defecto, y en los casos donde hay que cambiar algo (como el repositorio de claves), esto se puede hacer fácilmente.
  • Orientada al consumidor: En el sentido de que es fácil de usar correctamente y difícil de usar incorrectamente. Por ello abstrae los temas relacionados al cifrado, como la elección de los algoritmos de cifrado y la rotación de claves.
  • Está diseñada para protección de datos temporales como una cookie u otro tipo de dato temporal. Se podría usar para proteger datos a largo plazo, pero se necesitará ahondar en la extensión de la API, como la gestión de claves y algoritmos de cifrado.

Con todo lo mencionado anteriormente, se puede decir que ASP.NET usa DataProtection para:

  • La autenticación basada en cookies y/o tokens firmados.
  • La mitigación de ataques CSRF, ya que métodos como ValidateAntiForgeryToken hacen la comprobación de los tokens usando DataProtection.

DataProtection y el escalado horizontal

Si bien DataProtection y ASP .NET te dan todos esos beneficios relacionados a la seguridad “de caja”, he notado que muchas soluciones tienen problemas al momento de escalar de forma horizontal. La aplicación funciona correctamente dentro de un solo servidor, por ejemplo IIS con el módulo AspNetCore. Pero cuando este mismo código quiere ser llevado a un App Service con escalado horizontal o incluso en contenedores con AKS, hay muchas peticiones que fallan. Esto se debe a que por defecto ASP .NET DataProtection genera claves automáticamente en memoria. Esto quiere decir que en cada nodo se están generando claves diferentes. Entonces, las cookies generadas en el “nodo A” no podrán ser validadas en el “nodo B”, ya que no fueron generadas con la misma clave.

Para solucionar este problema de DataProtection y el escalado horizontal, es tan simple como configurar un “repositorio central de la clave”. Este repositorio puede ser Azure Blob Storage, un directorio compartido o incluso una base de datos. De esta manera, todos los nodos recuperarán la misma clave y podrán generar y descifrar cookies válidas para todos los nodos. DataProtection se encargará tras bambalinas de renovar esta clave (por defecto es cada 90 días, pero se puede cambiar este periodo).

Aunque este problema pueda parecer obvio, muchos equipos, por desconocer DataProtection, terminan haciendo maniobras “raras” para poder escalar su aplicación, cambian el modelo de gestión de sesiones e incluso incluyen componentes como Redis.


DataProtection y la seguridad web

Si bien vemos que ASP .NET usa DataProtection para la seguridad web, como el cifrado, firma de cookies y mitigación contra CSRF, la seguridad web no está garantizada solo por DataProtection y no te libra de la responsabilidad por las preocupaciones que eso conlleva. Incluso con DataProtection debes considerar cosas como:

  • Configuración de cookies seguras HttpOnly, de esa manera evitas que se robe la cookie por JavaScript y XSS.
  • Cifrado en tránsito: esto solo se garantiza con HTTPS/TLS.
  • Encabezados CSP (Content-Security-Policy) para fortalecer la protección anti-XSS.
  • Como se entiende, DataProtection genera una clave para el cifrado simétrico, para la protección de esa clave se puede usar Azure Key Vault. De esta manera la clave almacenada en el repositorio es un valor cifrado que si es robado no se puede usar. ASP .NET permite configurara esto de forma muy sencilla e implementar “envelope encryption” de la clave.

DataProtection y el desarrollo web “moderno”

El desarrollo web moderno con frameworks como React, Angular, Svelte, entre otros, está basado en la construcción de SPAs/MPAs que consumen APIs REST o GraphQL. Para consumir estas APIs, la aplicación acude a la obtención de tokens de acceso que servirán para poder autenticarse ante estas APIs. En este enfoque, DataProtection no pinta nada, ya que los tokens suelen ser generados por proveedores OAuth2.

Este enfoque tiene una debilidad: es vulnerable a ataques XSS que pueden “robar” los tokens de acceso o token de refresh que muchas veces son almacenados en localStorage y sessionStorage del browser. Obviamente, todo depende de tu propio caso de uso y puede que para tu situación esta debilidad no represente mayor riesgo, pero en situaciones más estrictas y delicadas se puede fortalecer la implementación.

Una implementación interesante es combinar las capacidades de DataProtection para generar cookies seguras y la generación de tokens de acceso para las APIs de una aplicación React, por ejemplo. En ASP .NET esto se puede lograr implementando un BFF (backend para el frontend) con un proxy YARP, que sirva el contenido estático de React junto con la cookie HttpOnly segura. Luego, en el mismo dominio del BFF se redirige a las APIs, para que de esta manera el navegador las envíe automáticamente. De esta manera, se puede proteger los endpoints de las APIs con validaciones AntiForgery y CSRF con esa cookie.

Para asegurar la generación de tokens de acceso, se colocaría el token de refresh en la cookie segura y el BFF pediría tokens de acceso al OAuth2 provider sin que estos tokens lleguen al browser. De esta manera ya no se guardan tokens ni en localStorage, ni en sessionStorage.


Para cerrar, dejo un enlace a un repositorio de ejemplo que muestra cómo agregar DataProtection a un clásico sitio Web MVC con ASP .NET y cómo configurar el repositorio de claves con Azure Blob Storage y proteger la clave con Azure Key Vault Envelope encription.

Repositorio de ejemplo ASP.NET DataProtection con .NET 9

Además, un pequeño diagrama que busca explicar este concepto:

DataProtection en .NET con BFF que gestiona autenticación y no expone tokens al browser


Conclusión

DataProtection es un concepto bastante interesante en términos de seguridad y criptografía. Es importante tenerlo en cuenta para el escalado de un sitio web basado en ASP .NET y autenticación por cookies.


Sígueme en Linkedin para estar al tanto de mis publicaciones y novedades

Referencias