Este documento habla sobre seguridad en aplicaciones Node.js. Explica qué es OWASP y su Top 10, que lista las 10 vulnerabilidades más comunes en aplicaciones web. También cubre JWT y JWK, estándares para transmitir información de forma segura entre aplicaciones. Finalmente, incluye una implementación de JWT y JWKS en Node.js para practicar estos conceptos de seguridad.
2. Raúl Requero García
Arquitecto FullStack y Formador en Boream
CTO en MrLooquer (https://mrlooquer.com)
Twitter: @rrequero
Linkedin: www.linkedin.com/in/requerogarciaraul
4. ● Proyecto abierto de seguridad en aplicaciones web (OWASP Open Web
Application Security Project)
● Comunidad abierta para la divulgación, formación y buenas prácticas
aplicables a mejorar la aplicaciones y apis de las empresas. De este modo
puedas construir aplicaciones y apis en las que se pueda confiar.
● Podemos encontrar:
○ Herramientas gratuitas: Por ejemplo ZASP
(https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project)
○ Presentaciones y videos: Canal de Youtube (https://www.youtube.com/user/OWASPGLOBAL)
○ Listas de correo
○ OWASP Top 10
○ Meetup y eventos
○ Etc
¿Que es OWASP?
5. ● Es una lista de las 10 vulnerabilidades más críticas encontradas en las
aplicaciones web.
● Suele haber una nueva versión cada 3 o 4 años.
● Pretende sensibilizar y ser la base para que las empresas comiencen a crear
código más seguro.
OWASP Top 10: ¿Que es?
7. Dentro de esta vulnerabilidad podemos tener 2 tipos:
● Inyección de JavaScript
● Inyección de SQL o NoSQL
A1:2017 Inyección
8. Descripción
- Si utilizamos funciones como eval, setTimeout, setInterval, Function()
pasándole como parámetro el texto introducido por el usuario puede ser
utilizado por un atacante para obtener información
Problema:
- Obtención de información o ataque de denegación de servicio
Solución
- Sanitizar siempre la entrada de información por parte del usuario
- No utilizar eval en el código
A1:2017 Inyección - Inyección de JS
9. Descripción
- Las inyecciones de SQL o NoSQL permiten a un usuario inyectar código en la consulta que se
ejecutará en la bbdd. Estos fallos suelen ocurrir al crear consultas dinámicas que añaden
información proveniente del usuario.
Problema:
- Obtención de información o ataque de denegación de servicio
Solución
- Utilizar siempre prepared statements
- Validar la entrada del usuario
- Para minimizar el riesgo no ejecutar los procesos con usuario administrador ni dar permisos de
ADMIN a las bbdd
A1:2017 Inyección - Inyección de SQL o NoSQL
10. Descripción
- Esta vulnerabilidad se produce cuando tenemos accesos no autorizados a nuestra aplicación. Esto
puede ser debido a ataques de fuerza bruta con diccionario por parte del atacante o robos de
sesión.
Problema:
- Accesos no autorizados
Solución
- Guardar las password encriptadas o hasheadas en la bbdd usando un salt en el proceso de
encriptación (bcrypt)
- No enviar el sessionId en la url y utilizar cookies firmadas (express-session o koa-session)
- Invalidar la sesión o token del usuario al hacer logout o por timeout (blacklist o whitelist)
- Utilizar 2FA (passport-totp) y establecer una validación de contraseñas fuertes
- Establecer un número máximo de reintentos en el login
A2:2017 Pérdida de autenticación
11. Descripción
- Esta vulnerabilidad se produce cuando un atacante puede obtener datos sensibles de la aplicación
por no estar bien protegido (números de tarjetas, datos médicos, etc)
Problema:
- Robo de información sensible
Solución
- Guardar los datos sensibles encriptados
- Utilizar siempre https para evitar ataques man-in-the-middle (Let’s Encrypt)
- Evitar cachear datos sensibles
- Utiliza algoritmos de encriptación estándar (no implementes tus propios algoritmos)
A3:2017 Exposición de datos sensibles
12. Descripción
- Esta vulnerabilidad se produce al procesar documentos XML se cargan referencias externas no
confiables.
Problema:
- Denegación de servicio u obtención de información
Solución
- No cargar referencias externas en las que no confiemos
- Intentar utilizar sistemas menos complejos (JSON)
- Validación de los datos de entrada del usuario
A4:2017 Entidades externas XML
13. Descripción
- Esta vulnerabilidad se produce cuando solo chequeamos los permisos de acceso en el front y no en
la API (confiando toda la gestión de roles/permisos al front), nuestra API es accesible por todo el
mundo, etc.
Problema:
- Obtención, modificación o destrucción de información por parte de usuarios no autorizados
Solución
- Chequear siempre los permisos en el lado del servidor (uso de middlewares de autorización)
- Generar tokens JWT seguros (JWT y JWKS)
- Establecer una política de CORS correcta para evitar el acceso a la API por parte de otras
aplicaciones
- Validar siempre la obtención de información
- Obtener los datos del usuario logado de la sesion y nunca de los datos enviados por el usuario.
A5:2017 Pérdida de control de acceso
14. Descripción
- Esta vulnerabilidad se produce cuando tenemos cuentas por defecto habilitadas, software
desactualizado, puertos desprotegidos, la aplicación da más información de la estrictamente
necesaria (cabeceras con versiones, errores muy descriptivos en producción, etc)
Problema:
- Obtención de versiones y software usado por la aplicación por parte del atacante que le da
información para obtener las vulnerabilidades de los sistemas.
Solución
- Uso de librerías como Helmet que eliminan toda la información innecesaria y agrega las cabeceras
necesarias para securizar la aplicación. (https://helmetjs.github.io/)
- Usar ultimas versiones de librerías y servicios (npm audit)
- No exponer puertos directamente a internet sin securizar. No exponer nuestro node directamente a
internet. Hacerlo a través de un servidor web.
- Eliminar configuración y cuentas por defecto.
A6:2017 Configuración de seguridad incorrecta
15. Descripción
- Esta vulnerabilidad se produce cuando utiliza datos de los usuarios sin validar ni escapar
directamente como parte del HTML de la página. Esta vulnerabilidad es más grave cuando además
estos datos son guardados por parte de la API y pueden ser mostrados para usuarios
Administradores.
Problema:
- Obtención de información sensible y control de la aplicación.
Solución
- Escapar siempre la entrada de información del usuario antes de mostrarla o guardarla.
- Utilizar librerías que escapen de forma automática el contenido que se vaya a pintar (librerías como
react, angular, etc ya lo hacen por defecto)
A7:2017 Cross-Site Scripting (XSS)
16. Descripción
- Esta vulnerabilidad se produce cuando un atacante utiliza objetos deserializados en los que inyecta
código malicioso y al serializarse consigue ejecutar ese código o modifica el contenido de los
objetos para darse más privilegios (si por ejemplo va el rol en ese objeto)
Problema:
- Obtención de información sensible y control de la aplicación.
Solución
- Validar el esquema antes de deserializar el objeto (jsonschema, joi, etc)
- Deserializar el objeto en un entorno con los menos privilegios posibles.
A8:2017 Deserialización Insegura
17. Descripción
- Esta vulnerabilidad se produce cuando un atacante utiliza vulnerabilidades conocidas de las
librerías o software que utiliza la aplicación para hacerse con datos o el control de esta.
Problema:
- Obtención de información sensible y control de la aplicación.
Solución
- Mantener actualizadas versiones de la librerías(npm audit), servicios y servidores
- Utilizar fuentes confiables para la instalación de librerías
- Uso de retire.js para la detección de librerías con vulnerabilidades conocidas
(https://github.com/RetireJS/retire.js)
- No ejecutes nunca el proceso node como root para minimizar el daño en el caso de que consigan
acceder a través de una vulnerabilidad
A9:2017 Uso de componentes con
vulnerabilidades conocidas
18. Descripción
- Esta vulnerabilidad se produce cuando no registramos los suficientes logs de eventos en la
aplicación. Logs de fallos de inicio de sesión, los errores no son lo suficientemente claros, no
mantenemos trazas de acciones de alto valor (borrado de datos importantes, accesos, etc),
registros de búsqueda de vulnerabilidades por parte de robots, etc.
Problema:
- Al no tener logs o no mantenerlos lo suficiente, no podemos realizar un análisis forense despues de
un ataque o prevenirlos si está ocurriendo.
Solución
- Registrar errores de inicio de sesión, control de acceso o validación de entrada de datos para
identificar cuentas o acciones sospechosas.
- Mantener registros para acciones de alto impacto.
A10:2017 Registro y monitoreo insuficientes
20. - Uso de CSRF para evitar llamadas por parte de un código malicioso
(https://github.com/expressjs/csurf)
- Limitar el número de peticiones por segundo (rate limit)
(https://www.npmjs.com/package/express-rate-limit)
- Nunca expongas tu servidor node directamente a internet y limita el tamaño de los payload. Para
ello utiliza un servidor web que haga de reverse proxy y limite el tamaño de los payload.
- Protégete contra las “evil Regex”. Utiliza librerías de validación en lugar de tus propias regex para
validar la entrada de datos del usuario. En el caso de que necesites utilizar tus propias regex utiliza
safe-regex para validar tus regex.
- Utilizar linters para chequear tu código (TSLint, ESLint, JSHint)
Otras a tener en cuenta
23. ● JSON Web Token
● Estándar RFC 7519
● Modo compacto y autónomo de transmitir información de forma segura
● Se puede verificar y confiar porque va firmado
¿Que es JWT?
24. header.payload.signature
Se compone de 3 partes:
- Header
- Payload
- Signature
¿Que es JWT?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXR
hIjp7Im5hbWUiOiJDb21taXQgQ29uZiIsImlkIjoyMD
E4fSwiaXNzIjoiUmEiLCJhdWQiOiJjb21taXRDb25m
IiwiaWF0IjoxNTQyOTAzNjU5LCJleHAiOjE1NDI5OT
AxMDZ9.e4znIBYG2VWsS3X2VrI_tkZMtBKzM5-i1
Nu_A8_yBdE
28. ● JWK: JSON Web Key
Mecanismo para distribuir las claves públicas que se usan para verificar
tokens JWT firmados con clave privada.
● JWKS: JSON Web Key Set
Conjunto de JWK’s
JWK y JWKs