Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Esta hoja de trucos enumera las cosas que uno puede usar al desarrollar
aplicaciones seguras de Node.js. Cada elemento tiene una breve explicación
y solución que es específica del entorno Node.js.
Contexto
Las aplicaciones de Node.js están aumentando en número y no son diferentes
de otros frameworks y lenguajes de programación. Las aplicaciones de
Node.js también son propensas a todo tipo de vulnerabilidades de aplicaciones
web.
Objetivo
Esta hoja de trucos tiene como objetivo proporcionar una lista de las mejores
prácticas a seguir durante el desarrollo de las aplicaciones Node.js.
Recomendaciones
Hay varias recomendaciones diferentes para mejorar la seguridad de sus
aplicaciones Node.js. Se clasifican como:
Seguridad de la aplicación
Manejo de errores y excepciones
Seguridad del servidor
Seguridad de la plataforma
Seguridad de la aplicación
Use cadenas planas Promise
Las funciones de devolución de llamada asincrónicas son una de las
características más potentes de Node.js. Sin embargo, aumentar las capas de
anidamiento dentro de las funciones de devolución de llamada puede
convertirse en un problema. Cualquier proceso de varias etapas puede
anidarse a 10 o más niveles de profundidad. Este problema se llama Pyramid
of Doom o Callback Hell. En dicho código, los errores y resultados se pierden
dentro de la devolución de llamada. Las promesas son una buena forma de
escribir código asincrónico sin entrar en pirámides anidadas. Las promesas
proporcionan una ejecución de arriba hacia abajo mientras son asíncronas al
entregar errores y resultados a la siguiente .thenfunción.
Otra ventaja de Promises es la forma en que Promises maneja los errores. Si
se produce un error en una clase Promise, omite las .thenfunciones e invoca
la primera .catchfunción que encuentra. De esta manera, las promesas
brindan una mayor seguridad de captura y manejo de errores. Como principio,
puede hacer que todo su código asíncrono (aparte de los emisores) devuelva
promesas. Sin embargo, debe tenerse en cuenta que las llamadas de Promise
también pueden convertirse en una pirámide. Para mantenerse
completamente alejado de los infiernos de devolución de llamada, se deben
usar cadenas planas Promise. Si el módulo que está utilizando no admite
Promesas, puede convertir el objeto base en una Promesa utilizando
la Promise.promisifyAll()función.
El siguiente fragmento de código es un ejemplo de infierno de devolución de
llamada.
function func1(name, callback) {
setTimeout(function() {
// operations
}, 500);
}
function func2(name, callback) {
setTimeout(function() {
// operations
}, 100);
}
function func3(name, callback) {
setTimeout(function() {
// operations
}, 900);
}
function func4(name, callback) {
setTimeout(function() {
// operations
}, 3000);
}
func1("input1")
.then(function (result){
return func2("input2");
})
.then(function (result){
return func3("input3");
})
.then(function (result){
return func4("input4");
})
.catch(function (error) {
// error operations
});
app.post('/auth',
bruteforce.prevent, // error 429 if we hit this route too often
function (req, res, next) {
res.send('Success!');
}
);
Además del expreso-bouncer y express-brute , el módulo limitador de
velocidad también ayuda a prevenir ataques de fuerza bruta. Permite
especificar cuántas solicitudes puede realizar una dirección IP específica
durante un período de tiempo específico.
var limiter = new RateLimiter();
limiter.addLimit('/login', 'GET', 5, 500); // login page can be requested 5
times at max within 500 seconds
El uso de CAPTCHA también es otro mecanismo común que se usa contra la
fuerza bruta. Hay módulos desarrollados para Node.js CAPTCHAs. Un módulo
común utilizado en aplicaciones Node.js es svg-captcha . Se puede usar de la
siguiente manera:
var svgCaptcha = require('svg-captcha');
app.get('/captcha', function (req, res) {
var captcha = svgCaptcha.create();
req.session.captcha = captcha.text;
res.type('svg');
res.status(200).send(captcha.data);
});
Además, el bloqueo de cuenta es una solución recomendada para mantener a
los atacantes lejos de sus usuarios válidos. El bloqueo de cuenta es posible
con muchos módulos como mangosta .
app.use(helmet.noSniff());
app.use(helmet.noCache());
El código anterior establece los encabezados Cache-Control, Surrogate-
Control, Pragma y Expires en consecuencia.
app.use(helmet.ieNoOpen());
app.use(helmet.hpkp({
maxAge: 123,
sha256s: ['Ab3Ef123=', 'ZyxawuV45='],
reportUri: 'http://example.com',
includeSubDomains: true
}));
La decisión de usar la fijación de clave pública debe tomarse con cuidadosa
consideración, ya que puede causar el bloqueo de los usuarios durante mucho
tiempo si se usa incorrectamente.
app.use(helmet.hidePoweredBy());
Además, puede mentir sobre las tecnologías utilizadas con este
encabezado. Por ejemplo, incluso si su aplicación no usa PHP, puede
configurar el encabezado X-Powered-By para que parezca así.
app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }));
Seguridad de la plataforma
Mantenga sus paquetes actualizados
La seguridad de su aplicación depende directamente de la seguridad de los
paquetes de terceros que utiliza en su aplicación. Por lo tanto, es importante
mantener sus paquetes actualizados. Debe tenerse en cuenta que el uso de
componentes con vulnerabilidades conocidas todavía se encuentra en el
OWASP Top 10. Puede usar OWASP Dependency-Check para ver si alguno
de los paquetes utilizados en el proyecto tiene una vulnerabilidad
conocida. También puede usar Retire.js para verificar las bibliotecas de
JavaScript con vulnerabilidades conocidas. Para usarlo, puede ejecutar los
siguientes comandos en la carpeta de código fuente de su aplicación:
npm install -g retire
retire
Hay varias otras herramientas que puede usar para verificar sus
dependencias. Una lista más completa se puede encontrar en Vulnerable
Dependency Management CS .
func();
function func() {
y = 3.14; // This will cause an error (y is not defined)
}