I’ve been working in the integration of SMF to my own users’ management system, and I have some doubts about the proper way to send and receive users’ data.
It’s a common practice to save in the database hashed or md5ed versions of passwords, and I’ve been wondering what the point of doing this is, although I recognise I have done it myself and smf has a quite complex function to perform this task.
Unless you’re using a secure connection, which it’s not usually the norm, passwords are sent over an open connection, meaning that theoretically anyone can get access to the information sent over this connection and users send their passwords as plain text, if a hacker can capture this connection, she’ll get the password, unless the password itself it’s hashed. On the other hand, if passwords are hashed, the hacker will get a hashed version of the password, this can be performed on client side by using a JavaScript version of md5 or similar hashing algorithm, but then again, the hashed version will travel over an insecure connection, anyone could then get access by sending the hashed version of the password which will match the one stored in the database.
Also, I reckon it’s pointless to hash passwords stored in the database since if a hacker or a malicious employee gets access to the database, will not only get access to the specific column where passwords are stored, but to the whole table or database, the only protection offered here is for users who use the same password for everything, for instance, their email accounts.
Perhaps we could also send an unintelligible version of user data, let’s say we use JavaScript to hash both username and password, then we concatenate both using a fixed concatenation string, something like
Code:
Hashed username: 851c396b5b7bb83452e19567836ed7f3
Hashed password: 5bf4ec8db1d13c79edfae0699ce662fe
Concatenation string: |an15tr1ng| or maybe just |
This way we’d be sending just one string:
Code:
851c396b5b7bb83452e19567836ed7f3|an15tr1ng|5bf4ec8db1d13c79edfae0699ce662fe
Which is more unintelligible but still prone to be hacked, or maybe without using a concatenation string, i.e., just:
Code:
851c396b5b7bb83452e19567836ed7f35bf4ec8db1d13c79edfae0699ce662fe
This should be even more unintelligible, and we know the first 32 chars are the username and the rest are the password, however, if our hacker knows the structure we are using, he’ll get access promptly, perhaps a secret structure would work, nonetheless this should be easy to implement for everyone without the need of editing scripts to customise functions. A session variable could also help, at least we can make sure the user is logging in from a script hosted on our server; let’s say we use this;
Code:
$secret_session_var=mt_rand ();
$_SESSION[‘secret’] = dechex($secret_session_var);
Let’s suppose $secret_session_var equals 1604716014 then $_SESSION[‘secret’] equals 5fa605ee, that will be our secret key for the length of the session. Then we send this value on the login form as a hidden field, which, certainly anyone can see, but it’ll be only valid for the current session. We use Javascript to hash both username and password and the user should submit with the form just a long string containing both, username and password;
Code:
Hashed username: 851c396b5b7bb83452e19567836ed7f3
Hashed password: 5bf4ec8db1d13c79edfae0699ce662fe
Secret key: 5fa605ee //$_SESSION[‘secret’]
The form should return: Hashed username+Secret key+Hashed password; or the combination you like, something like:
Code:
851c396b5b7bb83452e19567836ed7f35fa605ee5bf4ec8db1d13c79edfae0699ce662fe
Where the first 32 chars are the username, then the 8 char session key and then the 32 char password. Once we get it on the server we’ll have to unscramble it and contrast username, password and secret key. Far from being a bullet proof system, it does provide additional security and makes hackers’ work a bit harder. The cons here are the use of JavaScript to hash the user input, it should be working otherwise they shouldn’t be able to login, of course, if JavaScript is not available, the script can also receive plain text username and password and login the user with no security at all.
To summarize, unless anyone can prove otherwise, if security is a must, the only way to achieve it it’s using a secure connection, or does anyone have any other idea?