Ataques de Inyección SQL (II)

Antes del pertinente, necesario, deseado y siempre corto descanso veraniego, recordarán que estuvimos hablando de ataques de Inyección SQL, utilizados al parecer en los ataques a la delegación de Microsoft en el Reino Unido el mes de junio y a la página Web de la ONU hace unas semanas.

Como les dijimos literalmente aquella vez, los ataques de inyección SQL se basan en explotar la interacción con el usuario ofrecida por aplicaciones Web (formularios de petición de datos, por ejemplo), para hacer llegar a la base de datos consultas SQL manipuladas. Y las principales herramientas utilizadas para ello son los caracteres que dentro de SQL sirven para declarar cadenas de texto: las comillas simples (‘) y los caracteres que introducen comentarios en el código (––), igual que en cualquier código fuente. Pues bien, los atacantes suelen aprovechar este tipo de caracteres para incrustar código aleatorio y conseguir validar cualquier sentencia manipulada. Vamos a ver un ejemplo:

Sea la siguiente sentencia para mostrar el perfil de un determinado usuario en una página web:

SELECT * FROM users WHERE name = '"+ userName +"';

El atacante manipula la sentencia de esta manera…

SELECT * FROM users WHERE name = 'a' or 't'='t';

(En rojo y negritas, código inyectado por el atacante)

Mientras que la sentencia anterior debería mostrar las características de un único usuario, al incrustar el atacante un operador “or” con una condición que siempre es cierta, consigue que la sentencia sea cierta para todos los usuarios, devolviendo la base de datos por tanto todos los datos de la tabla users.

Como medida de seguridad, los distintos entornos de programación poseen ciertas funciones en las que se revisa estos tipos de entrada para evitar que lleguen a la base de datos. Por poner algunos ejemplos, en PHP por ejemplo existe la función mysql_real_escape_string para MySQL, en JAVA tenemos la función PreparedStatement, en Mono y C# de .NET se trata con las funciones SqlCommand (para Microsoft SQL Server) y OracleCommand (para gestores Oracle). De esta forma, si validamos tanto las entradas de primer orden como las de segundo, es decir, no sólo los posts, gets, cookies, sino también las que provienen de lectura de ficheros, bases de datos, etc… conseguimos filtrar instrucciones no deseadas, errores por tipos de datos, y manejo de tablas de la base de datos.

Como complemento de la seguridad en la aplicación, es recomendable generar las consultas de forma estática en la medida de lo posible, es decir, si predefinimos las consultas obligaremos al usuario de la aplicación únicamente a interactuar con los parámetros, por lo que no existe la posibilidad de que éste modifique las sentencias.

Hay muchas otras recomendaciones, como por ejemplo no acceder a la base de datos desde la aplicación con una cuenta de usuarios con privilegios de administrador, o hacer un uso restringido y controlado de los llamados “procedimientos almacenados”, pero de eso hablaremos en la tercera parte de esta serie.