Protección contra la inyección SQL

Protección contra la inyección SQL

07.12.2022
Autor: HostZealot Team
2 min.
866

En este artículo, contaremos cómo funciona la inyección SQL, lo peligrosos que son estos ataques y consideraremos los mecanismos y métodos de protección. Cabe señalar de antemano que, con el enfoque adecuado, puede cortar fácilmente incluso la más mínima posibilidad de que los atacantes tengan éxito. Si no se hace nada, los ataques de inyección SQL pueden causar graves daños a su servidor web.

Qué es una inyección SQL y cómo funciona

La inyección SQL es una forma común de piratear sitios y software que ejecutan bases de datos (BD). El método se reduce a introducir código SQL arbitrario, que finalmente permitirá al hacker interactuar con los datos de la base de datos de diversas maneras:

  • leer el contenido;
  • borrar datos;
  • añadir nuevos datos.

Además, en algunos casos, un atacante puede obtener acceso para leer y escribir archivos locales en el servidor, ejecutar comandos arbitrarios, etc.

Esto ocurre de la siguiente manera. La mayoría de los sitios tienen bases de datos donde se almacena toda la información. Cuando un visitante intenta cargar una página, se envía una consulta a la base de datos. Y eso estaría bien, pero el usuario puede modificar la consulta - en el proceso de creación de un comentario, durante una búsqueda, o incluso simplemente al cambiar de una página a otra. Estas consultas son una ventana de oportunidad para la inyección SQL. Se desencadena una acción no prevista por el creador del script. Veamos un ejemplo.

La mujer deja una nota para que su marido le dé algo de dinero a Nicolás, dejándola sobre la mesa de la cocina. Una posible consulta SQL podría ser la siguiente:

SACA 10 DÓLARES DE TU BOLSA Y DEJÁSELO EN LA MESA A Nicolás

Una vez hecho esto, la mujer dejó la nota sobre la mesa y se fue a trabajar. Maria, la hermana de Nicolás, se despertó, vio la nota y puede añadir unas palabras con letra parecida:

SACA 10 DÓLARES DE TU CARTERA Y DÉJALOS EN LA MESA PARA Nicolás O Maria

Cuando mi marido se despertó, no se lo pensó dos veces y decidió que los dos niños sabían para qué era el dinero. Cuando vio a Maria, le dijo que el dinero estaba sobre la mesa y dejó que lo cogiera.

Maria se salió con la suya por medios injustos, pero al final, ella tiene el dinero y Nicolás se queda sin nada. Este es un ejemplo sencillo de inyección SQL pero en palabras sencillas.

Ahora veamos un ejemplo más realista. Esto es lo que parece una consulta ID estándar en una búsqueda:

SELECT id,title,content FROM posts WHERE title LIKE '%user’s_query%'

Pero ahora imaginemos que en lugar de las palabras clave estándar el usuario introduce la siguiente combinación:

1%'; DROP TABLE posts LIKE '%;

El resultado será una consulta viable que el desarrollador de la base de datos no podía prever:

SELECT id,title,content FROM posts WHERE title LIKE '%1%'; DROP TABLE posts LIKE '%%'

Este esquema puede funcionar con cualquier consulta en la que se introduzcan datos del usuario, siempre que los desarrolladores o especialistas en seguridad no hayan previsto los mecanismos de seguridad necesarios. En este caso, basta con escapar todas las comillas en las consultas del usuario para resolver el problema. A continuación, veremos las principales formas de protegerse contra la inyección SQL.

Protección de su sitio contra la inyección SQL a nivel de código de programa

Cuando se utiliza el lenguaje de programación PHP, las comillas pueden escaparse con estas funciones:

  • mysql_real_escape_string;
  • mysqli_real_escape_string.

Siempre que se filtren todas las variables utilizadas en las consultas a la base de datos, no habrá ningún problema. Sólo es importante filtrar a nivel de CMS o código de programa.

El problema es que se tarda mucho menos en crear consultas de base de datos inseguras que en crear consultas seguras, con escapes. Y debido a esto, muchos sitios son vulnerables.

protección contra la inyección sql

Configurar la protección del servidor web

Si no puede refinar el código, puede filtrar todos los valores de la variable REQUEST al principio del script. Para ello, utilice el siguiente código:

if (!function_exists("clean")) {
if (get_magic_quotes_gpc()) {
function magicquotes_Stripslashes(&$value, $key) {
$value = stripslashes($value);
}
$gpc = array(&$_COOKIE, &$_REQUEST);
array_walk_recursive($gpc, 'magicquotes_Stripslashes');
}
function clean(&$value, $key) {
//this function escapes all quotation marks.
$value = mysql_real_escape_string($value);
}
}
$req = array(&$_REQUEST);

array_walk_recursive($req, 'clean');

Cuando se utiliza PHP 7, se debe utilizar la función mysqli_real_escape_string ya que la extensión mysql ha sido eliminada a partir de esta versión. Las comillas se escapan con la función clean y todo el código de abajo.

A continuación, puede añadir algunas reglas a la sección del servidor para proteger el servidor web. Aquí hay un ejemplo para usuarios de Nginx:

set $block_sql_injections 0;
if ($query_string ~ "union.*select.*\(") {
set $block_sql_injections 1;
}
if ($query_string ~ "union.*all.*select.*") {
set $block_sql_injections 1;
}
if ($query_string ~ "concat.*\(") {
set $block_sql_injections 1;
}
if ($block_sql_injections = 1) {
return 403;

}

Esta es una buena forma de filtrar todas las consultas que contengan las palabras select y concat entre comillas. Esta es una señal segura de que se está intentando una inyección SQL, y todas esas consultas deben ser bloqueadas.

También es posible bloquear direcciones sospechosas a nivel del servidor web Apache. El problema es que bloquear algunas palabras clave SQL de uso frecuente también puede bloquear peticiones de usuarios normales, por lo que hay que tener cuidado en este punto. Si está seguro de que esto es necesario, puede añadir unas líneas a la sección VirtualHost:

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

RewriteRule (.*) - [F]

Y por último, active el módulo mod_security:

sudo a2enmod mod_security

Utilice todos los métodos anteriores juntos para lograr la mayor eficacia en términos de protección contra la inyección SQL.

Partición de bases de datos

Otra buena forma de aumentar la seguridad de la base de datos es dividirla en 2-4 partes, aplicando el principio de privilegios mínimos. La idea es que los usuarios y los programas individuales sólo tengan acceso a la información que necesitan, ni más ni menos.

Como resultado de la división, la base de datos se reorganiza en dos archivos: la base de datos del servidor, que contiene tablas con datos, y la base de datos del cliente, que almacena todos los demás objetos: solicitudes, formularios, informes, datos de tarjetas de crédito, etc. Además del hecho de que aumenta el grado de protección contra la inyección SQL, la separación de la base de datos también tiene un impacto positivo en el rendimiento del servidor web, ya que sólo los datos se envían a través de la red.

Utilización de sistemas de protección avanzados

Otra opción fiable es utilizar soluciones de hardware que se ejecuten sobre iptables o ipfw. Existen varios sistemas de detección de intrusiones en servidores HIDS, incluido el popular OSSEC. Sí, esta solución es más complicada en términos de implementación, pero la eficacia para bloquear este tipo de ataques es cercana al 100%.

Resumen

Por último, cabe señalar que lo mejor es utilizar varios métodos en combinación. E incluso en este caso, el cien por ciento de protección contra la inyección SQL no se puede garantizar - vulnerabilidades siempre pueden ser. Con cada nueva versión de los desarrolladores de lenguaje PHP mejorarlo mediante la eliminación de las diversas vulnerabilidades, por lo que no se olvide de las actualizaciones periódicas del software. Ese es el final de nuestro artículo, y gracias por su atención. ¡Que tenga un buen día!

Artículos Relacionados