SQL Injection (SQLi)
¿Qué es SQL Injection?
SQL Injection es una vulnerabilidad que permite a un atacante ejecutar código SQL arbitrario en la base de datos de una aplicación web.
Ocurre cuando la aplicación concatena directamente input del usuario en una consulta SQL sin validación ni sanitización adecuada, permitiendo que el atacante "inyecte" código malicioso.
Impacto de un Ataque SQLi
- 🔓Extracción de datos: Robo de usuarios, contraseñas, tarjetas de crédito
- 🔥Modificación: Alterar o eliminar registros de la BD
- 👤Bypass de autenticación: Login sin credenciales
- 💀Escalada de privilegios: Convertirse en administrador
- 💻Ejecución de comandos: En algunos casos, control total del servidor
- 📋Enumeración del sistema: Descubrir estructura de BD
Ejemplo de Código Vulnerable
❌ CÓDIGO VULNERABLE
// ❌ Concatenación directa de input del usuario
const email = req.body.email;
const password = req.body.password;
const query = `
SELECT * FROM users
WHERE email = '${email}'
AND password = '${password}'
`;
const result = await db.query(query);⚠️ Problema:
El input del usuario se concatena directamente en el SQL. Un atacante puede inyectar código SQL modificando los valores de email o password.
Cómo se Explota
1. Bypass de Autenticación
Atacante envía:
Email: admin' OR '1'='1' --
Password: cualquier cosaLa consulta SQL resultante:
SELECT * FROM users WHERE email = 'admin' OR '1'='1' --' AND password = 'cualquier cosa'
🚨 Resultado:
- •
OR '1'='1'siempre es verdadero - •
--comenta el resto (incluido el password) - • ✅ Login exitoso sin saber la contraseña
2. Extracción de Datos con UNION
Búsqueda vulnerable:
Búsqueda: ' UNION SELECT username, password FROM users --Query resultante:
SELECT title, content FROM notes WHERE title LIKE '%' UNION SELECT username, password FROM users -- %'
🚨 Resultado:
La query devuelve todas las notas Y todos los usuarios con sus contraseñas.
3. Blind SQLi (Inferencia Booleana)
Cuando la aplicación no muestra errores SQL, se puede usar blind SQLipara extraer datos carácter por carácter.
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE id=1) = 'a' --
Si la página se comporta diferente (error, carga lenta, contenido diferente), el atacante sabe si el primer carácter de la contraseña es 'a'.
Tipos de SQL Injection
In-Band SQLi
El atacante ve la respuesta de la BD en la misma petición.
- • Error-based: Errores SQL revelan info
- • UNION-based: Combina queries
Blind SQLi
No hay output directo, se infiere por el comportamiento.
- • Boolean-based: Verdadero/Falso
- • Time-based: SLEEP() delays
Out-of-Band SQLi
Datos se exfiltran por otro canal (DNS, HTTP).
- • DNS exfiltration
- • HTTP callbacks
Second-Order SQLi
El payload se almacena y ejecuta después.
- • Input guardado en BD
- • Ejecutado en otra función
Cómo Prevenir SQL Injection
✅ 1. Consultas Parametrizadas (Prepared Statements)
La solución más efectiva. Los parámetros se escapan automáticamente.
// ✅ SEGURO - Prepared statement
const query = 'SELECT * FROM users WHERE email = ? AND password = ?';
const result = await db.query(query, [email, password]);
// ✅ SEGURO - Parameterized query (Node.js)
const query = {
text: 'SELECT * FROM users WHERE email = $1 AND password = $2',
values: [email, password]
};
const result = await db.query(query);✅ 2. ORM/Query Builders
Herramientas como Prisma, TypeORM, Sequelize escapan automáticamente.
// ✅ SEGURO - Prisma ORM
const user = await prisma.user.findFirst({
where: {
email: email,
password: password
}
});✅ 3. Validación de Input
- •Whitelist de caracteres permitidos
- •Validar tipos de datos (números, emails, etc.)
- •Limitar longitud de inputs
✅ 4. Principio de Menor Privilegio
El usuario de BD de la aplicación no debe ser admin. Solo permisos necesarios (SELECT, INSERT, UPDATE).
✅ 5. WAF y Monitorización
- •Web Application Firewall (WAF) para detectar patrones SQLi
- •Logs de queries sospechosas
- •Rate limiting en endpoints de búsqueda/login
Practica SQL Injection
Pon a prueba lo aprendido en nuestro laboratorio vulnerable de SQLi:
Ir al Lab de SQLi