Inyección SQL: Anatomía de una Vulnerabilidad
💡 El Tip Rápido
Recuerda: Nunca confíes en la entrada del usuario. Sanitiza siempre tus datos.
¿Qué es la Inyección SQL (SQLi)?
La Inyección SQL es una técnica de manipulación de datos que ocurre cuando un atacante logra insertar código SQL malicioso en una consulta a través de los campos de entrada de una aplicación. Si la aplicación no filtra correctamente estos datos, el motor de la base de datos ejecutará el código del atacante como si fuera una instrucción legítima. Es, históricamente, una de las vulnerabilidades más críticas debido a que permite el robo masivo de información.
Tipos de Ataques SQLi
- In-band (Classic): El atacante usa el mismo canal de comunicación para lanzar el ataque y ver los resultados (ej. errores de SQL que revelan nombres de tablas).
- Inferential (Blind): El atacante no ve los datos directamente, pero hace preguntas de 'sí o no' a la base de datos (ej. '¿empieza la contraseña del admin por A?') y observa la respuesta de la web o el tiempo de carga.
- Out-of-band: El atacante obliga a la base de datos a realizar una conexión externa (como una petición HTTP o DNS) para extraer los datos.
El Concepto de 'Tautología'
El ejemplo más clásico es el uso de una tautología (una afirmación siempre verdadera). En un formulario de login, un atacante podría escribir ' OR '1'='1 en el campo de usuario. La consulta resultante se convierte en:
SELECT * FROM usuarios WHERE username = '' OR '1'='1' AND password = '...'.
Como '1'='1' siempre es verdad, la base de datos devuelve el primer registro (generalmente el administrador), permitiendo el acceso sin contraseña.
Prevención Técnica: Sentencias Preparadas
La única defensa real y definitiva es el uso de Sentencias Preparadas (Prepared Statements) con parámetros vinculados. En este modelo, la consulta SQL se envía primero al servidor de base de datos para ser 'pre-compilada' con marcadores de posición (?). Los datos del usuario se envían después como parámetros puros, por lo que el motor de la base de datos nunca los interpreta como código, tratándolos simplemente como texto plano.
📊 Ejemplo Práctico
Escenario Real: Reparando un Formulario Vulnerable en PHP
Tienes un buscador en tu web que es vulnerable a SQLi porque concatena variables directamente en la consulta.
Paso 1: Identificación del fallo. El código actual es:
$db->query("SELECT * FROM productos WHERE nombre = '" . $_GET['buscar'] . "'");.
Si alguien busca x'' OR 1=1 --, obtendrá toda la base de datos de productos, incluyendo los ocultos.
Paso 2: Implementación de PDO. Cambiamos el código para usar el objeto PDO de PHP.
$stmt = $pdo->prepare('SELECT * FROM productos WHERE nombre = ?');
$stmt->execute([$_GET['buscar']]);
$resultados = $stmt->fetchAll();.
Paso 3: Verificación. Ahora, si el atacante intenta inyectar ' OR 1=1, la base de datos buscará literalmente un producto cuyo nombre sea la cadena de texto "' OR 1=1". Como no existe, no devolverá nada y el ataque habrá fallado.
Paso 4: Capas de defensa. Complementamos esto con un WAF (Web Application Firewall) que detecte patrones sospechosos de SQL en las peticiones entrantes como medida de seguridad en profundidad.