Inyección SQL
Se lee en aproximadamente 4 minutos
Última actualización: 2026-09-01
Qué es la inyección SQL
La inyección SQL es una vulnerabilidad en la que la entrada del usuario se incorpora sin el tratamiento adecuado a las consultas a la base de datos de una aplicación web, de modo que el atacante puede ejecutar sentencias SQL arbitrarias. El daño puede llegar al robo, la alteración y el borrado de todos los datos de la base de datos, e incluso a la ejecución de comandos del sistema operativo en el servidor. En el OWASP Top 10, la inyección SQL (CWE-89) se clasifica dentro de la categoría de inyección: encabezó la lista como A1:2017-Injection en la edición de 2017, y figura como A03:2021 en la de 2021 y como A05:2025 en la de 2025.
Uno de los primeros textos públicos sobre la inyección de SQL a través de la web es el artículo "NT Web Technology Vulnerabilities", publicado en el número 54 de Phrack Magazine en diciembre de 1998. Allí se señalaba que a una sentencia SQL construida concatenando directamente los valores introducidos en una página web se le puede añadir otra sentencia, y se ponía como ejemplo que MS SQL Server 6.5 admitía la ejecución por lotes de varias sentencias. Más de un cuarto de siglo después de aquel aviso, en agosto de 2026, las medidas de fondo siguen siendo claras y, aun así, no dejan de aparecer casos en los que la vulnerabilidad persiste por defectos de implementación.
Principio y tipos de ataque
La inyección SQL ocurre cuando la aplicación construye consultas SQL mediante concatenación de cadenas. Por ejemplo, si el nombre de usuario ingresado en un formulario de inicio de sesión se incrusta directamente en la consulta como SELECT * FROM users WHERE name = 'valor_entrada', cuando el atacante ingresa ' OR '1'='1 como valor de entrada, la cláusula WHERE siempre es verdadera, permitiendo evadir la autenticación.
Principales tipos de ataque
- Basado en UNION: Inyectar
UNION SELECTpara obtener datos de tablas a las que normalmente no se tiene acceso. Es necesario hacer coincidir el número y tipo de columnas, pero se puede deducir a partir de mensajes de error o cambios en la respuesta. - Basado en errores: Provocar errores intencionalmente y leer la información de la base de datos (nombres de tablas, nombres de columnas, datos) contenida en los mensajes de error.
- Inyección SQL ciega: Cuando no se muestran mensajes de error, se extrae información bit a bit utilizando bifurcaciones de condiciones booleanas (Boolean-based) o diferencias en el tiempo de respuesta (Time-based).
- Fuera de banda (Out-of-Band): Hacer que la base de datos envíe datos a un servidor externo a través de solicitudes DNS o HTTP.
La existencia de herramientas automatizadas (como sqlmap) permite la detección y explotación de inyecciones SQL sin conocimientos técnicos avanzados.
Realidad del daño y alcance del impacto
El daño de la inyección SQL no se limita al robo de datos.
- Robo de datos: pueden filtrarse todos los datos guardados en la base de datos, incluidos datos personales, credenciales de autenticación y números de tarjeta de crédito
- Alteración y borrado de datos: se inyectan sentencias
UPDATEoDELETEpara modificar o eliminar datos, y conDROP TABLEes posible borrar una tabla completa - Elusión de la autenticación: manipulando la consulta de inicio de sesión se accede a cualquier cuenta, incluida la de administrador, sin conocer la contraseña
- Toma de control del servidor: se abusa de funciones de la base de datos (como
LOAD_FILEen MySQL oxp_cmdshellen SQL Server) para ejecutar comandos en el sistema operativo
En los recuentos de OWASP para la edición de 2025 del Top 10, la inyección SQL (CWE-89) se notifica con menos frecuencia que el Cross-Site Scripting, pero se cuenta entre las debilidades de mayor impacto, con más de 14.000 CVE registrados. La detección mediante un WAF es un complemento eficaz, aunque también se conocen técnicas que lo eluden con codificaciones ingeniosas o insertando comentarios, por lo que no sustituye a las medidas de fondo.
Medidas fundamentales
Las medidas de fondo contra la inyección SQL son claras. Si se aplica de forma sistemática una implementación que separe la estructura de la sentencia SQL de los datos, se cierra la mayor parte de las vías de ataque. Aun así, tal como advierte OWASP, si el PL/SQL o el T-SQL del interior de un procedimiento almacenado concatena cadenas o las ejecuta con EXECUTE IMMEDIATE, la vulnerabilidad persiste aunque la llamada esté parametrizada.
Sentencias preparadas (consultas parametrizadas)
Separan la estructura de la sentencia SQL de los datos, de manera que la entrada del usuario no se interpreta como sintaxis SQL. El apartado de inyección del OWASP Top 10 sitúa igualmente en primer lugar el uso de API seguras que no pasan por el intérprete y de interfaces parametrizadas. Las principales bibliotecas de acceso a bases de datos ofrecen un mecanismo equivalente, así que el primer paso es sustituir los lugares en los que la consulta se arma concatenando cadenas. Conviene tener en cuenta que las partes estructurales del SQL, como los nombres de tabla y de columna, no pueden ir en un marcador de posición ni quedan protegidas con el escapado. Cuando la entrada del usuario decide, por ejemplo, la columna de ordenación, hay que fijar los valores admitidos con una lista de permitidos. El escapado, en los pocos puntos donde no queda otra opción que armar la consulta de forma dinámica, ocupa el papel complementario de cubrir lo que no se puede parametrizar.
Uso de un ORM
Con un ORM (Object-Relational Mapping) hace falta escribir SQL a mano en muchas menos ocasiones, lo que reduce el riesgo de inyección SQL. Sin embargo, al usar las funciones de consulta en bruto o las consultas personalizadas del ORM se necesita la misma precaución que con las sentencias preparadas.
Defensa en profundidad
- Principio de mínimo privilegio: limitar al mínimo necesario los permisos de la cuenta de base de datos que utiliza la aplicación y emplear una cuenta de solo lectura para las operaciones de solo lectura
- Validación de la entrada: aceptar solo números en los campos numéricos y solo valores con el formato correcto en los campos de correo electrónico. Es una medida complementaria que no sustituye a las sentencias preparadas
- Control de los mensajes de error: no mostrar directamente al usuario los mensajes de error de la base de datos, con lo que se evitan las filtraciones mediante inyección SQL basada en errores
- Gestión de vulnerabilidades: detectar pronto los fallos de inyección SQL con análisis de seguridad y revisiones de código periódicos
- Reparto de papeles con los encabezados de seguridad: los encabezados de seguridad controlan el comportamiento del navegador y no tienen efecto sobre la inyección SQL, en la que la consulta se arma en el servidor. Se emplean como la capa que atiende los otros riesgos que llegan por los mismos campos de entrada, como el XSS
Conceptos erróneos comunes
- Escapar los valores de entrada previene la inyección SQL
- El proceso de escape es propenso a errores de implementación y pueden producirse omisiones por diferencias en la codificación de caracteres o casos especiales. Las sentencias preparadas separan fundamentalmente la estructura SQL de los datos, eliminando el riesgo de omisiones de escape. Se deben usar sentencias preparadas en lugar de escape.
- Las bases de datos NoSQL no tienen inyección SQL
- La inyección SQL no ocurre, pero existe una vulnerabilidad similar llamada inyección NoSQL. En MongoDB, si se incrusta directamente la entrada del usuario en consultas JSON, es posible inyectar operadores de consulta. Independientemente del tipo de base de datos, el procesamiento adecuado de la entrada del usuario es obligatorio.
Comparación entre inyección SQL y XSS
Inyección SQL
Ataca la base de datos del lado del servidor. Permite robo, alteración y eliminación de datos. Se puede defender fundamentalmente con sentencias preparadas. El daño afecta a los datos del servidor.
XSS
Ataca el navegador del lado del cliente. Los principales daños son robo de cookies y secuestro de sesión. Se defiende con escape de salida y CSP. El daño ocurre en el navegador del usuario.