When a user forgets his password, you shouldn't send it by email. In his Pluralsight course "Hack Yourself First: How to go on the Cyber-Offense", Troy Hunt states that "there is no implicit transport-layer security on SMTP". This answer on Information Security Stack Exchange confirms that it's a bad idea to send or store passwords in the clear (including by email).
The proper way to reset a password, it seems, is to not reset it immediately. Instead, send the user a time-limited activation link via email. This requires manual intervention of the user and also does not communicate the password via email at any stage.
The aforementioned Information Security answer describes how one might implement a password-reset mechanism:
Don't RESET user's passwords no matter what - 'reset' passwords are harder for the user to remember, which means he/she MUST either change it OR write it down - say, on a bright yellow Post-It on the edge of his monitor. Instead, just let users pick a new one right away - which is what they want to do anyway.
If a user forgets their password, send them a secure one-time reset link, using a randomly generated reset token stored in the database. The token must be unique and secret, so hash the token in the database and compare it when the link is used.
The definitive guide to form based website authentication describes the implementation similarly:
Always hash the lost password code/token in the database. AGAIN, this code is another example of a Password Equivalent, so it MUST be hashed in case an attacker got his hands on your database. When a lost password code is requested, send the plaintext code to the user's email address, then hash it, save the hash in your database -- and throw away the original. Just like a password or a persistent login token.
But how will the user actually know the new password. Is it reset to some default? Is it changed to a randomly-generated password that needs to be communicated with the user somehow?
In "Hack Yourself First: How to go on the Cyber-Offense", the activation link takes you to a form where you can enter your new password.
That might be okay if you're dealing with a website, where you can go in and interact with the web application and choose your own new password. But with something like the .NET Web API, you're interacting with actions on controllers that are normally supposed to give you data, not a user interface. You can't just give them a link and expect them to do something with it.
Thus, if you're dealing with authentication over Web API, what is an effective and secure way to allow users to reset their passwords and also communicate the new password to them?
The thing to remember in this scenario is that Web API is just that: an API. Even though there might not be a website, there is still a user interface somewhere (an actual website, or a WPF application, or a mobile application - doesn't matter). So the usual secure "forgotten password" functionality can still be implemented.
There is one difference, however. Instead of sending a link, send the token itself. The UI then provides the place to enter the token. The steps to follow are below:
The user wanting to reset his password goes to the appropriate "Forgotten Password" screen in the UI.
The user is prompted for his username.
A token is sent to his associated email address in plaintext. The hashed version is stored in the database together with an expiry of, e.g., one hour from now.
The user enters the token in the next screen.
If the token is valid, the user is taken to a screen in which he can enter a new password (without having to enter the old one - the token already authenticated him).
Sending a plaintext token via email might sound a bit like sending a password via email. However the fact that it expires after a short period of time gives an attacker a very small window of opportunity to use it. Also, the token is one-time, and is discarded upon use.
There are two concepts you're addressing in this question: password reset and the mechanics involved, and the proper way to authenticate a user to a web API. I think it's important to draw a distinction between them and to understand the latter first.
Imagine you have a web application and a protected resource (web API). The web API requires that all callers must be authenticated by some mechanism. One way to allow a user to authenticate to the web API is to present credentials directly to the web API, but this presents many other issues such as the web API needing to store/maintain/access user account info, the security weakness in sending passwords along the wire in this fashion, the broad scope the web API has to act on the user's behalf when it obtains their raw credentials, etc.
You've probably heard of OAuth 2.0, which addresses these problems. A better way of accessing a protected resource (web API) is to add an authorization layer. For example, a web app presents a dialog for entering a user's credentials, which are then sent to an authorization server and validated, which produces an access token. The access token can then be used to authenticate calls to the web API on behalf of the user (or on behalf of an application using client credentials grant). Using this flow, the web API doesn't need to authenticate users directly, it can be much more lightweight, and many other security issues with the other flow are addressed. See the OAuth 2.0 specification for more detail.
Getting back to your example, a better answer is that you manage password reset at a different level. Your web API shouldn't have to know about the user and password at all, let a lone resetting it -- it should just receive a token and validate it. This allows you to play around with your desired password reset method and it won't affect access to any of your downstream resources.
Related
I'm learning Node, doing authentication stuff at the moment with passport.
Say my server has 2 pages, a public home page with various login options, then a super-secret page(and perhaps more) that is only accessible after authenticating.
If I'm only going to be using 3rd party strategies, is there any reason to have a database?
I know that you'd obviously need one for local user's id and pass, but if the server exclusively relies on 3rd party authentication, would session persistence be enough things to work? Or are there still various things that you would need to save for some reason (apart from logging) ?
Could you do without a database, sure... but in this case what is the point in authenticating at all? All you would be proving is that the user has a Google account which anyone can set up for free in a matter of minutes.
If your content is super secret then chances are you want to have a database of users (email addresses and the like) that have permission to see the content. By authenticating through OAuth you will be given an access token that will allow you to fetch the authenticated users email address. This can then be looked up against your user table to see if the user is registered and if your app enforces it, check whether the user has access to the page requested.
OAuth is proving that this person is the owner of the Google/Facebook/Twitter/Github Account. You can use this knowledge to sign someone in against a database of "local accounts" based on email used at sign up, assuming you validate the email on sign up locally.
I'm new to OAuth, and although I have scanned through many documents, I don't seem to have yet a good architecture / design to a secure web application, answering most/all of OWASP Top Ten
My newbie questions are
Why can't I just rely purely on OAuth? why do a user needs credential in my own application?
If I do, do I need hash / salt anything if I save it? I don't store any passwords, but what about tokens?
I still need to persist the users so they won't login everytime, (like in OS) - do I
Somehow use the OAuth token (save it? does it make even sense)?
Or use the plain old httpOnly secure cookie (if so, what happens if they log out of the Oauth provider? shouldn't I in this case ignore my cookie and let them log out?
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
I guess I have a lot to learn, but reading on so many potential security issues, and having to master so many different topics seems like a good potential for me missing something that someone later will exploit.
Is using a framework such as Spring Security, or using Lift's built in user management going to save me all this headache? or do I have to know exactly what I am doing to avoid things like Session Fixation, Cross Site Request Forgery, Cross site scripting, Rainbow tables and other things I only remotely get...
Why can't I just rely purely on OAuth?
From a service providers perspective, OAuth is a means of controlling access of third party applications to the business logic. The end user does not have to give out his password to the third party app, and the access can be controlled. For example, the provider could restrict the access to only parts of the service for limited amount of time.
If you write a third party application, there is no strict need for you to have your "own" user artifacts. You can rely on the users that authenticate your application.
You could require that user's have an account with a provider such as Facebook or Twitter and not implement any password stuff yourself.
(You probably need some sort of artifact to represent a user, it should in this case contain information about how that user authenticates your application, for instance an OAuth token, or an OpenID URL).
If I do, do I need hash / salt anything if I save it? I don't store
any passwords, but what about tokens?
Just to clarify, in OAuth a token is typically both a key and a secret, and they are needed in cleartext to sign requests (there are differences here depending on which version of OAuth you use). So you can store them encrypted, as long as it is reversible for you.
I still need to persist the users so they won't login everytime, (like in OS) - do I
somehow use the OAuth token (save it? does it make even sense)?
Yes this makes sense, a token represents your applications access to a specific user's data. Save the token if you want to keep a "session" alive.
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
There is no concept of "logging" out of OAUth, a token either has an expiration time or not. You can of course "log out" by simply choosing to forget the token. The next time you will have to redo the authentication. You cannot force users to invalidate an access token, unless the provider has an API for that.
You could save the token in a cookie, but I would use other unique identifiers for the session you want to keep alive. You can persist the details of the tokens server side. The information you store in your cookie shold make it possible to retrieve the token you need.
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
If you save a token in a database, save an ID for that token in a nice secure cookie. When a user goes to your service, use the information in the cookie to make a call from your service, to the service provider, to check if the token is still valid. If so, you have established enough trust for you to "log in" the user in your application without having to go through the pain of the OAuth process again.
And as a side not, StackOverflow uses OpenID and not OAuth for user authentication. OAuth can be used for the same purpose but is mainly a specification for application authorization.
I hope this helped, and don't sell yourself short. This site is for posting questions, not for appearing all-knowing.
I just started integration of OpenID in my website. All the examples I saw store the claimed IDs in cookies. How is it safe?
For example, myopenid.com returns a claimed ID that is {username}.myopenid.com
So if a hacker knows your claimed ID, he can easily hack your account.
Of course you encipher/md5 the ID before putting it into the cookies and using for authentication, but it's like storing a username without password!
Update
Now that I thought more about it, I realized, that you need to be logged in the OpenID provider, so even if the hacker gets the username, he still needs the provider's password to log in. Am I correct?
Update 2
No, update 1 is not correct :) My site cannot check whether the user is successfully logged in or not. All I receive is the claimed ID, and I just have to trust that the user is authenticated. That's really confusing...
Knowing the user's claimed identity isn't enough to authenticate.
Indeed, the user would have to be logged in to his provider, in order to authenticate with your website using that identity.
As for "trusting that the user is authenticated" -- no, you don't trust. As a final part of OpenID authentication you're supposed to verify that the authentication message comes from the provider. There are various security measures in place to ensure that the message is authentic, unaltered, etc.
If you do that, you're sure that your user is properly authenticated by the provider.
Now, since you don't want to do it every time your user makes a request, you store the session information in a cookie. However, you don't store only the claimed identifier (if you decide to store it at all), but a session id -- a pseudorandom number generated at the moment your user logs in. Since it's pseudorandom, no one can guess it, and therefore, knowledge of a claimed identifier itself doesn't mean anything.
If that answers your question, read about session management in your favorite language/framework, as it will tell you how to easily implement such mechanism, and how it works.
In summary: think of OpenID as a replacement for a password verification. You don't need to (and shouldn't) store logins and passwords in cookies, and you don't have to store claimed identifiers. Similarly, you don't verify that the login and password matches every time, but remember that the user is authenticated in a session.
I asked a similar question here a while back but all the answers were offering OpenID which is nice but it doesn't work with services that require authentication that don't use it (such as EventBrite).
Say I want to create an app that lists your events from event brite, and their analytics (which eventbrite includes). Any person can sign up for this service to list their events. But since EventBrite doesn't have OpenID to authenticate, I need to somehow get the user login and password to EventBrite.
Some possible solutions are:
Store credentials in YAML like this. Easily hackable.
Have user enter in credentials into a form on my site, I save the credentials to my database, and use them to login to EventBrite. Easily hackable.
Have user enter in credentials and I pass them directly to EventBrite without saving, and I save the response header Cookies to the database, and when they expire, have them login again. Is this easily hackable?
This hypothetical service also wants to automatically check events (say via cron), so it doesn't depend on the user going to my site via the browser. So cookies or credientials need to be stored somewhere.
The thing is, after asking this similar question about confidentiality and security it sounds like you should never build an application that does what I'm describing. There's got to be some way building something like this is okay.
What is that way? What am I missing? Is it okay to go with #3 and save the cookies (but still needing the user to submit their email/password via a form which I send to Eventbrite)? What is an acceptable solution to the problem?
There isn't a secure way to do this. You can employ workarounds, but that's about it.
Storing passwords in YAML or XML in cleartext is definitely out
In fact, even encrypting and storing passwords is wrong. Your application would need a way to decrypt the passwords, so the attacker can also decrypt the passwords.
The recommended way to store passwords is Salt + Hash, but because it becomes unrecoverable, it is useless in your case.
Because of 2 & 3, no matter where you store the users credentials, you are vulnerable.
Storing the cookies instead of the passwords is a better idea. But again, this involves the password going through your website, which isn't good.
Given your situation, storing the cookie is a better approach. Use HTTPS throughout, even on your website. Its less than ideal though, and you and your users should be aware of it.
Eventbrite has recently release new documentation describing how to implement OAuth2.0 for cross-site user authentication.
I would recommend using our javascipt-based OAuth2.0 widget, which stores the user's authentication tokens in their browser's localStorage by default.
Since the auth tokens are stored in the user's browser, and are prevented from being accessed by other domains, it's not likely that there would be any security leaks.
The need for email and password combos are completely avoided in this authentication scheme.
Most sites only support direct login with the original cleartext password, so you have to get, store and provide that too. And I would never ever trust you with that.
The problem with your concept is that you require the password to be given to a third party. The solution is not to involve a third party, for example my browser is pretty good at storing and filling in passwords for me automatically (my hard-drive is password protected too). And they are dozens of other password wallet apps too. I wouldn't gain anything by subscribing, using your service.
Before going into such a business, consider you are going to be the #1 target. Facebook, Google are incredibly paranoid about security, spending a lot of time, money and effort to keep the logins safe. Do you have the same resources? Then you are a better target. Also by hacking your service, they immediately get multiple accounts, passwords of your users, also seeing who is always reusing its password.
For working with the Eventbrite API, I'd recommend ensuring that all connections are over SSL, and that you authenticate using a user_key rather than a username and password.
More information about authentication for the Eventbrite API is here: http://developer.eventbrite.com/doc/auth/
After logging in, users can find their user_key here: http://www.eventbrite.com/userkeyapi
This should prevent username and password information from being intercepted over the wire, or read from a local data store.
I want to understand what token-based authentication means. I searched the internet but couldn't find anything understandable.
I think it's well explained here -- quoting just the key sentences of the long article:
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.
In other words: add one level of indirection for authentication -- instead of having to authenticate with username and password for each protected resource, the user authenticates that way once (within a session of limited duration), obtains a time-limited token in return, and uses that token for further authentication during the session.
Advantages are many -- e.g., the user could pass the token, once they've obtained it, on to some other automated system which they're willing to trust for a limited time and a limited set of resources, but would not be willing to trust with their username and password (i.e., with every resource they're allowed to access, forevermore or at least until they change their password).
If anything is still unclear, please edit your question to clarify WHAT isn't 100% clear to you, and I'm sure we can help you further.
From Auth0.com
Token-Based Authentication, relies on a signed token that is sent to
the server on each request.
What are the benefits of using a token-based approach?
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX
calls to any server, on any domain because you use an HTTP header
to transmit the user information.
Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contained entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Decoupling: you are not tied to any particular authentication scheme. The token might be generated anywhere, hence your API can
be called from anywhere with a single way of authenticating those
calls.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a
token-based approach simplifies this a lot.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to
sib your site, generate a POST request and re-use the existing authentication cookie because there will be none).
Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database)
is likely to take more time than calculating an HMACSHA256 to
validate a token and parsing its contents.
A token is a piece of data which only Server X could possibly have created, and which contains enough data to identify a particular user.
You might present your login information and ask Server X for a token; and then you might present your token and ask Server X to perform some user-specific action.
Tokens are created using various combinations of various techniques from the field of cryptography as well as with input from the wider field of security research. If you decide to go and create your own token system, you had best be really smart.
A token is a piece of data created by server, and contains information to identify a particular user and token validity. The token will contain the user's information, as well as a special token code that user can pass to the server with every method that supports authentication, instead of passing a username and password directly.
Token-based authentication is a security technique that authenticates the users who attempt to log in to a server, a network, or some other secure system, using a security token provided by the server.
An authentication is successful if a user can prove to a server that he or she is a valid user by passing a security token. The service validates the security token and processes the user request.
After the token is validated by the service, it is used to establish security context for the client, so the service can make authorization decisions or audit activity for successive user requests.
Source (Web Archive)
Token Based (Security / Authentication)
This means that in order for us to prove that we’ve access we first have to receive the token. In a real-life scenario, the token could be an access card to the building, it could be the key to the lock to your house. In order for you to retrieve a key card for your office or the key to your home, you first need to prove who you are and that you in fact do have access to that token. It could be something as simple as showing someone your ID or giving them a secret password. So imagine I need to get access to my office. I go down to the security office, I show them my ID, and they give me this token, which lets me into the building. Now I have unrestricted access to do whatever I want inside the building, as long as I have my token with me.
What’s the benefit of token-based security?
If we think back on the insecure API, what we had to do in that case was that we had to provide our password for everything that we wanted to do.
Imagine that every time we enter a door in our office, we have to give everyone sitting next to the door our password. Now that would be pretty bad because that means that anyone inside our office could take our password and impersonate us, and that’s pretty bad. Instead, what we do is that we retrieve the token, of course together with the password, but we retrieve that from one person. And then we can use this token wherever we want inside the building. Of course, if we lose the token, we have the same problem as if someone else knew our password, but that leads us to things like how do we make sure that if we lose the token, we can revoke the access, and maybe the token shouldn’t live for longer than 24 hours, so the next day that we come to the office, we need to show our ID again. But still, there’s just one person that we show the ID to, and that’s the security guard sitting where we retrieve the tokens.
The question is old and the technology has advanced, here is the current state:
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for passing claims between parties in web application environment. The tokens are designed to be compact, URL-safe and usable especially in web browser single sign-on (SSO) context.
https://en.wikipedia.org/wiki/JSON_Web_Token
It's just hash which is associated with user in database or some other way. That token can be used to authenticate and then authorize a user access related contents of the application. To retrieve this token on client side login is required. After first time login you need to save retrieved token not any other data like session, session id because here everything is token to access other resources of application.
Token is used to assure the authenticity of the user.
UPDATES:
In current time, We have more advanced token based technology called JWT (Json Web Token). This technology helps to use same token in multiple systems and we call it single sign-on.
Basically JSON Based Token contains information about user details and token expiry details. So that information can be used to further authenticate or reject the request if token is invalid or expired based on details.
When you register for a new website, often you are sent an email to activate your account. That email typically contains a link to click on. Part of that link, contains a token, the server knows about this token and can associate it with your account. The token would usually have an expiry date associated with it, so you may only have an hour to click on the link and activate your account. None of this would be possible with cookies or session variables, since its unknown what device or browser the customer is using to check emails.