Blog

Importancia de las consultas parametrizadas en SQL

Escrito por Miguel E. Guerra Connor

marzo 7, 2023

Cuando se interactúa con una base de datos en una aplicación, es importante tener en cuenta la seguridad y el rendimiento de las consultas que se realizan. Una mala práctica común en la programación es concatenar los valores directamente en una consulta SQL, en lugar de utilizar consultas parametrizadas. También es importante destacar que el uso de consultas SQL parametrizadas puede mejorar la planificación (explain plan) de consultas en un motor de bases de datos como Oracle. Cuando se utiliza una consulta concatenada, el motor de la base de datos no puede planificar la consulta de manera efectiva, ya que no sabe qué valores se incluirán en la consulta en tiempo de ejecución. En cambio, cuando se utilizan consultas SQL parametrizadas, el motor de la base de datos puede analizar y planificar la consulta de manera más eficiente, lo que puede mejorar el rendimiento de la consulta.

¿Qué es una consulta SQL concatenada?

Una consulta SQL concatenada es aquella en la que se incluyen variables concatenadas directamente en la consulta, en lugar de utilizar parámetros. A continuación te proporciono un ejemplo en Java utilizando JPA para ilustrar esto. Supongamos que tenemos una entidad llamada “Usuarios” con los siguientes atributos: “id”, “nombre”, “login” y “correo”.

Ejemplo 1: Consulta SQL concatenada

/**
 * Retorna un objeto Usuarios correspondiente al usuario con el login especificado
 * @param el login del usuario que se desea obtener
 * @return el objeto Usuarios correspondiente al usuario con el login especificado
 * @throws NoResultException si no se encuentra un usuario con el login especificado
 */
public Usuarios getUsuarioPorLogin(String login)throws NoResultException {
EntityManager em = entityManagerFactory.createEntityManager();
String query ="SELECT * FROM usuarios WHERE login = "+ login;
Usuarios usuario = em.createNativeQuery(query,Usuarios.class).getSingleResult(); em.close();return usuario;
}

El problema con este ejemplo es que es vulnerable a ataques de inyección SQL. Si el atributo login es proviene de un bean de respaldo que obtiene su valor de una página web, entonces un usuario malintencionado podría ingresar ‘John’ or 1=1;Delete all from usuarios;’ lo que le permitiría borrar todos los registros de la tabla usuarios.

Además de los riesgos de seguridad, las consultas SQL concatenadas también pueden afectar el rendimiento de la aplicación. Las consultas concatenadas se deben construir dinámicamente cada vez que se ejecutan, lo que puede ser costoso en términos de tiempo y recursos.

¿Qué es una consulta SQL parametrizada?

Una consulta SQL parametrizada es aquella en la que se utilizan parámetros en lugar de concatenar valores directamente en la consulta. Por ejemplo:

/**
 * Retorna un objeto Usuarios correspondiente al usuario con el login especificado
 * @param login el login del usuario que se desea obtener
 * @return el objeto Usuarios correspondiente al usuario con el login especificado
 * @throws NoResultException si no se encuentra un usuario con el login especificado
 */
public Usuarios getUsuarioPorLogin(String login) throws NoResultException {
    EntityManager em = entityManagerFactory.createEntityManager();
    String query = "SELECT u FROM Usuarios u WHERE u.login = :login";
    TypedQuery<Usuarios> typedQuery = em.createQuery(query, Usuarios.class);
    typedQuery.setParameter("login", login);
    Usuarios usuario = typedQuery.getSingleResult();
    em.close();
    return usuario;
}

Al usar setParameter, JPA convierte automáticamente los valores proporcionados en parámetros de consulta seguros, que son invulnerables a la inyección de SQL. Esto significa que, en lugar de concatenar valores de parámetros directamente en la cadena de consulta, como se hace en la primera versión del código, podemos usar un marcador de posición en la consulta y luego vincular un valor a ese marcador de posición utilizando setParameter. JPA asegurará que cualquier valor proporcionado a través de setParameter sea tratado de manera segura para evitar la inyección de SQL.

En resumen, es una buena práctica utilizar consultas parametrizadas siempre que sea posible, ya que hacen que el código sea más seguro y eficiente. Además, mejoran la legibilidad y mantenibilidad del código en general.

¿Necesitas orientación sobre este tema?

Esperamos que este artículo te haya ofrecido una perspectiva valiosa sobre el tema. Sin embargo, entendemos que en ocasiones podrías requerir mayor orientación. Si es así, no dudes en contactarnos.
Nuestro equipo de expertos están listos para asistirte en tus proyectos y desafíos tecnológicos.