API access and its implications


So I wanted to script something to remove a lot of cut-and-paste hand work. Rather than scraping the website for the information, the remote service supplied an API. This, in itself, made me very happy until I saw the requirements of how the API call needed to be made:

https://domain/getinfo?username[username]&password=[md5(pass)]&function=[name]

This made me look twice. Yeah, it said you needed to supply the md5 hash of the password in the GET call. That, sorry to say, is a horrible way to supply an API even if the API itself is protected by an IP whitelist.

Why, you ask?

Because this implies that obviously, all customer passwords are stored in md5 in the database. First of all, md5 is a horrible hash that has been proven super easy to break over and over and over. Secondly, it’s not salted making it even easier to crack.

This would mean that if anywhere in the customer website there would be an SQL injection attack that allowed database reads to the customer and password data; it’s game over for the customers.

So what do I recommend?

Generally speaking:

  • Use work-factor intensive SHA256 or SHA512 hashes with as many iterations you can get away with. The computation algorithms of BCrypt, SCrypt and PBKDF2 make brute forcing a really slow and annoying job.

On API access:

  • Supply API access using an API key that is not related to the password and also is hashed using the same principles as mentioned above
  • Preferably use POST with variables and don’t put this information in a GET request

More info on good and bad hashing can be found at crackstation.net