Llegamos a ustedes gracias a:



Columnas de opinión

No más excusas para los ataque de inyección de SQL

Por: Kenneth van Wyk, presidente y consultor socio de KRvW Associates LLC

[04/09/2009] Deberíamos haber erradicado los ataques de inyección SQL para este momento1. La inyección SQL debería ser como el sarampión o la polio para la Internet, que se han ido para siempre. Las contramedidas se encuentran listas y disponibles y son entendibles. Son fáciles de implementar. Y aún así sigo viendo titulares como Enorme ataque web infectó 500 mil páginas.

Los ataques de inyección SQL continúan siendo de los más fructíferos contra los sitios web y aplicaciones. Y ¿por qué no? Desde la perspectiva de un atacante, la base de datos que se encuentra detrás de muchas aplicaciones web, es donde se encuentran los objetivos más jugosos. Ese es el lugar en donde encontrará los registros de los clientes, los números de tarjetas de crédito y otros materiales interesantes.
Y ahora los atacantes han comenzado a utilizar la inyección SQL para plantar malware en sitios web, de tal forma que las computadoras de los visitantes de estos sitios se infectan con el malware. Las bases de datos no solo son los lugares en donde se encuentran los objetivos jugosos; ellas se encuentran en condiciones como para plantar datos maliciosos que infectan las computadoras de otras personas.
Esto incrementa el desafío y hace que sea más urgente el pedido de que se erradiquen todos los defectos de inyección existentes. Debemos asegurarnos que ninguna aplicación futura tenga defectos de inyección. Veamos esto más de cerca para saber que implica.
SQL, o Structured Query Language, es un lenguaje de base de datos interpretado que es comunmente usado por los servidores de aplicaciones, cuando hablan con los servidores de bases de datos. Las bases de datos es en donde, como dije, almacenamos cosas como los registros de los clientes. Un registro puede estar compuesto por el nombre del cliente, dirección, correo electrónico, número telefónico, e información de la tarjeta de pagos.
Para ver los datos del cliente en una base de datos, se construye un query o consulta en el servidor de aplicaciones y se envia a la base de datos, la cual retornaría la información de ese cliente y nada más. El query se vería como algo así:
select * from customers where last_name='Smith'</
Entonces, ¿cuál es el problema? Bueno, en los servidores de aplicaciones, el nombre del cliente generalmente se encuentra representado por una variable con un valor que ingresa a la aplicación vía un formulario web, siendo los datos provenientes del usuario de la aplicación. Así, en Java, el query podría estar construido algo así:
String query = "Select * from customers where last_name='" + req.getParameter("lastName") + "'";</
¿Ya ve el problema? Bueno, en el caso de funcionamiento normal, un usuario ingresa un apellido como Smith en ese campo, pero un atacante podría ingresar fácilmente un valor de "' or '1'='1'-". Lo cual produciría un query como el que se ve a continuación, que se envía al servidor:
select * from customers where last_name='' or '1'='1'</
Esa expresión booleana (last_name='' or '1'='1') siempre va a ser cierta, lo cual daría como resultado que la base de datos responda con todo el contenido de la tabla de datos del cliente. Eso es, nuestro atacante probablemente ha tenido éxito en la extracción de los datos de cada uno de nuestros clientes. Nada bueno.
Pero digo que el problema es fácil de resolver. Veamos, el problema subyacente en el escenario anterior, es que el propósito de la lógica de la SQL puede ser alterado por datos de usuario maliciosamente formados. Pero Java y la mayoría de los lenguajes relacionados a la web, nos proporcionan una solución simple llamada queries parametrizados.
En un query parametrizado, los datos son pasados al query de SQL como datos verdaderos, no como parte de la propia sintaxis de la SQL. Se requiere solo de un poco más de esfuerzo para configurar el query, pero luego ya está listo, y cualquier dato proporcionado por un atacantes no podrá hacer nada para alterar el propósito de nuestra consulta.
Aquí está la forma en que nuestra consulta anterior se vería si usamos el mecanismo de query parametrizado de Java, conocido como declaraciones preparadas:
String lastName = req.getParameter("lastName"); String query = "Select * from customers where last_name = ?" PreparedStatement pstmt = connection.prepareStatement( query ); pstmt.setString(1, lastName ); try { ResultSet results = pstmt.execute( ); }</
Bueno, hay unas cuantas líneas más de código, pero es un patron simple para seguir. Y los resultados son funcionalmente idénticos a la forma vulnerable, pero sin la vulnerabilidad.
Si simplemente vamos por nuestras aplicaciones web y cambiamos todos nuestros queries SQL en una forma de declaración preparada, podemos evitar todas las debilidades de la inyección SQL del mundo. De verdad.
Aún tenemos suficientes problemas sobre otros temas para tratar, como el scripting intersitios (también conocido como XSS), pero habremos eliminado este tema de la inyección SQL por completo.
Sé lo que debe estar pensando: no puede ser así de simple, de otra forma hubiésemos desaparecido la inyección SQL hace años. Eso sería solo una verdad parcialmente cierta. A nivel técnico, es simple. Pero a nivel humano, no mucho.
Para reparar el problema de una inyección SQL, tienen que existir muchos pre requisitos. Uno, necesitamos tener acceso al código fuente de la aplicación. Si nuestra aplicación ha sido producto de un outsourcing, o si estamos confiando en el código de un tercero, ya no sería tan simple.
Y ese es solo uno de los problemas humanos que he escuchado como excusas para no reperar un defecto de seguridad. Hay muchos otros.
Pero vamos, chicos, merecemos algo mejor que el status quo. Nuestras compañías merecen algo mejor; nuestros usuarios se merecen algo mejor. Paremos de dar excusas y comencemos a dar razones. Convierta en una meta usar sus aplicaciones web y erradicar todas estas debilidades de inyección SQL. Y mientras está ahí, asegúrese de enseñar a todos y cada uno de sus desarrolladores de software cómo hacer llamadas seguras al SQL.
Nada más inyección de SQL. No más excusas.
1 Una inyección SQL sucede cuando se inserta o "inyecta" un código SQL "invasor" dentro de otro código SQL para alterar su funcionamiento normal, y hacer que se ejecute maliciosamente el código "invasor" en la base de datos.
Con más de 20 años en el campo de la seguridad de la información, Kenneth van Wyk ha trabajado en el CERT/CC de la Universidad Carnegie Mellon, el Departamento de Defensa, Para-Protect y otros. Ha publicado dos libros sobre seguridad de la información y está trabajando un tercero. El es el presidente y consultor socio de KRvW Associates LLC en Alexandria, Virginia.
Computerworld (US)