Seguridad de aplicaciones TypeScript: top 10 vulnerabilidades en la práctica

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 TypeScript: top 10 vulnerabilidades en la práctica



TypeScript es una extensión de JavaScript que añade tipado estático. Muchos desarrolladores creen erróneamente que el tipado estricto hace que la aplicación sea segura automáticamente. Esto no es así. El compilador de TypeScript verifica tipos, pero no protege contra errores lógicos, inyecciones o problemas de autenticación. En este artículo analizaremos las 10 vulnerabilidades más comunes en aplicaciones TypeScript, mostraremos ejemplos de código y daremos recomendaciones concretas para la protección. El artículo será útil tanto para desarrolladores principiantes como experimentados.



1. Cross-Site Scripting (XSS) mediante procesamiento incorrecto de entrada



XSS sigue siendo una de las vulnerabilidades más peligrosas. TypeScript no escapa la salida automáticamente. Si inserta datos de usuario en una plantilla HTML sin sanitización, está abriendo la puerta a ataques.



Código vulnerable

function renderComment(comment: string): string {  return `<div>${comment}</div>`;}

// El atacante envía: <script>alert('XSS')</script>


Código corregido

import { escape } from 'lodash';

function renderComment(comment: string): string { const safeComment = escape(comment); return `<div>${safeComment}</div>`;}


Recomendación: Utilice siempre bibliotecas para escapar (DOMPurify, lodash.escape) o motores de plantillas con escape automático (React JSX, Handlebars).



2. Inyecciones SQL mediante plantillas de cadenas



TypeScript permite usar plantillas de cadenas para construir consultas SQL. Este es un camino directo a la inyección SQL si inserta datos de usuario.



Código vulnerable

async function getUser(id: string): Promise<User | null> {  const query = `SELECT * FROM users WHERE id = '${id}'`;  const result = await db.query(query);  return result.rows[0];}


Código corregido

async function getUser(id: string): Promise<User | null> {  const query = 'SELECT * FROM users WHERE id = $1';  const result = await db.query(query, [id]);  return result.rows[0];}


Recomendación: Utilice consultas parametrizadas u ORM (TypeORM, Prisma, Sequelize). Nunca concatenes cadenas para SQL.



3. Comparación insegura de contraseñas



Un error en la implementación de la comparación de contraseñas puede provocar ataques de temporización. Los desarrolladores de TypeScript suelen usar el operador === para comparar hashes, lo cual no es seguro.



Código vulnerable

async function verifyPassword(  inputPassword: string,   storedHash: string): Promise<boolean> {  const inputHash = await bcrypt.hash(inputPassword, 10);  return inputHash === storedHash; // Vulnerabilidad: timing attack}


Código corregido

import bcrypt from 'bcrypt';

async function verifyPassword( inputPassword: string, storedHash: string): Promise<boolean> { return bcrypt.compare(inputPassword, storedHash);}


Recomendación: Utilice las funciones de comparación integradas de las bibliotecas de hashing (bcrypt.compare, argon2.verify). Están protegidas contra ataques de temporización.



4. Prototype Pollution mediante fusión recursiva de objetos



Las aplicaciones TypeScript suelen usar funciones de copia profunda o fusión de objetos. Si no se controlan las claves, un atacante puede contaminar el prototipo Object.prototype.



Código vulnerable

function merge(target: Record<string, any>, source: Record<string, any>) {  for (const key in source) {    if (typeof source[key] === 'object') {      target[key] = merge(target[key] || {}, source[key]);    } else {      target[key] = source[key];    }  }  return target;}

// El atacante en

Blogs

Book Recommendations