Our developers left a surprise in handling user login. Namely:

// java
List users = hibernate.find("from Users where username = '"+formUsername+"'";
if (users.length==0) { return BAD_USER; }
if (!checkPassword(users.get(0).getPassword(), formPassword)) {
// continue to mark session as authenticated

Now, obviously, it's possible to inject into the query. But that is HQL language. If it was SQL, and I knew the structure of the database, I could hang a "union" operation, and could log in into any account. But I don't quite see what kind of malicious HQL I can hang on here, to really make something bad happen.

Yes, we've already replaced this code to use parameters, but I'm just curious as to what can be done in that situation. The HQL examples I've seen are about adding 'OR' operator, which will not help in this case.

Also, the underlying database is postgres, so any postgres functions are fair game.


There was a question as to how the union would help. Given the table structure of (id,username,password), and SQL query of:

select id, username, password from users where username = ...

I can inject:

' union select 1, 'root', 'synthetic_password

and the complete executed SQL will become:

select id, username, password from users where username = '' union select 1, 'root', 'synthetic_password'

First select would not return any records, and the second will return a record that JAVA code will read and populate its beans from it. It will then compare the password, but since I provided the password data in both the injected SQL, and in the form, they will check out.

  • I don't think a UNION would actually do anything in this particular case as the password would still end up being checked. – Steve Nov 20 '12 at 20:41
  • @SteveS you would create your own record with the union, that would match the superuser record, but with your own password. The password check then would succeed. – Pawel Veselov Nov 20 '12 at 22:56
  • I'm not familiar with HQL syntax, but UNIONs in regular SQL are for merging two SELECT queries. How would you UNION in an INSERT? – Steve Nov 22 '12 at 1:12
  • @SteveS I've updated the question to include the details. – Pawel Veselov Nov 23 '12 at 2:10
  • Oh! Right, that makes sense. :) – Steve Nov 23 '12 at 19:25

You could for example enumerate any users hash/password:

insert the following as the username:

admin' AND substring(password,0,1) == char(64) AND '1' = '1

Checks if first character in column 'password' is a lower case a.

| improve this answer | |
  • nice! Still would only enumerate hashes for us, and there is no interface to use hash as a password directly. – Pawel Veselov Nov 20 '12 at 23:22
  • It's worth mentioning that this technique is called Blind Injection. – Polynomial Nov 21 '12 at 6:56
  • 1
    Are you sure the passwords are hashed? The naming of stuff up there makes it seem otherwise... And at minimum, you don't appear to be using salts. – Clockwork-Muse Nov 21 '12 at 21:04
  • 1
    @PawelVeselov, you have misunderstood the function of the salt :) I recommend reading up on it and learning about its function. – Chris Dale Nov 26 '12 at 7:00
  • 1
    @PawelVeselov, Yes!This is when it gets interesting, and also this is explained in several questions already on sec.se. Being able to thwart rainbow tables and make the attacker recompute hashes for every password he is trying are some serious benefits of salts. Again, I recommend reading up on it, as the subject is too big to answer in a comment :) Best of luck. PS:You should use a slow password algorithm such as PBKDF#2, Bcrypt or Scrypt. They are designed to hash passwords, which MD5 is not. – Chris Dale Nov 26 '12 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.