hey there.
I'm developing a website and i want to have a password recovery system for the users who lost their password, but i don't want to save the user email address or any private data.
i thought of saving a hash of the email address but if the db is compromised one could check if an email address is registered and which account it belongs to.
do you have any ideas?
To protect against the DB being compromised and hashes extracted, just add some random (but constant string) to all email addresses before cashing. E.g. add "BLABLABLA" to turn "joe#example.com" into "joe#example.comBLABLABLA" before hashing. It's still not perfect, but now an attacker needs your DB, your application code, reverse engineer it, and know that that's what he needs to do in the first place (there is no hint in the DB that your application modifies the email address before hashing).
Related
For some less critical websites it seems common for a user to be able to reset their password if they have forgotten it. The fact that they can access the email account that they registered with is considered good enough.
In those cases the only advantage of the password seems to be that, if the user can remember it, they don't have to check their emails in order to access the website.
Although not having to check your email is a convenience it has to be weighed against the inconvenience of remembering a large number of passwords for all the websites that require them.
A user would register their email address and verify it by responding to a link sent to their email address. After that, every time they wanted to access the site they would enter their email address into the login form and then click the link in the email sent to them.
Is there an argument for less critical websites to allow access without a password in this way?
I'm setting up an anonymous site. So basically a user's account cannot be traced back to any actual person (such as by an email address). Authentication is the part that I'd like your thoughts on. If I use the email/pass combo to authenticate can I use bcrypt to hash both the email address and password (well I know this is possible but is it practical)? I thought if the email is encrypted then it'll be extremely slow to search the db to find a match. Is this true/false? What are your thoughts? Any other ideas? Basically, I'm open to any ideas on how to authenticate, but if it's authenticated with an email then it can't be exposed/or decrypt-able. Thanks!
Once you hash something, the original can never be recovered.
Let's take a password for instance, typically when a user signs up with an email/password you'll hash the password (with something like bcrypt), then store the hash in your database. This is great because if an attacker gets a copy of the database, there's no way to 'decrypt' the hash.
In your situation, you probably WON'T want to hash the email because that means you'll never be able to email the person -- which I'm assuming you'll want to do.
If you decide to go that route, you'll basically just be storing two passwords per user (that's the closest analogy I could come up with, sorry!).
Hope that helps!
EDIT: A better way to do this would be to create a new account given ONLY a password -- and then you generate a username for the person automatically. This is what companies like privateinternetaccess.com do -- they'll generate some random username for you -- this way you can't contact the user, but they can still safely log into your application.
i don't see any problem with your idea (assuming that you never want to asynchronously send email to the user).
login:
user posts a login form that has cleartext email and cleartext password (of course you use good TLS transport encryption)
eh = h(email), ph = h(password)
fetch the record from user database where eh == stored_eh
compare ph against stored_ph
forgot password procedure: in the very moment the user posts the "forgot password" form with his cleartext email address, you HAVE his email. compute eh, lookup profile, generate onetime token, store it into profile and put it into a mail to his email address. he can then use the token to define a new password.
change email procedure: similar to above, you have the cleartext old/new email addrs in the moment the form is posted.
Notes:
the db lookup in step 3 is not slower than using a plaintext search key
for 2 and 4, use some sane code from a well-maintained library (scrypt, bcrypt, pbkdf2, sha512_crypt, not just a simple salted-hash)
if an attacker gets your database and has a list of potential email addrs, he can easily find out whether you have (some of) them as users and determine their user record in your db. if that is a problem, you maybe could use h(email+password), but then there is no password recovery possible.
If I understand correctly, the biggest problem with sending a password via email is that it requires the password to be stored in clear text in the database. If the DB is compromised, the attackers will gain access to all accounts.
Is there a workaround for this problem?
How can one make sending a user their password via email as safe as possible?
The simple answer is: don't. If you think your database is insecure, an email is far, far less.
If you mean that you want to send them their password when they register, then you could do that before you store it in the database.
If you mean after they have registered, the only option is to store in plaintext (again, don't do this) or make a new, random password and send them that. It is impossible to get their password from the hash, which is why it makes the password storage safer. The best option is to generate a new (temporary) password you send them, or a token giving them access to a password change system.
You may want to consider a good hashing algorithm like BCrypt that includes a salt.
I don't know if my suggestion is feasible for your scenario, but you should better keep the data hashed or encrypted and send password reset links instead of plain-text passwords.
The moment the password is in cleartext in the email, it is inherently insecure.
As such, there is no safe way to send a password in cleartext safely.
You should not be storing passwords in cleartext in your database - you should be using salted hashes. When the user enters their password, you hash it with the salt and compare to the stored hash.
When people forget their password, instead of sending passwords by email, you should send reset links backed up by expiring tokens. These would generate a temporary new password (that would expire within minutes).
You should be hashing all passwords in your database.
sha1($_POST['password'].$salt.$username);
In the case of a lost password
A user requests a password reset link, which contains a hash generated in the "user_meta" table. When the user recieves this link, the hash is compared to that in the database, and the user will be able to UPDATE their current password with a new password.
The PTXT of the password is never reveiled.
You only compare hashes.
Yes, there is a common workaround.
Assuming that you have your users in your database.
You send the "password reset link" containing some "key" information, like a guid. An example link is a form:
http://your.site.com/setpassword?id=5b070092-4be8-4f4d-9952-1b915837d10f
In your database you store the mapping between sent guids and emails.
When someone opens your link, you check your database and you can find out who asks for the page - because any valid guid maps to an email. You can then safely let the user change his/her password assuming their email is not compromised.
When it's about to store the password, you never store it in plain text, you always hash passwords, using additional random salt to make the dictionary attack more difficult when someone breaks into your database.
There is a workaround which is less secure than a password reset but works if it is a requirement that users are sent a password, not a reset link.
What you do is you generate a new password that contains sufficient randomness to be very hard to guess, but is also formatted in a way that it is easy for them to remember and read out (say over the phone).
Something like: xyz-xyz-xyz-nnnn where xyz is an easy-to-spell but uncommon word and nnnn is a four digit number.
Then set it up so that this is a temporary password that needs to be changed on first login.
Set the password using the same logic you would use to set a normal password, so that it is correctly salted and hashed, and then send the password plaintext via email, like so.
Dear FirstName LastName,
You requested we reset your password.
Your new password is:
insipid-mirth-nonplus-9174
You will be able to log into the system once using this password, then you will need to enter a new password.
Important Caveats
This system has some serious vulnerabilities which make it unsuitable for websites where data security is crucial. There are more than these, but these are the ones I know/can think of:
Unlike systems which use a password reset link, this system could be used to lock someone out of the system (assuming you use it as is) unless you either require someone to fill out identifiable information before issuing the password reset, or send a "are you sure you want to reset your password?" email first. This would entail them clicking on a link with a GUID that goes to the server; at that point they may as well be sent to the password reset form anyway.
Since the password is being sent plain text via email, there is a danger it can be intercepted and the password can be used. Although to be fair this is not that much different than the risk of sending a password reset link.
If you ignore the risks in step #1 and you don't use a sufficiently random way of generating passwords (say you use a word list of fewer than 1000 items), someone who has hacked into your server will be able to retrieve the salted password hash and then write an algorithm that generates all possible passwords and checks them against the hashed password. Not as much of a problem if you use a cryptographically complex hashing algorithm.
If you want to send password to user via Email in cleartext and want to store those password into database as hash or any other format . It will be possible.......
Just you will have to follow some simple way....
1 .you will have to take those password as variable which will send from user.
2. When you store database then just convert it as you wishes format.
3. But when you send those to user by mail , That time just sent those variable password...
I think it will be helpful to build your concept about WAY.......
We are building a CRM type app although this would apply to any application where there are "members" and "staff" e.g. a shopping site, dating site, facebook etc.
In our app, users can change their password the usual way, by resetting it with email confirmation. Users can also have more than one email address associated with their account.
What we are trying to work out is how to prevent staff using the system taking over the accounts. We want staff to be able to edit the email address (because someone may phone in and request a change); the issue then is they can simply change the email to one they control - and request a password re-set as a user.
Are there any recommended best practices for this?
You could require the user to also authenticate the action by other means, such as when the email address is changed the user is sent a confirmation code via text message that they must input somewhere.
Another means would be to only allow access to the account if certain information is inputted correctly. This could be address information or DOB. It is unlikely that this information could be guessed from something like a name or account number.
1) Add one of those silly security questions like "What is your favorite color?" and store the answer, encrypted, in the database. Staff could edit the email to their heart's content, but if they didn't know the answer to the secret question the system wouldn't let them change the password. If you have concerns about staff trustworthiness, then you need to introduce something outside their control that serves as a final gateway before you can change the user account.
I imagine a simple implementation would simply check to see if the user reset their password. If so, on login, it challenges them with the security question to "authenticate" them before allowing them to proceed.
2) Logging, monitoring, and auditing. Record which staff accounts accessed the email address change form, what address(es) they changed, what they changed them too, and when they changed them. Also record the connection information of the people accessing the accounts. If your logs show one IP address accessing 4-5 completely disparate accounts, you might need to look into that. (Yes, I know you can use proxies etc. to mask this. Not perfect but it'd weed out the chaff pretty fast).
3) Hire trustworthy people! #2 should really only need to be used as a "check" against abuse instead of the end all be all to stop it.
I’m developing a website of a client and they are sending out newsletters to their customers (through the website administration interface)
The newsletters are personal to each of the subscribed recipients/customers.
Each recipient/ customer is also a user with a username/password that enables them to sign in on the website and manage their newsletter subscriptions and participate in the sites community.
This all works like a charm.
Now my client want a “Manage my subscriptions” link in the newsletter email that when pressed automatically signs the recipient/customer in on the website with no need to remember username and password.
This could be easily solved be making a link like this:
http://mysite.com/manage.aspx?user=peter&password=hounddog
Of course information should not be clear text but encrypted in some way.
This however poses a problem since the only way a user can be authenticated on the website if by providing a valid username and password.
In the name of security, passwords are stored as hashed values in the database making it impossible for me to insert the password in the link.
What is the best way to accomplish this without compromising the security?
You will have to compromise your security somewhat, if you want people to be able to login without entering password. Note that even if you had access to the password (as in your example), you would have to embed it in a mail massage which would be transmitted in plaintext.
You can create a Guid associated with each user and message, and append it to the URL, and allow that to login automatically.
You could perhaps isolate the permissions so that a login through a newsletter guid link only allows the user to manage subscriptions, but that a real password-login is still required to participate in the forum. In that case its pretty limited what havoc can be wrecked if someone gets access to a Guid from a mail message.
Could you not insert an encrypted user name bundled with the hash value of the password?
What I mean is, encrypt & encode the user name to always be a particular length or to have a known break character in it then append the passwords hash value. this way, you could break apart the query string easily while still having the user name and password securely encoded. A straight compare of the hash values would be enough, with the unencrypted, decoded user name to allow access.
What about using an encrypted cookie that contains an access token ?
This cookie would be delivered after a successfull authentication by a separate page.
This kind of token can also be part of the URL query string.
Also you might consider using secured https instead of http.