5

Apuntes del Curso de Autenticación con Passport.js

<h1>Curso de Autenticación con Passport.js</h1> <h3>Stack de seguridad moderno</h3>
  • JSON Web Tokens: Son un estándar qué nos permite comunicarnos entre dos clientes de una manera más seguro.
  • OAuth 2.0: Es un estándar de la industria qué permite implementar autorización.
  • OpenID Connect: Es una capa de autenticación qué funciona por encima de OAuth 2.0.
<h3>¿Qué es la autenticación?</h3>

La autenticación es la acción de verificar la identidad de un usuario, es decir, si ese usuario existe y es válido.

<h3>¿Qué es la autorización?</h3>

La autorización es la acción de otorgar permisos de manera limitada a nuestros recursos.

<h3>¿Qué son las sesiones?</h3>

Cuando visitas un sitio web se crea una sesión http, http no transmite información entre sí y para eso están las sesiones del navegador.

  • Cookie session: Nos permite almacenar la sesión en las cookies del navegador.
  • Express session: Nos permite almacenar la sesión en memoria del lado del servidor.
<h3>Anatomía de un JWT</h3>

Consta de 3 partes

  • Header: El cual consta de un tipo de qué en este caso siempre debería ser JWT y del algoritmo de encriptación qué utiliza la firma.
  • Payload: Es donde guardamos toda la información de nuestro usuario, se compone de clains.
  • Signature: Está compuesta por el header codificado + el payload codificado.
<h3>Autenticación tradicional vs JWT</h3>
  • Tradicional: Al abrir un navegador se crea una sesión el ID de esa sesión se almacena en las cookies, apartir de aca todos los request van con la información almacenada en la cookie.
  • JWT: Al procesar la autenticación se firma un token este token es enviado al cliente y este debe ser almacenado en memoria o en una cookie
<h3>Firmar y verificar un JWT</h3>

//Firmando
jwt.sign({ sub: user.id }, ‘secret’, options);
//Verificando
jwt.verify( token , ‘secret’, function (err, decoded){});

<h3>Sesiones del lado del servidor vs sesiones del lado del cliente</h3>
  • ¿Qué es una sesión? En términos generales una sesión es una manera de preservar un estado deseado.
  • ¿Qué es una sesión del lado del servidor? La sesión en el lado del servidor suele ser una pieza de información que se guarda en memoria o en una base de datos y esta permite hacerle seguimiento a la información de autenticación, con el fin de identificar al usuario y determinar cuál es el estado de autenticación. Mantener la sesión de esta manera en el lado del servidor es lo que se considera “stateful”, es decir que maneja un estado.
  • ¿Qué es una sesión del lado del cliente? Las SPA (Single-page apps) requieren una manera de saber si el usuario está autenticado o no. Pero esto no se puede hacer de una manera tradicional porque suelen ser muy desacopladas con el backend y no suelen refrescar la página como lo hacen las aplicaciones renderizadas en el servidor.

JWT (JSON Web Token) es un mecanismo de autenticación sin estado, lo que conocemos como “stateless”. Lo que significa que no hay una sesión que exista del lado del servidor.

La manera como se comporta la sesión del lado del cliente es:

  • Cuando el usuario hace “login” agregamos una bandera para indicar que lo está.
  • En cualquier punto de la aplicación verificamos la expiración del token.
  • Si el token expira, cambiamos el flag para indicar que no está logueado.
  • Se suele chequear cuando la ruta cambia.
  • Si el token expiró lo redireccionamos a la ruta de “login” y actualizamos el estado como “logout”.
  • Se actualiza la UI para mostrar que el usuario ha cerrado la sesión.
<h3>Buenas prácticas con JSON Web token</h3>

En los últimos años se ha criticado fuertemente el uso de JSON Web Tokens como buena práctica de seguridad. La realidad es que muchas compañías hoy en día los usan sin ningún problema siguiendo unas buenas prácticas de seguridad, que aseguran su uso sin ningún inconveniente.

A continuación listamos unos consejos que se deben tener en cuenta:

  • Evitar almacenar información sensible: Debido a que los JSON Web tokens son decodificables es posible visualizar la información del payload, por lo que ningún tipo de información sensible debe ser expuesto como contraseñas, keys, etc. Tampoco debería agregarse información confidencial del usuario como su número de identificación o información médica, ya que como hablamos anteriormente, los hackers pueden usar esta información para hacer ingeniería social.
  • Mantener su peso lo más liviano posible: Suele tenerse la tentación de guardar toda la información del perfil en el payload del JWT, pero esto no debería hacerse ya que necesitamos que el JWT sea lo más pequeño posible debido a que al enviarse con todos los request estamos consumiendo parte del ancho de banda.
  • Establecer un tiempo de expiración corto: Debido a que los tokens pueden ser robados si no se toman las medidas correctas de almacenamiento seguro, es muy importante que estos tengan unas expiración corta, el tiempo recomendado es desde 15 minutos hasta un máximo de 2 horas.
  • Tratar los JWT como tokens opacos: Aunque los tokens se pueden decodificar, deben tratarse como tokens opacos, es decir como si no tuviesen ningún valor legible. Esto es porque desde el lado del cliente no tenemos manera de verificar si la firma es correcta, así que si confiamos en la información decodificada del token, alguien podría introducir un token invalido con otra información a propósito. Lo mejor, es siempre enviar el token del lado del servidor y hacer las verificaciones allí.
<h3>¿Donde guardar los tokens?</h3>
  • Cuando estamos trabajando con SPA (Single Page apps) debemos evitar almacenar los tokens en Local Storage o Session Storage. Estos deben ser almacenados en memoria o en una Cookie, pero solo de manera segura y con el flag httpOnly, esto quiere decir que la cookie debe venir del lado del servidor con el token almacenado.

Más información: https://auth0.com/docs/security/store-tokens#single-page-apps

<h3>Silent authentication vs Refresh tokens</h3>

Debido a que es riesgoso almacenar tokens del lado del cliente, no se deberían usar Refresh Tokens cuando se trabaja solo con una SPA. Lo que se debe implementar es Silent Authentication, para ello se debe seguir el siguiente flujo:

  • La SPA obtiene un access token al hacer login o mediante cualquier flujo de OAuth.
  • Cuando el token expira el API retornara un error 401.
  • En este momento se debe detectar el error y hacer un request para obtener de nuevo un access token.
  • Si nuestro backend server tiene una sesión válida (Se puede usar una cookie) entonces respondemos con un nuevo access token.

Más información:
https://auth0.com/docs/api-auth/tutorials/silent-authentication
https://auth0.com/docs/tokens/refresh-token/current

Hay que tener en cuenta que para implementar Silent authentication y Refresh tokens, se requiere tener un tipo de sesión válida del lado del servidor por lo que en una SPA es posible que sea necesario una especie de backend-proxy, ya que la sesión no debería convivir en el lado del API server.

NOTA: En el paso 2, si se está usando alguna librería para manejo de estado como redux, se puede implementar un middleware que detecte este error y proceda con el paso 3.

<h3>¿Qué es una cookie y para qué sirve?</h3>

Una cookie es un archivo creado por un sitio web qué tiene pequeños pedazos de datos almacenados en él, su propósito principal es identificar al usuario mediante el almacenamiento de su historial.

  • Las cookies sessions: Tienen corto tiempo de vida, estas son removidas cuando se cierra el tab ó el navegador.
  • Las persistance cookies: Se usan generalmente para rastrear al usuario guardando información de su interes.
  • Las secure cookies: Almacenan datos de manera cifrada, suelen usarse en conexiones HTTPS.
<h3>Leyes sobre cookies</h3>
  • Siempre debes avisarle al usuario qué estás haciendo uso de ellas.
  • Es necesario el consentimiento del usuario para el uso de las mismas.
  • Si las cookies son necesarias para autenticación de usuario las leyes no aplican en estos casos.
<h3>Local Storage</h3>
  • Tiene un almacenamiento máximo de 5mb.
  • La información qué almacenamos aquí no va en cada request qué hacemos al servidor.
  • La información persiste aunque cerremos la ventana de nuestro navegador.
<h3>Session Storage</h3>
  • Funciona igual qué el Local Storage pero solo persiste mientras tengamos abierta esa ventana del navegador.
    La información solo se mantiene en ese tab.
<h3>Cookies</h3>
  • Tienen un almacenamiento de 4 kb.
  • Se les puede establecer un tiempo de expiración.
  • Por cada request al servidor estás van vinculadas al mismo.
  • Se pueden hacer seguras mediante el HTTPOnly el cual permite qué la información de la cookie solo sea accedida y modificada en el servidor.
<h3>¿Cuando usar uno u otro?</h3>
  • Si la información no es sensible la podemos almacenar en Local Storage o Session Storage.
  • Si la información es medianamente sensible podemos almacenarla en el Session Storage, como por ejemplo nombre de usuario.
  • Si la información es muy sensible lo más recomendado es almacenarla en una cookie con el flag HTTPOnly para seguridad.

Passport.js: Es un middleware para express que nos permite implementar estrategias de autenticación de una manera rápida y simple.

<h3>¿Que es 0Auth 2.0 y OpenID Connect?</h3>
  • OAuth 2.0 es un estándar de la industria que nos permite implementar autorización.
  • OpenID Connect es una capa de autorización que funciona sobre OAuth con métodos ya construidos.
<h3>Partes involucradas en Open Authorization</h3>
  • Resource owner: Usuario
  • Resource server: Service API, donde tenemos nuestro recurso y datos
  • Client: Application, es quien intenta acceder a los recurso en nombre del usuario
  • Authorization Server: Service API, se encarga de verificar la identidad del usuario

Helmet.Js: Es un middleware qué implementa 13 funciones middleware qué establecen códigos HTTP qué ayudar a la seguridad de nuestra aplicación.

Detección de vulnerabilidades con npm audit: corremos el comando “npm audit” el cual recorre todas nuestras dependencias y se fija si tenemos vulnerabilidades no conocidas, si este detecta vulnerabilidades nos envía un comando para ejecutar y corregir nuestra vulnerabilidades.

<h3>Automatizar el chequeo de vulnerabilidades con Snyk</h3>
  • Para usar snyk lo primero es crear una cuenta en https://app.snyk.io/signup para agilizar el proceso recomiendo usar la cuenta de GitHub.
  • Después de la creación de la cuenta nos redireccionará a las integraciones o podemos ir directamente mediante el link https://app.snyk.io/org/<usuario>/integrations.
  • Seleccionamos la integración con GitHub (ó con el servicio más adecuado para nuestro proyecto) y allí nos aseguramos de conectar nuestra cuenta con GitHub, otorgando los permisos necesarios.
  • Por último necesitamos agregar el repositorio de nuestro proyecto para que haga la revisión automática de vulnerabilidades en cada Pull request, mediante el botón Add your GitHub repositories to Snyk.
  • Allí buscaremos el repositorio de nuestro proyecto, lo seleccionamos y le damos en el botón Add 1 selected repository to Snyk.
  • Cuando termine la integración podemos dirigirnos al dashboard de nuestros proyectos haciendo click en la pestaña Projects o mediante el link https://app.snyk.io/org/<usuario></usuario>/projects y verificar el estado de nuestras dependencias.
  • En lo posible debemos evitar tener vulnerabilidades High (H) o Medium (M) para corregirlas le damos click en View report and fix.

NOTA: Tener en cuenta que algunas vulnerabilidades no tienen solución en el momento por lo que toca estar pendiente de un posible fix o cambiar de librería.

<h3>¿Qué es OWASP? y buenas prácticas de seguridad</h3>

Open Web Application Security Project: Es una organización qué se encarga de velar por las buenas prácticas de seguridad a nivel mundial, existe un documento llamado Top ten OWASP qué lista los 10 riesgos de seguridad informática más comunes.
Algunos de ellos son: Injection, broken authentication y sensitive data exposure

<h3>Buenas prácticas de seguridad</h3>
  • Usa un gestor de contraseñas
  • Usa multi-factor auth
  • IRL security
  • Mantén actualizadas tus aplicaciones y SO
  • Mantente informado
Escribe tu comentario
+ 2