Español | English
rss facebook linkedin Twitter

HQL Injection

Durante los últimos años dentro del lenguaje de programación orientado a objetos se han puesto de moda los ORM (Object-Relational Mapping). Estas herramientas nos permiten virtualizar el contenido de base de datos relacionales en forma de objetos. Hay pros y contras en su uso, defensores y detractores de este tipo de soluciones, pero si se decide utilizar una de ellas debemos conocer como su uso, debido a la existencia de amenazas de tipo SQL Injection , puede llegar a comprometer la seguridad de nuestras aplicaciones.

Comúnmente se piensa que por el hecho de utilizar un ORM nuestras aplicaciones ya son inmunes, y desde luego no es así. En muchas ocasiones está en manos del programador el que se pueda evitar declarar alguna jornada de puertas abiertas.


¿Qué es HQL? Existe un ORM en concreto compatible con leguajes Java y .Net llamado Hibernate. Esta herramienta dispone de un lenguaje de consulta HQL que acepta sentencias sql nativas con prácticamente todas sus clausulas (DELETE ,DROP….), así como otros elementos específicos del lenguaje, lo que hace que hibernate sea susceptible de sufrir ataques que podríamos denominar “HQL Injection”.

Una de las recomendaciones más importantes a la hora de evitar este tipo de ataque es el uso de "Prepared Statements", sentencias parametrizadas que permiten que en el paso de parámetros estos no sean interpretados. Hibernate por defecto en la mayoría de los casos utiliza este tipo de sentencias, pero ¿quiere eso decir que ya no nos debemos preocupar? La respuesta obviamente es no. Veamos un ejemplo.

Un error muy típico es construir consultas concatenando los parámetros directamente en la sentencia HQL .

String queryString ="from com.s21sec.model.Website as site 
where site= ('"+url+"', '"+mime+"')";
Session session = factory.openSession();
//Opcion 1
List resultadosOp1 = session.find(queryString);
//Opcion2
Query q = session.createQuery(queryString);
List resultadosOp2 = q.list();


Las dos opciones expuestas son un claro ejemplo de malas prácticas ya que la variable “url”, si no ha sido filtrada previamente, puede contener caracteres no deseados que se interpretaran, arriesgándonos a sufrir efectos inesperados en nuestra aplicación, provocar fugas de información etc...

Existen diversas alternativas para hacer algo equivalente de manera correcta, todas desembocan en el uso de prepared statements.

String queryString ="from rom.s21sec.model.Website as site where
site.url=(:urlparam, :mimeparam)";
Session session = factory.openSession();
Query q = getSession().createQuery(queryStr);
q.setParameter("urlparam",url);
q.setParameter("mimeparam",mime);
List resultados = q.list();


Esta es una buena práctica para el uso de Hibernate haciendo a nuestra aplicación un poquito menos vulnerable a este tipo de ataques. Además tampoco deberíamos descuidar otras medidas.

1. Asegurarnos que los parámetros que llegan a las sentencias no son las que el usuario ha introducido directamente.
2. Muchas veces es inevitable que se del punto anterior. En ese caso habría que llevar a cabo algún filtrado, introducir una capa de control que reduzca el riesgo.
3. El uso de procedimientos almacenados, al igual que los prepared statements, también nos hace menos vulnerables, pero con ellos perdemos una de las principales ventajas del uso de ORM’s, la portabilidad entre diferentes tipos de bases de datos.
4. Auditar nuestras aplicaciones periódicamente.

Raúl Martínez
S21Sec e-crime - Vigilancia Digital

1 comentario:

Anónimo dijo...

El primer y el segundo listado de código son idénticos.


(+34 902 222 521)


24 horas / 7 días a la semana



© Copyright S21sec 2013 - Todos los derechos reservados


login