style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Desarrollo inseguro, aún con un Object-Relational Mapping.

Seguro más de una vez has escuchado cuándo alguien dice orgulloso: "Mi aplicación es más segura, uso Hibernate para la persistencia de mis datos."

Si no, algún día toparás con alguien que te lo diga.

El uso de herramientas como Hibernate, que nos permiten trabajar con objetos durante nuestras sesiones de trabajo no garantiza que nuestra aplicación sea inmune. Simplemente no hay aplicaciones inmunes, pero no hay que dejar que sea trabajo fácil para el que intenta corromper nuestra seguridad.

Por defecto Hibernate utiliza sentencias de tipo Prepared Statements lo cual de primera instancia nos permitiría pensar que no debemos preocuparnos por algún SQL Injection, pero no es así, por ejemplo:

String hqlQuery = " select pftDescuento.numeroContrato as numContrato, " +
                           " where pftSolicitud.comp_id.sptTitularGrupo.comp_id.id=  " + idUsuario+
                           ...

Como vemos la variable idUsuario puede contener caracteres no deseados que pueden ser interpretados de manera que generen errores o peor aún, fugas de información.

Otro ejemplo con el mismo caso :

List descuentos = session.createQuery("from PftDescuento as pftDescuento where pftDescuento.id = " + usuario.getId()).list();

La manera que pareciera más correcta para utilizar parámetros en nuestras consultas son más o menos estas:

Enviando parámetros posicionados:

Query hqlQuery = session.createQuery("from PftDescuento as pftDescuento where pftDescuento.id = ?");
List descuentos = hqlQuery.setString(0, idUsuario).list();

En el caso anterior le enviamos el parámetro a utilizar y su tipo, como a éste le indicamos que estará en la posición 0 será el primero que utilice en la consulta, muy parecido a como trabajaríamos con el prepared statement del JDBC.

Identificando los parámetros:

Query hqlQuery = session.createQuery("from PftDescuento as pftDescuento where pftDescuento.id> :idUsuario");
List results = hqlQuery.setString("idUsuario", idUsuario).list();

Como vemos, se asigna un nombre al parámetro y la consulta lo consumirá, no por la posición que le indiquemos si no por el identificador que le hemos asignado.

Para los que no quieren alejarse de SQL:

Query sqlQuery = session.createSQLQuery("Select * from PftDescuento where id = ?");
List results = sqlQuery.setString(0, idUsuario).list();

Hay algunas otras maneras, aunque a mi experiencia estas son las más utilizadas y por ende los casos más vulnerables.

Con sencillas prácticas podemos evitar dolores de cabeza terribles como cuando el cliente nos busque por que los datos han desaparecido. >.<'

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Sr. Negativo

Desarrollo inseguro

Tienes razón cualquier aplicación puede ser insegura si no se tiene cuidado.

@ezamudio había escrito algo sobre seguridad en SQL

http://www.javamexico.org/blogs/ezamudio/ejemplo_de_inyeccion_de_sql

Buen post.

Imagen de 043h68

Gracias.

Gracias!

Tienes razón, que bueno que agregas el link del post de @ezamudio, ayuda a comprendero más éste.

Imagen de zachiel

Aprovechar busqueda por criterio

Me parece que cuando se usa hql en lugar de SearchByCriteria se esta desaprovechando una de las principales ventajas de Hibernate.
No solo dificultas enormemente las inyecciones, sino que también te libras de una buena vez del odioso SQL y la necesidad de estar metiendo dichos Strings con sentencias SQL a ciegas en tu código Java.

Un ejemplo muy simple: Al query del ejemplo

String hqlQuery = " select pftDescuento.numeroContrato as numContrato, " +
                           " where pftSolicitud.comp_id.sptTitularGrupo.comp_id.id=  " + idUsuario+
   

lo podemos fácilmente estructurar así con SearchByCriteria :

    criteria.add(Restrictions.eq("pftSolicitud.comp_id.sptTitularGrupo.comp_id.id", idUsuario );
   

Con esto Hibernate solo espera un valor para comparar y no aceptará código hql dentro de la variable idUsuario.
¿No creen que conviene mas? :)

Imagen de JaimeItlzc

HQL.

Y que me podrías comentar sobre el HQL de hibernate?

Consultas complejas

Estoy de acuerdo contigo en cuanto al Criteria ya que de esta forma se aislan totalmente cuestiones como palabras especificas del motor de base de datos asi que para queries dinamicos es muy bueno. El problema viene cuando tienes un query muy complejo con joins y subqueries, al menos en mi caso el comportamiento es siempre primero realizar el query con sql y luego traducirlo a Criteria pero se vuelve un verdadero dolor de cabeza ademas de que es menos legible que el hql

Imagen de paranoid_android

Legibilidad HQL ya cambió un poco el tema.

Buen post 043h68, saludos.
Para mí es más sencillo entender y optimizar un query que optimizar sentencias Hibernate.
Debo comentar que no diseñar una buena base de datos que incluya llaves e índices por el simple hecho de usar Hibernate me parece un grave problema.
Por otra parte trabajar con procedimientos almacenados es más sencillo y da mejor rendimiento vs su costo de migración a otra plataforma.
¿Tendrá Hibernate algún motor para ejecución de script tipo PL?

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">