15

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)) {
  return BAD_USERNAME_PASSWORD_COMBO;
}
// 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.

P.S.

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.

5
  • I don't think a UNION would actually do anything in this particular case as the password would still end up being checked.
    – Steve
    Commented Nov 20, 2012 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. Commented Nov 20, 2012 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
    Commented Nov 22, 2012 at 1:12
  • @SteveS I've updated the question to include the details. Commented Nov 23, 2012 at 2:10
  • Oh! Right, that makes sense. :)
    – Steve
    Commented Nov 23, 2012 at 19:25

1 Answer 1

7

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.

11
  • nice! Still would only enumerate hashes for us, and there is no interface to use hash as a password directly. Commented Nov 20, 2012 at 23:22
  • It's worth mentioning that this technique is called Blind Injection.
    – Polynomial
    Commented Nov 21, 2012 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. Commented Nov 21, 2012 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
    Commented Nov 26, 2012 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
    Commented Nov 26, 2012 at 9:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .