Tutorial de seguridad con Node.js

La seguridad es un tema de suma importancia en la actualidad, si has llegado a este práctico tutorial seguramente sea porque te preocupa el nivel de seguridad y fiabilidad de tus programas. Sigue leyendo para que aprendas a aumentar la seguridad de tu propia App.

¡Comencemos y aseguremos nuestra aplicación con Node.js mediante codificación, herramientas y hábitos de operación adecuadas!

1. Aplicando formas de codificación seguras

  • Primero: evitar usar eval

Quizá no sepas esta información, pero eval puede abrir tu aplicación para ataques de inyección de código. Trata de no usarlo, pero si tienes que hacerlo, nunca inyectes entradas de usuario no validadas en eval.

Eval no es el único que debes evitar para esto: en el fondo, cada una de las siguientes expresiones usa eval:

setInterval(String, 2)
setTimeout(String, 2)
new Function(String)

  • Segundo: trata de usar siempre la instrcción ‘use strict’

Con ‘use strict’ tu puedes optar por usar una “variable” restringida de JavaScript. Esta variable, elimina algunos errores silenciosos y los desecha todo el tiempo.

'use strict'
delete Object.prototype
// TypeError
var obj = {
a: 1,
a: 2
}
// error de sintaxis

  • Tercero: tratar de manejar los errores con extremo cuidado

Durante diferentes escenarios de error, tu aplicación puede perder datos sensibles sobre la infraestructura subyacente, como: X-Powered-By:Express.

Los rastros de pila no se tratan como vulnerabilidades por sí mismos, pero a menudo revelan información que puede ser interesante para un atacante. Proporcionar información de depuración como resultado de operaciones que generan errores se considera una mala práctica. Siempre debe registrarlos, pero nunca mostrarlos a los usuarios.

  • Cuarto: Intenta hacer un análisis estático de tu base de datos

El análisis estático del código de base de datos de tu aplicación puede detectar muchos errores. Para eso sugerimos usar ESLint con el estilo de código estándar .

Ejecución de sus servicios en producción de forma segura

El uso del estilo de código adecuado no es suficiente para proteger de manera eficiente las aplicaciones Node.js, también debes tener cuidado de cómo ejecutas tus servicios en producción.

  • Quinto: evita ejecutar tus procesos con derechos de superusuario

Lamentablemente, vemos que este caso pasa mucho: los desarrolladores están ejecutando su aplicación Node.js con derechos de super usuario, ya que quieren que se escuche en el puerto 80 o 443.

Esto está muy mal. En el caso de un error o bug, su proceso puede hacer caer todo el sistema, ya que tiene credenciales para hacer cualquier cosa.

En lugar de esto, lo que puedes hacer es configurar un servidor o proxy HTTP para reenviar las solicitudes. Puede ser nginx o Apache.

  • Sexto: configurar las cabeceras HTTP obligatorias

Hay algunas cabeceras HTTP relacionadas con la seguridad que su sitio debería establecer. Estas cabeceras lo son:

  • Strict-Transport-Security: este refuerza las conexiones seguras (HTTP sobre SSL/TLS) al servidor.
  • X-Frame-Options: te proporciona protección contra el clickjacking
  • X-XSS-Protection: puede habilitar el filtro XSS (cross-site scripting) integrado en los navegadores web más recientes.
  • X-Content-Type-Options: este evita que los navegadores olfateen una respuesta alejada del tipo de contenido declarado.
  • La política de seguridad de contenido previene una amplia gama de ataques, incluyendo secuencias de comandos entre sitios y otras inyecciones entre sitios.

En Node.js es fácil configurarlos usando el módulo Helmet:


var express = require('express')
var helmet = require('helmet')

var app = express()

app.use(helmet())

Helmet está disponible también para Koa: koa-helmet.

  • Séptimo: llevar a cabo una gestión adecuada de las sesiones

La siguiente lista de marcas debe ser establecida para cada cookie:

  1. secure:  este atributo le dice al navegador que sólo envíe la cookie si la petición se está enviando a través de HTTPS.
  2. HttpOnlyly: este atributo se utiliza para ayudar a prevenir ataques tales como scripts cruzados, ya que no permite el acceso a la cookie a través de JavaScript.
  • Octavo: Establecimiento del ambiente de aplicación de las cookies

  1. domain: este atributo se utiliza para comparar con el dominio del servidor en el que se está solicitando la URL. Si el dominio coincide o es un subdominio, el atributo de ruta se comprobará a continuación.
  2. path: además del dominio, se puede especificar la ruta URL para la que es válida la cookie. Si el dominio y la ruta coinciden, entonces la cookie se enviará en la solicitud.
  3. expires: este atributo se usa para establecer cookies persistentes ya que la cookie no expira hasta que se excede la fecha establecida.

En Node.js puede crear fácilmente esta cookie utilizando el paquete de cookies. Una vez más, esto es bastante bajo por lo que probablemente terminará usando una envoltura, como la sesión de galletas.

var cookieSession = require('cookie-session')
var express = require('express')

var app = express()

app.use(cookieSession({
name: 'session',
keys: [
process.env.COOKIE_KEY1,
process.env.COOKIE_KEY2
]
}))

app.use(function (req, res, next) {
var n = req.session.views || 0
req.session.views = n++
res.end(n + ' views')
})

app.listen(3000)

Considera las herramientas a utilizar

¡Felicidades, ya casi llegas al final del artículo! Si has seguido este tutorial y ha realizado los pasos anteriores a fondo y al pie de la letra, sólo te queda un área por cubrir en cuanto a la seguridad de Node.js. ¡Sumerjámonos en el uso de las herramientas adecuadas para buscar vulnerabilidades de los módulos!

  • Noveno: busca vulnerabilidades con Retire.js

El objetivo de Retire.js es ayudarte a detectar el uso de versiones de módulos con vulnerabilidades conocidas.

Simplemente instale con:

npm install -g retire

Después de eso, ejecutarlo con el comando retire buscará vulnerabilidades en el directorio node_modules. (También ten en cuenta que retire.js no sólo funciona con módulos de nodos sino también con librerías frontales).

  • Décimo: audita tus módulos con la plataforma de seguridad de Node CLI

nsp es la interfaz principal de la línea de comandos para la plataforma de seguridad de Node. Permite auditar un archivo package.json o npm-shrinkwrap.json contra la API del NSP para comprobar si hay módulos vulnerables.


npm install nsp --global
# Desde dentro del directorio de su proyecto
nsp check

La seguridad de Node.js no es un gran problema después de todo, ¿verdad? Espero que hayas encontrado útiles y necesarias estas reglas para asegurar tus aplicaciones Node.js, y que las sigas en el futuro ya que la seguridad es parte de tu trabajo. ¡Felicidades!