Si recuerdan el post que publicamos hace poco más de una semana titulado OWASP Top 10 2010. Release Candidate, éste iniciaba una serie de entradas a través de las que pretendemos mostrar en qué consiste cada una de las vulnerabilidades que forman el TOP 10 de OWASP, así como ofrecer algunas indicaciones y recomendaciones sobre la mejor forma de evitar que nuestras aplicaciones sufran estas conocidas vulnerabilidades. Con algo de retraso sobre la fecha prevista, he aquí el primero.
La vulnerabilidad más comúnmente explotada desde el año 2004 que OWASP lleva realizando esta clasificación es la inyección. Aunque la más común sea probablemente la Inyección de SQL, existen otros tipos de inyecciones que es posible que no nos resulten tan familiares: LDAP, XPath, XSLT, XML, OS injection, etc., y que al igual que la Inyección SQL se aprovechan de la sintaxis del interprete que se va a encargar de ejecutar una determinada acción. Las vulnerabilidad de inyección pueden permiten a un atacante obtener cualquier tipo de información disponible en la aplicación, pudiendo llegar a comprometer totalmente la aplicación, así como los sistemas relacionados con ésta. Y ya saben que de ahí al infinito y más allá.
Veamos el siguiente ejemplo como demostración del tipo de situaciones en los que podemos encontrar una inyección SQL. Sea una aplicación que dispone de un frontal web en el que se muestra un formulario. Al seleccionar el usuario una determinada categoría, pulsa el botón de buscar y le aparece el conjunto de artículos que contiene dicha categoría. Al pulsar sobre “Seleccionar”, se envía una petición al servidor del tipo:
Una vez recibida en el servidor, dicha petición se transforma en el siguiente código para obtener el listado de artículos de una determinada categoría:
Un atacante de nuestra plataforma podría modificar la petición esperada y solicitar información no controlada, por ejemplo:
De esta forma, el atacante podría obtener el listado de todos los artículos de la base de datos con una simple modificación que puede ser realizada directamente desde el navegador con, por ejemplo, el plugin Hack Bar de Firefox. Aunque esto parezca trivial y quizá en algún caso pueda interesar que un usuario se pase toda la tarde viendo mi página web para comprar un cabecero para su dormitorio, la cosa cambia sustancialmente cuando la información que se pretende mostrar son los ingresos de un trabajador o el grado de minusvalía de una determinada persona. Si a esto le añadimos la posibilidad de algunos sistemas gestores de base de datos de concatenar sentencias en una misma ejecución, el resultado podría ser la modificación de una tabla o incluso el borrado de la propia base de datos.
Pasando a otra tipología, veamos ahora una inyección de sistema operativo. Supongamos que en la interfaz de administración de la aplicación de catálogo comentada anteriormente existe una interfaz de administración que permite ejecutar unas tareas administrativas sobre el servidor, cuyo resultado es mejorar la indexación de las distintas bases de datos que componen la aplicación. Una vez seleccionada la base de datos, el usuario pulsa el botón de optimizar y se envía una petición al servidor del tipo:
Una vez recibida en el servidor, dicha petición se transforma en el siguiente código para optimizar la base de datos solicitada:
Cuando el proceso termina se envía un mensaje al espacio privado del usuario con el resultado de la ejecución. Un atacante de nuestra plataforma podría modificar la petición esperada y solicitar información no controlada, por ejemplo de la siguiente manera:
De esta forma, podría obtener el listado de todos los usuarios y sus contraseñas en su espacio de usuario, únicamente esperando a que el proceso termine su ejecución (seguro que en lugar de /etc/passwd pueden pensar alternativas mejores).
Aunque los ejemplos de vulnerabilidades se han mostrado siempre con peticiones GET, las aplicaciones son igualmente vulnerables a peticiones POST. Del mismo modo, estas vulnerabilidades son independientes del lenguaje utilizado en el servidor, aunque el uso de determinados frameworks puede mitigar la existencia de estas vulnerabilidades. Los dos ejemplos mostrados son sólo un par de situaciones en las que es posible encontrar vulnerabilidades de inyección, pero la filosofía es extensible al resto de tipos de inyecciones.
La primera manera de protegerse, independientemente del tipo de inyección que podamos sufrir, es asegurar que los datos que se utilizan para componer la visualización dinámica de la aplicación —aquella que depende de la petición del usuario— se encuentran correctamente validados antes de su interpretación. Es decir, si “estamos esperando” un número, se debe validar que el parámetro utilizado será un número, y si por el contrario esperamos una dirección de correo electrónico, utilizaremos ese dato únicamente si éste es conforme al formato establecido. En segundo lugar, es importante prestar especial atención a la existencia de determinadas secuencias de caracteres y cuando se presenten, “escaparlas” mediante las funciones apropiadas. Por último, la mayoría de lenguajes disponen de APIs con funciones diseñadas para proteger la aplicación, y que ofrecen la posibilidad de ejecutar consultas especialmente preparadas para evitar este tipo de problemas de seguridad.
Y hasta aquí todo lo referente a ataques de inyección, de momento. Como saben, si quieren extenderse en la materia, más allá de los innumerables recursos de la red, pueden acudir a la web de OWASP, donde encontrarán mucha información de utilidad. Si desean que demos más detalles sobre alguna de las vulnerabilidades mostradas, no tienen más que indicarlo en los comentarios.











Twitter! 