Mitigación y Prevención de SQL Injection
📌 Introducción
Después de estudiar cómo ocurre y se explota una SQL Injection, es fundamental aprender cómo prevenirla y cómo mitigarla correctamente en nuestras aplicaciones. Las técnicas incluyen sanitización, validación, consultas parametrizadas, privilegios mínimos y controles adicionales como WAF.
🧹 Sanitización de entrada
Incluir directamente valores de entrada del usuario dentro de una consulta SQL permite que un atacante inyecte código.
Ejemplo vulnerable:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM logins WHERE username='". $username. "'
AND password = '" . $password . "';" ;
📌 Solución: escapar los caracteres especiales con mysqli_real_escape_string():
$username = mysqli_real_escape_string($conn, $_POST['username']);
$password = mysqli_real_escape_string($conn, $_POST['password']);
Escapa caracteres como ' y ", haciendo que pierdan su significado especial en SQL.
🧪 Validación de entrada
Otra defensa es validar que la entrada coincide con lo esperado.
Ejemplo vulnerable:
$q = "Select * from ports where port_code ilike '%" . $_GET["port_code"] . "%'";
Como port_code solo debería tener letras y espacios, se valida con regex:
$pattern = "/^[A-Za-z\s]+$/";
$code = $_GET["port_code"];
if(!preg_match($pattern, $code)) {
die("Invalid input! Please try again.");
}
-
[A-Za-z\s]+→ solo letras y espacios -
Cualquier otro carácter → entrada rechazada
🔐 Privilegios del usuario
La cuenta conectada al DBMS debe tener el mínimo privilegio necesario.
Ejemplo de creación de un usuario seguro:
CREATE USER 'reader'@'localhost';
GRANT SELECT ON ilfreight.ports TO 'reader'@'localhost'
IDENTIFIED BY 'p@ssw0Rd!!';
Al iniciar sesión como reader:
-
Puede consultar solo la tabla necesaria (
ports) -
No puede consultar otras tablas como
credentials
Incluso si existe SQL Injection, la explotación queda muy limitada por permisos.
🔥 Firewall de Aplicaciones Web (WAF)
Los WAF ayudan a detener ataques automáticamente, incluso cuando la lógica de la aplicación es insegura.
Ejemplos:
-
ModSecurity (open source)
-
Cloudflare WAF (premium)
Un WAF no reemplaza una buena validación/sanitización interna, pero ayuda a bloquear cadenas sospechosas como:
-
INFORMATION_SCHEMA -
UNION SELECT -
' OR 1=1 --
🔒 Consultas Parametrizadas (Prepared Statements)
Es la solución más efectiva para evitar SQL Injection.
Ejemplo seguro:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM logins WHERE username=? AND password=?";
$stmt = mysqli_prepare($conn, $query);
mysqli_stmt_bind_param($stmt, 'ss', $username, $password);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result);
mysqli_stmt_close($stmt);
Los valores no se interpretan como código SQL, sino como datos.
🏁 Conclusión
-
La mitigación de SQL Injection requiere varias capas de defensa.
-
Las técnicas vistas aplican a cualquier lenguaje o framework:
-
✔ Sanitización
-
✔ Validación
-
✔ Privilegios mínimos
-
✔ WAF
-
✔ Consultas parametrizadas (lo más seguro)
-
-
La defensa nunca depende de una sola técnica.