Nuestros desarrolladores dejaron una sorpresa al manejar el inicio de sesión del usuario. A saber:
// java
List users = hibernate.find("from Users where username = '"+formUsername+"'";
if (users.length==0) { return BAD_USER; }
if (!checkPassword(users.get(0).getPassword(), formPassword)) {
return BAD_USERNAME_PASSWORD_COMBO;
}
// continue to mark session as authenticated
Ahora, obviamente, es posible inyectar en la consulta. Pero ese es el lenguaje HQL. Si era SQL, y conocía la estructura de la base de datos, podría colgar una operación de "unión" y podría iniciar sesión en cualquier cuenta. Pero no veo muy bien qué tipo de HQL malicioso puedo retener aquí para que realmente suceda algo malo.
Sí, ya hemos reemplazado este código para usar parámetros, pero tengo curiosidad por saber qué se puede hacer en esa situación. Los ejemplos de HQL que he visto son sobre la adición del operador 'OR', que no ayudará en este caso.
Además, la base de datos subyacente es postgres, por lo que cualquier función de postgres es un juego justo.
P.S.
Hubo una pregunta sobre cómo ayudaría el sindicato. Dada la estructura de la tabla (id, nombre de usuario, contraseña) y la consulta SQL de:
select id, username, password from users where username = ...
Puedo inyectar:
' union select 1, 'root', 'synthetic_password
y el SQL ejecutado completo se convertirá en:
select id, username, password from users where username = '' union select 1, 'root', 'synthetic_password'
La primera selección no devolvería ningún registro, y la segunda devolverá un registro que el código JAVA leerá y llenará sus beans. Luego comparará la contraseña, pero dado que proporcioné los datos de la contraseña tanto en el SQL inyectado como en el formulario, se verificará.