Seguridad de aplicaciones JavaScript: las 10 principales 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



JavaScript, especialmente en el entorno Node.js, se ha convertido en la base del desarrollo web moderno. Sin embargo, su popularidad hace que las aplicaciones sean un objetivo atractivo para los ataques. Ignorar los problemas de seguridad puede provocar fugas de datos, pérdidas financieras y daños a la reputación. En este artículo, analizaremos las 10 vulnerabilidades más críticas de las aplicaciones JavaScript (Node.js), basadas en el estándar OWASP Top 10, y mostraremos cómo prevenirlas con ejemplos de código.



1. Inyecciones (Injection)

Las inyecciones siguen siendo una de las amenazas más peligrosas. En el contexto de Node.js, las más comunes son las SQL injection y las NoSQL injection (por ejemplo, en MongoDB).



Problema

La concatenación directa de la entrada del usuario en las consultas a la base de datos permite a un atacante ejecutar código arbitrario.



Ejemplo de código vulnerable

const user = req.body.username;const query = `SELECT * FROM users WHERE username = '${user}'`;db.query(query, callback);


Solución

Utilice consultas parametrizadas u ORM/ODM. Para MongoDB, use mongo-sanitize.

const query = 'SELECT * FROM users WHERE username = $1';db.query(query, [user], callback);


2. Fallos de autenticación y gestión de sesiones

Una autenticación débil es un camino directo al compromiso de cuentas.



Problema

Uso de tokens predecibles (por ejemplo, JWT con el algoritmo none), almacenamiento de contraseñas en texto plano o falta de limitación en el número de intentos de inicio de sesión.



Ejemplo de vulnerabilidad

// JWT sin verificación de algoritmoconst token = jwt.sign({ user: 'admin' }, 'secret', { algorithm: 'none' });


Solución

  • Siempre verifique el algoritmo JWT: jwt.verify(token, secret, { algorithms: ['HS256'] }).
  • Almacene las contraseñas usando bcrypt o argon2.
  • Implemente un límite de intentos de inicio de sesión (express-rate-limit).
const bcrypt = require('bcrypt');const saltRounds = 10;const hash = await bcrypt.hash(password, saltRounds);


3. XSS (Cross-Site Scripting)

XSS permite inyectar un script malicioso en una página web, que luego se ejecuta en el navegador de la víctima.



Problema

Mostrar contenido del usuario sin escapar, especialmente al usar Server-Side Rendering (SSR) en Next.js o Nuxt.js.



Código vulnerable (Express)

res.send(`<h1>Hello, ${req.query.name}</h1>`);


Solución

  • Escape la salida: use bibliotecas como escape-html o motores de plantillas con auto-escaped (EJS, Pug).
  • Establezca la cabecera CSP (Content Security Policy): helmet.contentSecurityPolicy().
const helmet = require('helmet');app.use(helmet.contentSecurityPolicy({  directives: { defaultSrc: ["'self'"] }}));


4. Referencia directa insegura a objetos (IDOR)

La vulnerabilidad surge cuando un usuario puede acceder a objetos (archivos, registros de BD) conociendo o adivinando su identificador.



Ejemplo

app.get('/api/user/:id', (req, res) => {  // No hay verificación de que req.user.id === req.params.id  const user = db.findUser(req.params.id);  res.json(user);});


Solución

Siempre verifique los permisos de acceso a nivel del servidor.

if (req.user.id !== req.params.id) {  return res.status(403).send('Forbidden');}


5. Configuración de seguridad insegura

Esto incluye el uso de credenciales predeterminadas, modos de depuración en producción y configuraciones incorrectas de CORS.



Problema

// CORS abiertoapp.use(cors({ origin: '*' }));


Solución

Blogs

Book Recommendations