27.06.2018, 13:11
(
Last edited by Sasino97; 28/06/2018 at 09:50 AM.
Reason: Added more info on bcrypt
)
How NOT To Store Your Users' Passwords
By Sasinosoft
The first thing we must be aware of when programming anything that will ask the user to enter a password, is that the user is giving us their trust. It is our duty to keep their password as safe as possible, so that in case of attack to our servers, the attacker will not be able to read their password. You might think that "it is just a game", so the security of the game accounts is not so serious, but a poll showed that 59% of people use the same password everywhere or almost everywhere. [source] If the attacker gets access to your game database, he will most likely obtain all your users' nicknames and passwords, and if they are not properly hashed, then you have made his work easier. After getting this information, the attacker will proceed to check for each user if he is registered on the main websites, such as Go0gle, Microsoft, mail providers, using the passwords and user names he just stole.Here are a few hints to make his work harder.
1. DO NOT Store Passwords In Plain Text
It is believed that at least 30% of the websites store the passwords in plain text. [source] This is really a shame, and it must come to an end. If any website emails your password back in plain text, then he is surely storing your password as such, and compromising your security in all the websites that you used the same password.
You must never do so. In the case of a San Andreas Multiplayer server, as soon as you receive the user password in the inputtext parameter of OnDialogResponse, you must one-way hash it. Fortunately, the developers of SA-MP added the SHA256_PassHash function in version 0.3.7 R2-1, so there is no more excuse for those who don't like to use external plugins. [great tutorial]
Said that, I will also add that since there are better algorithms than SHA-256, it would be better if you used another one: bcrypt (the best, as I will show in the next section), SHA-512 or Whirlpool. On SA-MP Forums you can find plugins for bcrypt [link], SHA-512 [link] and Whirlpool [link]
2. DO NOT Simply Hash The Password And Store it
Hashing the password and store it will add very little security; most users' passwords are simple words or numbers which can be found in dictionaries. If this is the case, the attacker will easily detect the password of the user, simply by searching the hash in rainbow tables; these are per-algorithm tables which already contain the hashes of the most common passwords and more, and they are publicly available on the internet. [example]
To avoid this problem, and force the attacker to use brute-force attacks, thus wasting his time, money and energy, you must put salt on your passwords.
A prudent programmer putting salt on the password of his users.
3. DO NOT Use The Username As Salt
If your SA-MP Server does this, and another website that your user is registered on with the same username and the same password does the same, both databases will contain the same password hash for the user. If the attacker, after getting a copy of your database and that of the other website, notices this coincidence, then he will most likeley focus on this particular user.
If you implemented a system to let the user change his password, you are then going to hash it with the same salt as before. This needs to be avoided.
The best practice is to generate a random string the first time the user registers, and to store it into the database in a separate column. When the user wants to change his password, your program will generate a new random string, and update the value in the database.
4. DO NOT Write Your Own Hashing Function
Do not do this, unless you work for the NSA and your algorithm has been tested for years. Do not do this even if you have studied cryptography and security. This is because, even if you think that your algorithm is strong enough, it has not been tested enough against all the possible kinds of attack. Do not risk, and if you have written one, just keep it as your personal project.
5. Use bcrypt
In this post I mentioned different hashing algorithms whose implementations are also available for SA-MP Servers. I must also say that the best option you have is to use bcrypt.
The primary advantage is that bcrypt, unlike the other algorithms mentioned here, aims at being slow to execute, especially on GPUs. When we are computing our hash during user registration or login, we don't care if it takes 1 second or more, because most likely the user will not notice it, instead we really care about the attacker being as slow as possible at brute/dictionary attacking our hashed password. SHA and Whirlpool are aimed at being as fast as possible to execute, and while this means that the user's password is checked in the blink of an eye, it also means that the attacker is able to crack the password in fewer time (with the appropriate equipment).
By using bcrypt, we make almost impossible for an attacker to crack the password, definitely not worth it for him.
Another advantage is that bcrypt will generate the salt for you, and you will have to do nothing.
6. Additional Tips
- Also put pepper. Pepper is another value that is added to the algorithm before the final hash, but instead of being a different value for each user, it is a single constant string which is used for every hash, and it is secretly hardcoded in your code. Of course, after your first user is registered, you must never change it again.
- Force the user to use a password of a certain minimum length, and made of multiple words.
- In your register dialog, tell the user not to use the same password as other websites or SA-MP Servers, and not to tell his password to anyone.
- Ask the user to input his password twice during registration and password changing procedure.
- Kick the user and prevent him from logging in again for a certain time if he fails to log in for a certain number of times. This makes unpractical using direct brute force attacks to your server.
- Implement a system to change the password, and encourage your users to change it when they feel it is compromised.