Todo lo que debes saber sobre inyección SQL (SQLi) – Ejemplos prácticos
Qué es una inyección SQL y cómo detectarla
La inyección SQL es una técnica de inyección de código para aplicaciones con conexión a una base de datos. Un usuario malintencionado envía una consulta SQL diseñada para extraer, agregar, modificar o eliminar datos de la base de datos.
Imaginemos que estás utilizando la función de búsqueda de una aplicación, utilizando la siguiente palabra clave para buscar: apple
https://vulnerableURL.com/images?search=apple
La siguiente consulta SQL se envía en segundo plano:
SELECT * from fruits WHERE name=’apple’
Agregaremos una sola comilla en la búsqueda, así: ?search=apple’ y se envía la siguiente consulta. La estructura de la consulta está esta:
SELECT * from fruits WHERE name='apple''
A partir de ahí, el atacante escribe una consulta UNION SQL para que la búsqueda tome el control de la consulta SQL. De esta manera la consulta le permite al atacante extraer información para la que no estaba prevista.
?search=apple’ UNION SELECT username, password FROM users —
SELECT * from fruits WHERE name=’apple’’ UNION SELECT username, password FROM users —
En esta circunstancia, se extraen los datos de nombre de usuario y contraseña de la tabla de usuarios en lugar de los resultados previstos.
¿Cuál es su impacto?
Las inyecciones de SQL son problemas muy críticos, ya que se pueden utilizar para extraer el contenido completo de la base de datos. Y, en algunos casos, se pueden aprovechar para ejecutar un comando en el servidor. Los payloads relacionadas para estos ataques te los mostraré en la hoja de trucos a continuación.
¿Cómo evito una inyección de SQL?
Para evitar inyecciones de SQL, asegúrate de que se realice una validación de entrada del lado del servidor adecuada. Debes hacer esto en todas las fuentes de entrada del usuario. Se deben implementar varias protecciones usando lo siguiente en orden de efectividad:
- Errores. Asegúrate de que los errores de SQL estén desactivados y no se muestren al usuario cuando se produzca un error. Esto para no exponer información valiosa a un atacante.
- Parametrizar consultas: Asegúrate de que cuando la entrada de un usuario se agrega a una consulta SQL de back-end, no se agrega una cadena, sino que se coloca en el parámetro SQL específico. El método para realizar esto varía de un lenguaje a otro.
- Longitud de entrada del lado del servidor. Debes limitar la longitud de cada campo según su tipo. Por ejemplo, un nombre debe tener menos de 16 caracteres y un ID debe tener menos de 5 caracteres.
- Lista blanca. Debes crear rangos de caracteres (es decir, numéricos, alfabéticos, alfanuméricos, alfanuméricos con caracteres específicos). También asegúrate de que cada entrada esté restringida a la lista blanca de longitud mínima necesaria.
- Lista negra. No debes permitir los caracteres de inyección comunes como “<>\/?*()& y comandos SQL y SCRIPT como SELECT, INSERT, UPDATE, DROP, y SCRIPT. Tampoco permitas caracteres nulos%00 y esquemas de codificación innecesarios o incorrectos (Por ejemplo, ASCII, UTF-7, UTF-8, UTF-16, Unicode, etc.).
- Registros e IDS/IPS (Sistema de Prevención/Detección de Intrusiones) específico de la Web. Asegúrate de realizar un registro adecuado y de que se esté revisando, y que cualquier tráfico malicioso que genere una alerta se limite de inmediato. Finalmente, esto se debe incluir en la lista negra.