domingo, 11 de julio de 2010

Cómo realizar queries con HQL (una sugerencia para evitar SQL injection)

Cuando trabajamos con Hibernate y deseamos realizar queries con el lenguaje de consultas propio, HQL, recomiendo trabajar con parámetros a la forma de sentencias preparadas (prepared statements). Por ejemplo:


@Override
public Usuario login(Cuenta cuenta) {

Query query = this.getEntityManager().createQuery("from Usuario where cuenta.login = :login and cuenta.password = :password ");

query.setParameter("login", cuenta.getLogin());
query.setParameter("password", cuenta.getPassword());


List result = query.getResultList();

if (result.size()==0){
return null;
}
return result.get(0);

}


En el código mostrado arriba se puede ver como los parámetros "login" y "password" son pasados en diferido y no concatenados directamente en el string, esto puede salvarle la vida contra ataques de SQL injection. No estoy seguro de que además obtenga ganancias en tiempo de ejecución, para llamadas posteriores, porque estas sentencias sean preparadas y almacenadas en el catálogo del RDBMS.

2 comentarios:

  1. Otra forma que en algun momento me fue util y muy sencilla para evitar SQL injection (no estaba utilizando Hibernate), es utilizar los prepared statements de esta forma:

    aqui les presento un ejemplo muy sencillo donde queremos realizar un insert:

    public void insertar_telefono(String telefono, int id, String tipo){

    String sql ="INSERT INTO BECOFILE.JOB_TELEFONO (NUMERO_TELEFONO,ID_COLABORADOR,TIPO_TELEFONO) VALUES (?,?,?)";

    try {

    PreparedStatement stmt = con.prepareStatement(sql);
    stmt.setString(1, telefono);
    stmt.setInt(2,id);
    stmt.setString(3, tipo);
    stmt.executeUpdate();

    } catch (SQLException e) {
    log.error("el insert ha fallado ",e);
    }

    }
    Como podran observar en el metodo de arriba queremos declaramos un String sql, el cual va a contener el insert, lo extraño que van a observar son los signos de interrogacion, los cual seran reemplazados por cuando hagamos el realicemos los set, por ejemplo: stmt.setString(1, telefono); esto indica que la variable "telefono" va a ser puesta donde esta el primer signo de interrogacion y de esta forma se evitan SQL injection de una manera sencilla si no estas trabajando con hibernate y estas haciendo algo muy sencillo.

    ResponderEliminar
  2. Gracias mingo, definitvamente la mejor forma de trabajar cuando lo hacemos con JDBC puro...

    ResponderEliminar