Volver al glosario

Inyección SQL (SQL injection)

8 min de lectura

En seguridad de aplicaciones, la inyección SQL es un fallo por el que una entrada cambia el significado de la consulta que construye la aplicación, en vez de leerse como dato dentro de ella. Las consultas parametrizadas arreglan el caso común, pero los identificadores como la tabla, la columna o el orden no se pueden parametrizar, y el SQL dinámico dentro de un procedimiento almacenado reconstruye el mismo problema.

24 de julio de 2026
Compartir:

Cómo funciona

Una aplicación construye una consulta como texto y se la manda a la base de datos. Si alguna parte de ese texto venía del usuario y no se separó del código, la base de datos no tiene forma de notar la diferencia: analiza la cadena entera y ejecuta la gramática que encuentre. La inyección no es engañar a la base de datos. Es la base de datos haciendo exactamente lo que dice el texto.

La concatenación de cadenas es el caso visible y no el único. El mismo fallo aparece en el SQL dinámico construido dentro de un procedimiento almacenado, donde el parámetro llega a salvo y después se pega dentro de otra sentencia y se ejecuta. Aparece en un ORM en cuanto un fragmento en crudo, una expresión de filtro o un campo de ordenación se componen a partir de entrada de usuario, que es habitual porque los ORM cubren las consultas fáciles y el desarrollador baja a SQL en crudo para las difíciles. Y aparece de segundo orden: un valor se guarda correctamente con una inserción parametrizada, se vuelve a leer después y se concatena en otra consulta, que es la razón de que probar solo el campo por el que entra el dato no lo encuentre.

Lo que hace después un atacante depende de la respuesta. Si los resultados vuelven en la página, la consulta se extiende para leer otras tablas. Si no vuelven, la respuesta se infiere bit a bit a partir de si la página cambia, o de cuánto tarda la base de datos en contestar, o de una petición DNS o HTTP que se hace salir a la propia base de datos. Ese último canal es el que sigue funcionando cuando todo lo demás calla.

Qué sale mal

El fallo que más vemos no es una aplicación sin parametrización. Es una aplicación que parametriza el noventa por ciento que puede y se construye a mano el resto. La ordenación es el clásico: una cláusula ORDER BY toma un nombre de columna, un nombre de columna es un identificador, y los identificadores no se pueden ligar como parámetros. Quien lo escribió conocía los marcadores de posición y llegó al límite de lo que pueden hacer, y rellenó el hueco con concatenación y un comentario.

Las pantallas de informes y de búsqueda son el segundo sitio fiable. Se construyen tarde, aceptan expresiones de filtro que se corresponden bastante directamente con SQL, y suelen estar detrás de un rol autenticado al que un escáner no llega nunca. La exportación y la funcionalidad de administración son donde encontramos inyección en aplicaciones que por lo demás están limpias.

Sobrevive porque el síntoma visible no está. Un caso ciego no produce error, ni traza de pila, ni cambio en la página. La única diferencia son los tiempos, y unos tiempos no parecen un incidente para nadie que esté mirando. En un encargo lo confirmamos con una respuesta condicional y un retardo deliberado, y ahí paramos: demostrar acceso de lectura a una fila de una tabla basta para escribir el hallazgo. Extraer una base de datos de clientes para demostrar impacto no es probar, es el incidente.

En banda, ciega y fuera de banda

Los tres nombres describen cómo le vuelve la respuesta al atacante, no cómo ocurre la inyección. El punto de entrada y el arreglo son idénticos en los tres. Lo que cambia es lo difícil que es encontrarla y el ruido que hace.

En banda Ciega Fuera de banda
Cómo vuelve la respuesta En la página, en los resultados o en un error Se infiere del comportamiento o del tiempo de respuesta Por una petición que la base de datos hace hacia fuera
Qué necesita el atacante Nada más Muchas peticiones, una inferencia cada una DNS o HTTP de salida desde el equipo de base de datos
Velocidad Inmediata Lenta, cientos o miles de peticiones Rápida
Probabilidad de que se note Los errores se pueden registrar El volumen es la única señal Los registros de salida, si alguien los lee
Por qué se suele escapar Es rara, casi todos los equipos la arreglan No hay ningún síntoma visible Nadie vigila la salida de la base de datos

La consecuencia práctica es para el defensor, no para el atacante. Si lo único que te separa de una extracción masiva es que los errores están suprimidos, no tienes un control. Suprimir los errores sube el número de peticiones y nada más. Bloquear el tráfico de salida de los equipos de base de datos, en cambio, elimina un canal entero y merece la pena por sí solo.

Errores frecuentes

Creer que un ORM lo hace imposible. Hace seguro el comportamiento por defecto. Cada fragmento en crudo, cada consulta nativa, cada filtro dinámico y cada campo de ordenación interpolado quedan fuera de ese defecto, y son justo las partes que el desarrollador escribe a propósito.

Escapar comillas en vez de ligar parámetros. Escapar depende del contexto, depende del juego de caracteres y es fácil de esquivar en contextos numéricos donde no hace falta ninguna comilla. Ligar elimina la pregunta.

Parametrizar los valores y olvidarse de los identificadores. Los nombres de tabla, los nombres de columna, la dirección de orden y el LIMIT en algunos motores no se pueden ligar. Necesitan una lista de permitidos que traduzca un valor visible al usuario a un nombre interno fijo, nunca un filtro que inspeccione la cadena.

Ejecutar la aplicación como propietario de la base de datos. La cuenta con la que se conecta la aplicación decide a qué llega una inyección que funcione. Encontramos por rutina una sola cuenta con derechos sobre todos los esquemas, que convierte un fallo en una pantalla de informes en acceso a todo.

Tratar un escaneo limpio como cobertura. Los escáneres prueban lo que alcanzan. Los casos de segundo orden y los de trastienda autenticada necesitan una sesión, un flujo de trabajo y un motivo para mirar.

Cómo reducirlo

Liga todos los valores, sin excepción, y trata cada sitio donde no puedas ligar como una decisión de diseño con una respuesta escrita. Para los identificadores, traduce la elección del usuario a un nombre fijo de una lista que controles tú, para que la cadena de la petición no llegue nunca al texto de la consulta. Audita los procedimientos almacenados en busca de SQL dinámico con el mismo cuidado que el código de aplicación, porque la frontera de parámetros en la llamada al procedimiento no es la frontera que importa.

Después reduce lo que vale una inyección que funcione. Dale a la aplicación una cuenta de base de datos con derechos sobre los objetos que usa de verdad, separa los roles de lectura y de escritura donde la carga lo permita, y quita permisos sobre los esquemas que la aplicación no toca. Bloquea el DNS y el HTTP de salida desde los equipos de base de datos. Cuando la carga es un conjunto fijo de sentencias, una lista de permitidos en la propia base de datos es alcanzable y convierte la inyección en un error.

Para la detección, el DAST encuentra barato los casos reflejados y los basados en error; el análisis estático con SAST encuentra la concatenación en el código, incluidas las ramas a las que un escáner no llega nunca. Ninguno encuentra de forma fiable los casos de segundo orden. En los registros, la señal no es un carácter de comilla: es una sesión que emite muchas peticiones casi idénticas cuya única diferencia es un límite numérico, o una consulta que en un endpoint normalmente rápido tarda un número de segundos sospechosamente redondo.

Dónde aparece esto en una auditoría

En un informe web o de API, la inyección SQL se escribe contra el parámetro y contra la ruta de código, no contra la aplicación, y es un hallazgo por cada sumidero inyectable. La evidencia que entregamos es la petición exacta, la diferencia observable que demuestra que la consulta cambió de significado, la cuenta de base de datos con la que se conecta la aplicación y la prueba de acceso de lectura más pequeña posible. No incluimos datos extraídos en el cuerpo del informe.

La severidad se mueve con lo que alcance la cuenta de conexión y con si el fallo permite escribir además de leer. La misma técnica contra una cuenta de informes de solo lectura con un esquema es un hallazgo serio; contra una cuenta que es propietaria de la base de datos, y donde hay consultas apiladas o acceso a ficheros, es lo primero del informe, y es con frecuencia la ruta a la ejecución remota de código.

Esto sale en todos los encargos en los que probamos una aplicación contra su base de datos.

Preguntas frecuentes

¿Sigue siendo común la inyección SQL en 2026? Ya no es el estado por defecto de un formulario de acceso público, y no ha desaparecido. Ahora se concentra en pantallas de trastienda autenticadas, en funcionalidad de informes y de exportación, en SQL dinámico dentro de procedimientos almacenados y en servicios antiguos detrás de una pasarela de API, que son los sitios a los que las pruebas automatizadas no suelen llegar.

¿Las consultas parametrizadas arreglan la inyección SQL? La arreglan allí donde se pasa un valor. No pueden ayudar donde se elige un identificador, como un nombre de columna o una dirección de orden, porque esos cambian la estructura de la sentencia. Eso necesita una lista de permitidos. Decir «usamos parámetros» no es, por sí solo, una respuesta.

¿Qué es la inyección SQL ciega? Inyección en la que la aplicación no devuelve nada útil, así que el atacante recupera el dato bit a bit a partir de una diferencia de comportamiento o de tiempo de respuesta. Es más lenta e igual de completa, y es la forma que con más probabilidad está ahora mismo dentro de una aplicación en producción.

¿Puede un WAF parar la inyección SQL? Un WAF bloquea formas de carga conocidas y sube el esfuerzo. La codificación, los comentarios y la sintaxis propia de cada motor se le cuelan, y no ve absolutamente nada en los casos de segundo orden, donde el valor malicioso llegó como texto corriente días antes. Compra tiempo; no es un arreglo.

¿Quieres ver cómo trabajamos en Asperis Security?

Agenda 30 minutos con uno de nuestros especialistas. Revisamos tu stack y te decimos qué conviene probar primero.