Saltar al contenido
BeoHosting
BeoHosting
Seguridad

Cómo reconocer y prevenir la inyección SQL

BeoHosting Team··11 min de lectura de lectura
Cómo reconocer y prevenir la inyección SQL

Qué es la inyección SQL

La inyección SQL (SQLi) es uno de los tipos de ataque más antiguos y peligrosos contra las aplicaciones web. El ataque funciona inyectando código SQL malicioso en los campos de entrada (formularios, parámetros de URL, cookies) que la aplicación utiliza para construir consultas SQL a la base de datos. Si la aplicación no valida ni sanea la entrada del usuario antes de incrustarla en una consulta SQL, el atacante puede manipular la consulta para leer, modificar o eliminar datos de la base de datos.

Según la lista OWASP Top 10, los ataques de inyección llevan años entre las tres vulnerabilidades web más críticas. Un ataque de inyección SQL exitoso puede dar lugar al robo de toda la base de datos (cuentas de usuario, contraseñas, datos personales), a la modificación o eliminación de datos, a la elusión de la autenticación (acceso sin contraseña), a la ejecución de comandos en el sistema operativo del servidor y al compromiso total del servidor.

Cómo funciona la inyección SQL

Principio básico

Imagina un formulario de inicio de sesión que comprueba un nombre de usuario y una contraseña. La aplicación construye una consulta SQL parecida a esta: SELECT * FROM users WHERE username = 'nombre_introducido' AND password = 'contraseña_introducida'. Si la aplicación simplemente inserta la entrada del usuario en la consulta sin ninguna comprobación, el atacante puede introducir un valor especial en el campo del nombre de usuario que cambie la lógica de la consulta. Por ejemplo, una entrada que contenga un apóstrofo seguido de código SQL puede cerrar el literal de cadena y añadir una condición que siempre sea verdadera, eludiendo así la comprobación de la contraseña.

Tipos de ataques de inyección SQL

Existen varios tipos de ataques de inyección SQL. La SQLi in-band es la más común, en la que el atacante usa el mismo canal de comunicación para enviar el ataque y recibir los resultados. Se divide en SQLi basada en errores (utiliza los mensajes de error de la base de datos para extraer información) y SQLi basada en UNION (utiliza el operador UNION para combinar los resultados de una consulta maliciosa con una legítima). La SQLi ciega (blind) es un tipo en el que el atacante no ve resultados directos, pero puede inferir información a partir del comportamiento de la aplicación. La SQLi ciega basada en booleanos envía consultas que devuelven verdadero o falso e infiere los datos carácter a carácter según las diferencias en las respuestas. La SQLi ciega basada en tiempo utiliza funciones de pausa SQL (SLEEP, WAITFOR DELAY) para determinar si una condición es verdadera según el tiempo de respuesta. La SQLi out-of-band utiliza un canal diferente para la exfiltración de datos, como peticiones DNS o HTTP que la base de datos envía al servidor del atacante.

Detectar vulnerabilidades de inyección SQL

Pruebas manuales

La forma más sencilla de probar la existencia de vulnerabilidades de inyección SQL es inyectar caracteres especiales en los campos de entrada. El apóstrofo (') es la primera prueba: si la aplicación devuelve un error de base de datos, existe una posible vulnerabilidad. Un doble apóstrofo ('') no debería provocar un error si uno solo lo provocaba. Los comentarios SQL (-- o #) se pueden utilizar para comentar el resto de la consulta. Los operadores lógicos (OR 1=1, AND 1=2) pueden revelar vulnerabilidades basadas en booleanos. El comando SLEEP ('; WAITFOR DELAY '0:0:5'--) revela vulnerabilidades basadas en tiempo si la página retrasa su respuesta.

Herramientas automatizadas

Para realizar pruebas sistemáticas, utiliza herramientas especializadas. SQLMap es la herramienta de código abierto más conocida para la detección y explotación automáticas de vulnerabilidades de inyección SQL: admite todos los tipos de SQLi y la mayoría de las bases de datos. Burp Suite Professional incorpora un escáner de inyección SQL y otras vulnerabilidades web. OWASP ZAP es una alternativa gratuita a Burp Suite con un sólido escáner de SQLi. Acunetix y Netsparker son escáneres comerciales de vulnerabilidades web con detección avanzada de SQLi.

Señales de un compromiso

Si sospechas que tu sitio ya ha sido objetivo de una inyección SQL, comprueba lo siguiente: entradas inusuales en los registros del servidor web (URL con palabras clave SQL), cuentas de usuario nuevas o modificadas en la base de datos (especialmente cuentas de administrador), datos modificados sin tu conocimiento, archivos nuevos en el servidor (web shells) y un aumento del tráfico hacia páginas concretas con parámetros inusuales. Revisa también los archivos de registro de la base de datos en busca de consultas inesperadas.

Prevención: sentencias preparadas

Qué son las sentencias preparadas

Las sentencias preparadas (consultas parametrizadas) son la protección más eficaz contra la inyección SQL. En lugar de insertar la entrada del usuario directamente en una consulta SQL como texto, una sentencia preparada separa la estructura de la consulta de los datos. Primero se define la estructura de la consulta con marcadores de posición para los datos y, a continuación, los datos se envían por separado. La base de datos trata los datos únicamente como valores, nunca como código SQL, lo que hace imposible la inyección.

Implementación en diferentes lenguajes

PHP con PDO (PHP Data Objects) usa el método prepare() para preparar una consulta con marcadores de posición (:username, :password) y execute() con un array de valores. La extensión MySQLi admite sentencias preparadas con marcadores de posición ? y bind_param() para vincular valores con tipos de datos. Python con sqlite3 o psycopg2 utiliza marcadores ? o %s. Java usa la clase PreparedStatement con los métodos setString(), setInt(). Las bibliotecas de Node.js como mysql2 y pg admiten consultas parametrizadas con marcadores ? o $1. Independientemente del lenguaje de programación, el principio es el mismo: nunca concatenes la entrada del usuario con una consulta SQL como cadenas.

Métodos de prevención adicionales

Validación de entradas

Además de las sentencias preparadas, valida siempre la entrada del usuario. La validación por lista blanca solo permite los valores esperados: si un campo debe contener un número, verifica que realmente lo sea antes de procesarlo. Para los campos de texto, restringe los caracteres permitidos, la longitud de la entrada y el formato (regex). Nunca confíes únicamente en la validación del lado del cliente (JavaScript), porque un atacante puede eludirla: la validación debe implementarse en el servidor.

Procedimientos almacenados

Los procedimientos almacenados son código SQL guardado y ejecutado en el servidor de la base de datos. Cuando están bien escritos (sin SQL dinámico dentro del procedimiento), proporcionan una capa de protección adicional, porque la aplicación llama al procedimiento con parámetros en lugar de enviar consultas SQL en bruto. Sin embargo, los procedimientos almacenados por sí mismos no garantizan la seguridad: si los procedimientos construyen internamente consultas dinámicas a partir de parámetros, la vulnerabilidad sigue existiendo.

ORM (Object-Relational Mapping)

Las bibliotecas ORM como Eloquent (Laravel), SQLAlchemy (Python), Hibernate (Java) y TypeORM (Node.js) utilizan automáticamente sentencias preparadas para todas las consultas, eliminando la mayor parte del riesgo de inyección SQL. No obstante, la mayoría de los ORM permiten consultas SQL en bruto para operaciones complejas: en esos casos debes usar sentencias preparadas manualmente. Un ORM no sustituye al conocimiento de la seguridad SQL, pero reduce significativamente la superficie de ataque.

Principio de privilegios mínimos

Configura la base de datos para que la aplicación use una cuenta con los privilegios mínimos necesarios. Una aplicación web suele necesitar privilegios SELECT, INSERT, UPDATE y DELETE sobre tablas concretas. No concedas a la cuenta de la aplicación privilegios DROP, ALTER, CREATE o FILE. Si un atacante logra una inyección SQL, los privilegios restringidos impiden eliminar tablas, modificar la estructura de la base de datos y acceder al sistema de archivos del servidor.

Protección WAF contra la inyección SQL

Cómo detecta un WAF la SQLi

Un Web Application Firewall (WAF) analiza las peticiones HTTP y bloquea las que contienen patrones de inyección SQL. El WAF reconoce palabras clave SQL en lugares inesperados (SELECT, UNION, DROP en los parámetros de la URL), caracteres especiales usados en ataques SQLi (apóstrofos, comentarios, operadores lógicos), payloads SQLi conocidos de una base de datos de firmas y anomalías en la estructura de la petición que indican un intento de inyección.

Limitaciones del WAF

Un WAF no sustituye al código seguro. Los atacantes experimentados pueden eludir un WAF mediante técnicas de codificación (codificación de URL, Unicode, doble codificación), comentarios y espacios para romper las firmas, sintaxis SQL alternativas que el WAF no reconoce y pruebas incrementales para determinar qué reglas usa el WAF. El WAF es una capa de protección adicional (defensa en profundidad), pero la protección principal debe estar en el código de la aplicación mediante sentencias preparadas y validación de entradas.

Inyección SQL en WordPress

Mecanismos de protección de WordPress

El núcleo de WordPress usa el método $wpdb->prepare() para todas las consultas a la base de datos, que es la implementación de sentencias preparadas de WordPress. Este método utiliza marcadores de posición al estilo sprintf (%s para cadenas, %d para enteros, %f para decimales) y escapa automáticamente los valores. Sin embargo, las vulnerabilidades aparecen con mayor frecuencia en plugins y temas que no usan $wpdb->prepare() o que construyen consultas concatenando cadenas manualmente.

Proteger un sitio WordPress

Para proteger un sitio WordPress de la inyección SQL, actualiza con regularidad el núcleo de WordPress, los plugins y los temas, porque los parches de seguridad a menudo corrigen vulnerabilidades de SQLi. Usa solo plugins y temas de fuentes de confianza (el repositorio de WordPress.org, proveedores comerciales reconocidos). Instala un plugin de seguridad (Wordfence, Sucuri, iThemes Security) que incluya protección WAF. Consulta también nuestra guía para proteger un sitio de los hackers. Elimina los plugins y temas que no utilices, porque incluso los plugins desactivados pueden ser explotados. Restringe el acceso a la base de datos: WordPress solo necesita un usuario con acceso a su base de datos.

Errores comunes que dejan un sitio vulnerable

  • SQL dinámico en el código: concatenar la entrada del usuario con una consulta SQL como cadena es la principal causa de las vulnerabilidades de inyección SQL. Usa siempre sentencias preparadas.
  • Confiar en la validación del lado del cliente: la validación de JavaScript se puede eludir; toda la validación debe existir en el servidor.
  • Mensajes de error detallados: mostrar errores SQL a los usuarios revela la estructura de la base de datos y facilita el ataque. En producción, registra los errores internamente y muestra un mensaje genérico a los usuarios.
  • Software desactualizado: las versiones antiguas de CMS, frameworks y bibliotecas suelen tener vulnerabilidades SQLi conocidas con exploits disponibles públicamente.
  • Un único usuario de base de datos para todo: usar una cuenta root para la aplicación le da al atacante el control total de la base de datos en caso de un ataque exitoso.

Conclusión

La inyección SQL es una amenaza grave que puede comprometer por completo tu sitio y los datos de los usuarios. La prevención es relativamente sencilla: usa sentencias preparadas para todas las interacciones con la base de datos, valida la entrada del usuario en el servidor, aplica el principio de privilegios mínimos y mantén el software actualizado. Un WAF proporciona una capa de protección adicional, pero no sustituye al código seguro. Con el hosting de BeoHosting, todos los servidores incluyen un WAF ModSecurity configurado que detecta y bloquea los intentos de inyección SQL, pero recomendamos que tu código también siga las mejores prácticas de codificación segura.

BeoHosting Team

10+ años de experiencia — Especialistas en alojamiento web e infraestructura

  • Web Hosting
  • WordPress Hosting
  • VPS
  • Dedicated Serveri
  • Domeni
  • SSL
  • cPanel
  • LiteSpeed
  • Linux administracija
  • DNS

Última actualización: