I just finished encrypting the passwords in my database using a salted sha1. Naturally I'll need to implement a forgot password link ( email as well ). I have make shift versions of those right now that are no good.
I am assuming due to the style of encryption, that I will need to prompt the user to reset their password.
I am just looking for the most secure way to do this. Any suggestions, or links to resources and tutorials, as well as what kinda of method I should use would be greatly appreciated.
thanks and good day.
Just to be clear, sha1, salted or cheesy onion flavour, is not encryption, it is called hashing. It's a one way function with unique output for unique. The idea of using a salted hash for passwords in your database is twofold:
The hash is a one way function, so nobody with access to the database can actually determine what those passwords are. Very good practise.
The salted part, assuming you're hashing the username+password+some junk, means that each username + password combination should be a unique hash. It makes dictionary attacks / shortcuts via precomputed hashes difficult, because most people don't have a dictionary of ninefingers:stackoverflow!!:{insertcommonwordhere} lying around. It doesn't stop them generating it, just makes it more inconvenient.
Now we've cleared that up, yes, if the user forgets their password, you can't email it to them because you can't reverse the hash. By design.
Instead, what you're looking to do is allow the user to securely reset their password. The simplest form of this is that, if the user enters their email address, you email them a link to your site including in its parameters a unique, use-once token valid for a short time window.
Other options? Generate them a password and email them that. The Uk Gov't Gateway here in the UK does something quite interesting: the web-page contains half the password, the email the other half. You need both to then log in again.
Now, the million-dollar question: is it secure? No. Nothing's secure. There is no 100% security. Ever. This particular method of storing passwords adds security because:
DBAs can't easily abuse their access to the user table;
Malicious requests that somehow select * from table users; can't easily read those passwords either.
But as soon as you rely on being able to email the user as a method of secure communication, you rely on:
Their email account being secure;
That their email is not being monitored.
The question then becomes - how secure do you really need to be? Implementing the email-out-a-reset-link solution will work for most cases because they're not high-value enough targets, really.
Related
I have an app where a few administrators will need write access in the data. To authorize them I was thinking about having their email address in a list in the database, since they don't have a uid until they have logged in for the first time.
Will this be safe enough, or will I have to figure out another way?
Thank you in advance!
If you are concerned with any security risks, the approach you are describing would actually be safe as it would minimize the chance that there is a bot or some other entity which may corrupt your data.
Additionally, you can always test your Firestore rules as mentioned over here so that you are happy with the security you are enforcing.
Hope you find this useful!
I think that is no big point if the email could be verified, means to make sure that it come from the actual email owner.
And will be better if it been encoded with appropriate encryption before saved into the database.
I am trying to find the best practices for forgot password functionality via sending a link to reset password i.e. sending an email with a one time token to the registered user. The token will be stored in the database and when the user clicks the link, we check the token and allow the user to set a new password.
Best practices while designing forgot password function -
The token must be unpredictable, that's accomplished best with a
"really" random code which is not based upon a timestamp or values
like the user-id.
Like a password, the token should be hashed, before storing it in
the database. This makes them useless for an attacker, even if the
database is stolen.
The reset-link should preferably be short to avoid problems with
email clients, and contain only safe characters 0-9 A-Z a-z
(base62 encoded)
The token should have an expiration time within single-digit hours.
The token should be marked as used,after the user has
successfully set a new password.
When a user changes their password or requests another password
reset, expire all tokens already associated with their account.
These are some of the points I found. What can be other security issues that should be considered ?
Sources:
Secure password-reset function
Ycombinator News
A couple other practices I've seen:
Check user is on the same machine/browser/IP as the one where the reset password request was triggered (unless it was initiated by admin/system).
Rate-limit number of reset tokens that can be generated for an account.
It should also be noted that the best practice is usually to use an established library rather than inventing your own mechanism, as too many things can be overlooked.
I have the same question and found the OWASP Forgot Password Cheat Sheet.
Also few things that I would like to add:
Usually if user entered non existing email sites anyway shows message "pwd restoration link was sent". This is due to prevent hackers from determining that user with the email exists in system. But IMHO it's better to say user that email is not exists because usually it may not remember email used during registration.
It is better to add some additional personal question to user like a birthday date. If hacker stole user's email it makes harder to receive reset link. But since reset link may be sent to user by site admin the question with birthday must be on change password page which is opened by link.
Hackers may automatically send a lot of letters to some user. Some sites uses a CAPTCHA near email field to prevent this.
After successful changing of password all active sessions should be closed and user must be logged out. Thus even if hacker is logged in he will logged out.
It is a good idea to hash a restoration ticket like a password. Here should be used the same hashing algorithms like with password: Argon2, SCrypt, BCrypt.
After user restoration password it is good to mark it a possible fraud and for some time (like a week) do not allow to make some critical actions, like withdrawal money from account.
Also some sites are sending a letter to user that it's password was changed. They do this when user was logged normally changed it manually but maybe it is good to send the same latter when pwd was reseted.
I understand that a hash salt combination is the ideal way to store a users password. I also know that hashes are one way and not really possible to get the original plain text.
So, if one is to implement a "forgot password" function in a web application, what would be the best way to get to the original plain text password so we can send that back to the user?
Hopefully this isn't too ignorant of a question.
David
You don't. You can either change their password to a new (random) one and send that, or you send them a link that will let them access a page where they can enter a new password.
I need to know if an installation has been paid for in the past so I can provide some premium features.
Storing a payment flag in indexeddb or the file system sounds easy to defeat. Periodically asking a server and caching the response could do the trick, but I guess the user would have to be logged-in at all times (through google or otherwise) and I'd rather not impose that restriction.
Maybe if there's a way to uniquely identify a user's machine (uuid, mac address, etc) that could allow me to determine if they've made that payment?
Ultimately, this is client side JavaScript. The only means by which you can prevent use of certain features, is to put them on your server and charge for the service.
Some weak methods for preventing access include license validation, and asking the server for non-essential information (if it was essential, then see the above).
For license validation, you could create an algorithm that takes data from the user and transforms it into something else. For example, say they create an account on your website, which your server knows is a 'pro' account. You could then take their first name and email address and do some magic on it.
Here's a simple example that takes those inputs and gives us a key. In this example if our first name is "John" and our email is "john#domain.org", then our key will be fcumnflqjpBfqockp0qtifcufLqjp. However, Tony, with the email "tony#doman.org" would recieve fcumnfvqp{Bfqockp0qtifcufVqp{
You can send this key to the user, and have your code decide whether it can extract the name and email by applying the reverse algorithm.
You can reverse the strings, do various bit math, etc. It's security by obscurity. Other than an account, this is the most common method. It's used by nearly all offline software. Its kryptonite is key generators, which reverse engineer your code, and generate keys by the algorithm you use to verify them.
All the methods such as uuid, mac address etc can be easily forged imo. I think you cannot escape keeping track of user's logged-in status. Implementing something like a cookie based mechanism would be the right way to go.
my goal is to give my customers an option to lock their App's Data, so when they give their iPad/iPhone to someone else for an extended period of time, users can't access or accidentally look at confidential data.
[Some Background: It's a medical Application where physicians/staff-members would give iPads to patients. Now the patients are supposed to access some contents, yet shouldn't be able to look at other patients data]
So far, I have a password inside my App. But when a staff-member forgets and wants to reset it, the only thing I can do is "deletion of the whole database". I have a Disclaimer telling people to store their password somewhere, but this is still not the optimal user experience.
Is there anyway I could authenticate the user via his Apple-Password? This way only the person knowing the Devices-Account password can access the data and can always reset the Apple-Password with Apple.
PS: Server-Solutions, like having a User-Password pair with reset-via-mail on a server of mine is out of the question, since it would add to much complexity for the users and in many medical situations the Device shouldn't have access to the web.
Multiple thoughts:
I am not aware of any native public API to authentication using Apple password.
If your app is enterprise app, possibly you can use native private API. I would recommend to disassemble AppStore and check how does it do authentication then
You can also to try to access to some Apple web page which requires authentication and pass to it apple account and password and see what it will return. If it authenticated correctly, then you are fine and you can reset a password.
To make it secure, you will need to ask a user to enter it for a first time, so you can encrypt your encryption keys using authentication material (so you can decrypt encryption key later on).
However, I am not very big fan of this solution, since you can change Apple password and you will be stuck in such case.
Server solution is the best option and it's not that complex. Another option is Forgot password. You ask something what administrator know ("What is your first pet?") and he enters the answer when your application is configured and this answer could be used later to unlock your app.
P.S. And the best solution at the end (which is absolutely shameless self advertisement). A startup which I am part of (SpydrSafe) works on the product which solves exactly your problem. In fact, healthcare is one of the verticals which whom we actively works. If you are interested, contact me (my email is in profile)
if you authenticate the user via apple password, and they forget their apple password, then in order for them to retrieve that password is by reset-via-email .... so either way you are stuck with that dilemma.
As for actually using your apple password, no.
Best way to get what you want is to have the password stored somewhere in real life. Like another computer that the doctors can report to and ask for passwords or just don't forget the password.