Good afternoon,
I am working on a script to allow news users to register on a website.
In a nutshell, these are the steps I have planned:
register.php - New user completes a form, entering their username, address details, business name and email address. The data is then posted back to the script via SSL.
register.php - The script checks that the username or email address is not already stored in the database. If they are not, it uses those data to generate a token, which is emailed to the email address in the form of a hyperlink, with that token and the rest of the data as parameters of the hyperlink. The token used is made from a secret string - that way, only this script can make a code that can be reconstructed using the rest of the data.
email - The hyperlink (SSL) is clicked on, thereby passing the data via $_GET into the next script via SSL.
verify.php - The token is reconstructed using the passed $_GET data and a known secret string. If the hash is identical, we know that the token was generated by one of our scripts. The user is prompted to enter a password (twice), before clicking "submit" (which posts the data to itself, via SSL).
verify.php - The script checks if the username or email address does not exist, before inserting the new user data into the database, along with a hashed password and salt.
email - An email notification is sent to the administrator, to tell them that a new user has registered - the new user needs to be approved before they can log in. The email contains a link to the next script, with the ID of the new user passed to it via $_GET. SSL is used.
confirm.php - The script uses the passed ID of the new user to display all details that have been registered, in editable fields (not the password or salt). On clicking "confirm", the form data is posted back to the same script, via SSL.
confirm.php - The script updates the record for that user, and sets the new user record to "confirmed". The new user receives email notification, and can now log in.
This may seem long, but there are a series of steps that need to be completed.
All new users must verify their email address before any data are stored in our database. The password is not passed about any more than it needs to be. It is only passed in its raw form back into the "verify.php" script via POST, which then hashes it. I will ensure that POST data for SSL packets are not logged on the server. In that way, there should be no record of the raw password on the server, right?
A random salt for each user is generated and stored - to protect against rainbow tables.
Have I missed something? My only concern is the transmission of the raw password via SSL. Although SSL protects against sniffing, I am still uneasy about receiving the raw password into the server. That said, I do not want to make the project vulnerable to "middle-man" attacks, by hashing it client-side.
Can anyone suggest any flaws in my method? I tried Googling this, and although there are some applicable posts, nothing seems to tie in the whole process. I hope this thread will benefit future visitors to this page as well as myself.
Thanks.
I had to do the same thing 2 months ago and I did it your way. Except for this point:
Before asking the user to enter everything, the first step should be to validate and confirm the email. Once completed, we ask everything else.
2 goals are reached:
Users are sometimes afraid to enter too much info.
If they have already sent their email, they are usually more willing to continue the process.
Users that already signed up and that are in the wrong page: you can suppose they lost their email and propose a solution (if the email is already in the database)
...But I personally think the best thing is to stick with openId ;-) Next time that's what I will try to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With