Seguridad de aplicaciones TypeScript: top 10 vulnerabilidades para principiantes

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

Introducción: por qué la seguridad de las aplicaciones TypeScript es importante desde el primer día

TypeScript es una extensión de JavaScript que añade tipado estático. Muchos desarrolladores principiantes creen erróneamente que el tipado resuelve automáticamente todos los problemas de seguridad. En realidad, TypeScript se compila a JavaScript normal, y todas las vulnerabilidades inherentes a JS siguen siendo relevantes. En este artículo, analizaremos las 10 principales vulnerabilidades que enfrentan los principiantes y mostraremos cómo evitarlas.



1. XSS (Cross-Site Scripting)

XSS es uno de los ataques más comunes. Un atacante inyecta un script malicioso en la página que se ejecuta en el navegador del usuario.

Ejemplo de código vulnerable:

function renderUserInput(input: string): string {    return `<div>${input}</div>`;}

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

Cómo solucionarlo:

Escape siempre la entrada del usuario. Use bibliotecas como DOMPurify o métodos de escape integrados:

import DOMPurify from 'dompurify';

function safeRender(input: string): string { const clean = DOMPurify.sanitize(input); return `<div>${clean}</div>`;}


2. Inyección SQL

Si construye consultas SQL concatenando cadenas con entrada del usuario, está abriendo la puerta a la inyección SQL.

Código vulnerable:

function getUser(username: string): Promise<User> {    const query = `SELECT * FROM users WHERE username = '${username}'`;    return db.execute(query);}

Opción segura:

function getUserSafe(username: string): Promise<User> {    const query = 'SELECT * FROM users WHERE username = $1';    return db.execute(query, [username]); // consulta parametrizada}


3. Almacenamiento inseguro de contraseñas

Nunca almacene contraseñas en texto plano. Use bcrypt o argon2 para el hash.

import bcrypt from 'bcrypt';

async function hashPassword(password: string): Promise<string> { const saltRounds = 12; return bcrypt.hash(password, saltRounds);}

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


4. Referencia directa insegura a objetos (IDOR)

Cuando un usuario puede acceder a datos de otros simplemente cambiando el ID en la URL.

Ejemplo:

// Vulnerable: cualquier usuario puede obtener cualquier pedidoapp.get('/api/order/:id', (req, res) => {    const order = getOrderById(req.params.id);    res.json(order);});

// Seguro: verificamos la pertenenciaapp.get('/api/order/:id', (req, res) => { const order = getOrderById(req.params.id); if (order.userId !== req.user.id) { return res.status(403).json({ error: 'Forbidden' }); } res.json(order);});


5. Uso de dependencias obsoletas

Los proyectos TypeScript a menudo usan paquetes npm. Las versiones obsoletas pueden contener vulnerabilidades conocidas.

  • Ejecute regularmente npm audit
  • Use npm update para actualizar paquetes
  • Configure verificaciones automáticas en CI/CD


6. Validación insuficiente de datos de entrada

Los tipos de TypeScript no se verifican en tiempo de ejecución. Siempre valide los datos en el servidor.

interface UserInput {    email: string;    age: number;}

// Insuficiente: los tipos de TypeScript no protegen en tiempo de ejecuciónfunction processUser(input: UserInput) { // ...}

// Correcto: use Zod o Joi para validaciónimport { z } from 'zod';

const UserSchema = z.object({ email: z.string().email(), age: z.number().min(18).max(120)});

function processUserSafe(input: unknown) { const validate

Blogs

Book Recommendations