Password Security Basics when working with SQL databases in your iOS App
On a recent interview, I have been asked some questions on how to securely store the username and password in the database and also how to prevent a SQL injection attack. I have worked with SQL databases on a couple of iOS apps, but none of them had user input or stored any sensitive information on the servers, so I did not know much about security practices. After the interview, I looked into the security issues and how to handle them in your app and decided to write a post in case anyone else finds it useful, and also as notes to myself.
What is a SQL injection attack?
Attackers use this code injection technique to attack data-driven applications, in which nefarious SQL statements are inserted into an entry field for execution. The attacker is looking to gain any database setup insights from the error messages and would start by probing the text fields with extra characters (like ‘ ) to trigger errors and try to insert their own code into the query. So a world of advice — keep your client-facing error messages very generic.
So, how to prevent SQL injection attacks?
- Sanitize the input strings by taking out all the extraneous characters. For example, if a password (mySecretPassword92) only supposed to be composed of letters and numbers, you should remove all the other characters (!@#$}’ etc…).
- Keep error messages local or if they have to be client-facing, then keep them as generic as possible.
- Limit database privileges. Compartmentalize the app’s permissions or accounts that access different sets of data from you app and only allow the least amount of privileges. For example, the password query should only have permissions to access the credentials table. This way if one of the data sets is compromised, the attacker does not gain access to all of the app’s data.
More on injection attacks: esecurityplanet.com
Securing user password
Additionally to sanitizing input strings, the consensus from the developer community on password security best practices seems to be the following:
- Password hashing. Hashing a password means using an encryption algorithm on the password and storing the output of the hash function (and not the password itself) in the database. The use of a strong and slow algorithm is recommended. Slower algorithm will slow down the attacker and if they’ve stolen a database full of passwords, it could take years to decrypt. The 2 recommended algorithms are PBKDF2 and bcrypt. (Other algorithms: MD-5, SHA-1, SHA-2 are not recommended for password hashing because they’re fast). There are also two recent and promising algorithms to keep an eye on: scrypt and Argon2.
- Password stretching is using many iteration of the hashing algorithm in your code to slow the attacker down even more. 2000 iteration is recommended.
- Password salting. String salting means appending an additional string to the user password to make it longer. The key here is longer, a long password will take a lot more time to decrypt by an attacker. UUID strings are one option for salts. The recommendation from the community is to have a unique salt per user (and not per table). The salts are only meant to slow down the attacker and don’t have to be secret, they can be stored in the credentials table along with the password.
- Also, storing username and password hash in the same database is not recommended.
Excellent links on password security:
And more to learn:
Introduction to Secure Coding Guide from the Apple Developer website
Thanks for reading!