Seguridad de aplicaciones JavaScript: top 10 vulnerabilidades

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Seguridad de aplicaciones JavaScript: top 10 vulnerabilidades



Las aplicaciones JavaScript modernas en Node.js procesan enormes volúmenes de datos sensibles, lo que las convierte en un objetivo atractivo para los atacantes. Según OWASP, la mayoría de las intrusiones ocurren debido a errores típicos que se pueden prevenir. En este artículo analizaremos las 10 vulnerabilidades más comunes, proporcionaremos ejemplos reales de código y mostraremos cómo proteger su aplicación.



1. XSS (Cross-Site Scripting)

El scripting entre sitios es una de las amenazas más antiguas, pero sigue siendo relevante. El atacante inyecta un script malicioso en una página web que se ejecuta en el navegador de la víctima.



// Código vulnerableapp.get('/search', (req, res) => {    const query = req.query.q;    res.send(`<h2>Resultados de búsqueda para: ${query}</h2>`);});

// Versión seguraconst escapeHtml = (str) => { return str.replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#039;');};

app.get('/search', (req, res) => { const query = escapeHtml(req.query.q || ''); res.send(`<h2>Resultados de búsqueda para: ${query}</h2>`);});


2. SQL Injection

La inyección de código SQL ocurre cuando la entrada del usuario se concatena directamente en una consulta SQL. Esto puede provocar la fuga o eliminación de datos.



// Código vulnerableconst userId = req.body.id;const query = `SELECT * FROM users WHERE id = ${userId}`;

// Versión segura con consultas parametrizadasconst userId = req.body.id;const query = 'SELECT * FROM users WHERE id = ?';db.query(query, [userId], (err, results) => { // procesamiento de resultados});


3. Deserialización insegura

Node.js usa frecuentemente JSON.parse(), pero si trabaja con otros formatos (por ejemplo, Buffer), un atacante puede inyectar datos maliciosos.



// Enfoque peligrosoconst data = JSON.parse(req.body.data); // puede contener __proto__

// Enfoque seguroconst safeParse = (json) => { const data = JSON.parse(json); // Eliminamos recursivamente propiedades peligrosas return JSON.parse(JSON.stringify(data));};


4. CSRF (Cross-Site Request Forgery)

Ataque en el que el atacante obliga al usuario a realizar una acción no deseada en un sitio donde está autenticado.



// Configuración de protección con csurfconst csrf = require('csurf');const csrfProtection = csrf({ cookie: true });

app.post('/transfer', csrfProtection, (req, res) => { // procesamiento seguro de la transferencia});


5. Autenticación insegura

Contraseñas débiles, falta de límite de intentos de inicio de sesión y almacenamiento de contraseñas en texto plano son problemas comunes.



// Hash correcto de contraseñasconst bcrypt = require('bcrypt');

async function createUser(password) { const salt = await bcrypt.genSalt(12); const hash = await bcrypt.hash(password, salt); // guardamos el hash en la BD}

async function checkPassword(plainPassword, hash) { return await bcrypt.compare(plainPassword, hash);}


6. Fuga de datos confidenciales

Enviar el stack de errores al cliente o registrar contraseñas es un error frecuente de los desarrolladores.



// Incorrectoapp.use((err, req, res, next) => {    res.status(500).json({ error: err.stack });});

// Correctoapp.use((err, req, res, next) => { console.error(err); // registramos en el servidor res.status(500).json({ error: 'Error interno del servidor' });});


7. Configuración insegura

Uso de puertos estándar, modo de depuración habilitado en producción y políticas CORS débiles.



// Configuración segura de CORSconst cors = require('cors');cons                

Blogs

Book Recommendations