Reports

Inyección SQL: qué es, cómo se detecta y cómo se evita

Guía en castellano sobre inyección SQL: cómo funciona, dónde sigue apareciendo hoy, cómo se detecta en bug bounty y por qué las consultas parametrizadas la evitan.

Qué es

La inyección SQL ocurre cuando un dato del usuario se pega dentro de una consulta a la base de datos y acaba formando parte de la propia consulta. Si la aplicación construye algo así:

SELECT * FROM productos WHERE nombre = '<lo que escribe el usuario>'

basta con escribir una comilla para salir del texto y añadir condiciones propias. Según la base de datos y los permisos, permite leer tablas enteras, saltarse un inicio de sesión, modificar datos o, en casos extremos, ejecutar comandos.

Dónde sigue apareciendo

Los formularios de inicio de sesión ya rara vez fallan. Hoy aparece sobre todo en sitios menos vistosos:

  • Parámetros de ordenación (ORDER BY) y nombres de columna, que no se pueden parametrizar y se concatenan a mano.
  • Filtros avanzados, búsquedas con muchos campos y exportaciones.
  • Cabeceras HTTP o cookies que la aplicación guarda o consulta.
  • Consultas "en bruto" dentro de aplicaciones que usan un ORM para todo lo demás.

Cómo se detecta

  1. Añade una comilla simple o doble a un parámetro y fíjate si cambia la respuesta: un error, una página vacía o un código 500.
  2. Compara condiciones que deberían dar el mismo resultado y otras que no (AND 1=1 frente a AND 1=2). Si la respuesta cambia, el parámetro llega a la consulta.
  3. Si no hay diferencias visibles, mide tiempos con funciones de espera de la base de datos (inyección "a ciegas").
  4. Herramientas como sqlmap automatizan la explotación, pero en bug bounty muchos programas limitan su uso: lee las reglas y empieza siempre a mano.

Cómo se evita

  • Consultas parametrizadas (prepared statements) en todos los casos: el dato viaja aparte y nunca se interpreta como SQL.
  • Para lo que no se puede parametrizar (columnas, orden), una lista cerrada de valores permitidos.
  • Un usuario de base de datos con los permisos mínimos.
  • No mostrar errores de la base de datos al usuario.

Al reportarlo

Demuestra la inyección con la mínima lectura posible (por ejemplo, la versión de la base de datos) y no extraigas datos de usuarios: no hace falta para probar el impacto y muchos programas lo prohíben expresamente.

Casos reales de SQL Injection