How reauthentication is handled in current modern web application - security

In our web application, when a user logs in, if the session is idle for longer than 15 minutes, the user has to enter the login credentials again to continue.
As I do not use other web applications I would like to ask the following questions concerning this matter:
Is such a reauthentication usual in current web applications?
After how many minutes inactivity does it come?
From a security standpoint, is it common and reasonable to only ask for the password (and not the user name again)?
If you fail to reauthenticate (3 times), is it more common to only end the session or lock the whole account?
Thanks alot in advance

Re-Authentication
Re-authentication is the process of making a secondary confirmation of a person’s identity after checking previously. Usually a user has to perform an additional login by force to ensure that a user who is accessing a protected resource is the same person who initially authenticated at the start of the session. Forced re-authentication provides additional protection for sensitive resources in the secure domain.
Authentication is token based. Rest APIs are designed with this too, and can sometimes perform re-authentication.
Of course, sessions are used.

Is such a reauthentication usual in current web applications?
Yes it is. Most web applications that have access to valuable data implement the reauthentication mechanism to prevent information leak.
After how many minutes inactivity does it come? Depends on the application and the sensitivity of the data you're protecting. The normal timout is 15 to 20 minutes (Its even lesser in Banking web apps)
From a security standpoint, is it common and reasonable to only ask for the password (and not the user name again)? "Login" refers to a correct combination of username and password. Most web apps will ask you for the username again. Unless that is you have the "Remember my username" option enabled. This is because a malicious user can potentially get your username after accessing the web app after your session timed out. If he also manages to get his hands on your email (which is usually linked to your username), he can easily reset your password and do whatever he wishes with your account
If you fail to reauthenticate (3 times), is it more common to only end the session or lock the whole account? This too depends on the application.
Data is very valuable -> Lock the account
Not so much-> End session and force Reauthentication (3 more tries)
Best of both worlds-> Timeout the username for a fixed duration (Ranges from half an hour to a couple of hours) and then force reauthentication.

Session times out usually at 15 to 20 minutes depending what it's set to in IIS. That is a reasonable idle time for a user to be logged off. If you need your application to sit idle and still be usable for longer periods than that you'll want to look into token authentication (stateless) and using refresh tokens.

Related

Shall JWT expires in mobile apps?

I've implemented lots of Restful APIs and web applications, I used to generate a JWT and give some time for expiration.
Currently I am developing mobile apps, and they all work on the same Restful APIs, but I am a bit confused of should the token expires in mobile apps and log out the user?
On many places, websites and as I do know JWT should never ever live eternally and the time for expiration must be kinda short period of time, maybe one day or less.
But if the mobile logs out the user, would it be considered bad User Experience
On the other hand, the user might click Remember me check box, so how would the JWT get expired?
Any idea would be appreciated.
There are several different ways to handle JWT expiration. First thing is to determine the value of your token. If you're using the token as a log-in to a game server, you might not be as worried about having a week-long expiration as you would for a banking app.
There are lots of ways to handle token expiration, but the most common I find below.
Automatic time-based expiration. This is a best practice, because a hijacked JWT will have less value. As you mention, logging the user out unexpectedly can be a poor experience, so one option are to include a "refresh" token, that can be exchanged once for a new, fresh, valid JWT token when the shorter-lived token expires. Refresh tokens have a longer lifetime, and may be bound to additional details such as a secure element on the device, or a policy such as in-session only (e.g. must obtain a new refresh token on app restart).
Policy-based revocation - instead of relying on a baked-in timeout, you can issue a revocation of the JWT. This relies on your services deciding when to revoke a login, and publishing the revocation somewhere it can be checked. This basically is what opaque tokens do, and thus you've just thrown away one of the advantages of JWT, but you can time out a session based on activity observed by your services.
Generally, these token management policies operate independently from the "remember me" function, which is usually a special "long-lived" (e.g. forever, 30 days, 90 days etc) token that is secured behind a secure element (e.g. fingerprint recognition, password etc) on the device that's used to obtain session tokens when a user starts a new app session.

How is using JWT refresh tokens and short lived access tokens not massively insecure?

As I understand it, the typical (and simplified) usage of JWT refresh tokens is as follows:
User logs into the system. User is granted a refresh token and a short lived (e.g: 10 minute expiry) access token. The refresh token is stored in the database of the "authentication server" for revocation purposes. Any requests made to the app ("resource server") will use the short lived access token.
When the user's 10 minutes are up, the client will send a request to the auth server for a new access token using the refresh token.
When the user changes their password or revokes access to a specific signin (in the case of theft, a lost device, etc), the refresh token is removed from the auth server database and rendered invalid.
Thus, when a user accidentally leaks his password out or loses his device, he can simply change his password, which would cause all previously issued refresh tokens to become invalidated.
However, the obvious security hole here is that the short lived access token is still perfectly valid for the next 10 minutes. And 10 minutes, no matter how short a time, is still plenty of time for a malicious user to cause some damage.
The only possible solutions I can think of are to:
maintain a blacklist or whitelist of access tokens. This makes the
usage of refresh tokens seem pretty redundant. If we're going to hit
the database on every request or to keep a cached list of blacklisted
access tokens, then what's the point of having a refresh token?
make the expiry of the access token shorter (e.g: every 1 minute
instead of every 10 minute). This doesn't solve the problem perse, it
just does some damage control, since it shortens the window of time a
malicious user has to do damage. And hitting the database for a new
access token every minute doesn't seem much better than hitting the
database on every request.
I have been working on the exact same problem. Although I cannot say I am any sort of definitive authority on the subject, I'm glad to share what I came up with based on a lot of research and building out a proof of concept.
The requirement is to have instant token access token revocation. During regular operation of the application, the actual probability of the scenario of a malicious user gaining access to someone's account is relatively low. This is not to say it should not be accounted for, but it's not going to be the case for 99.9% of request that come into your system, thus having it check the access token against the database on all the requests where it doesn't matter is bad design in my opinion.
However, bad design or not, it doesn't change the requirement. Requiring the access token to be refreshed every minute does not seem to be much better as it would put tremendous strain on the auth server and database. Managing an in memory access token revocation list wouldn't do much good because it wouldn't be shared across instances. Depending on your volume of users this may be able to get a way with using a database for while, but I don't think it would scale beyond a certain point.
The solution I chose to go with is using a shared in memory database/cache. I've evaluated Cassandra, Redis, and Apache Ignite and for the time being, decided to use Ignite. Because I am not sure how it will perform once this goes to production, I've made the components easily swappable for another in memory solution in case the performance is not sufficient.
I have a JWT filter responsible for validating each request, at the end of which I make a call to the shared cache to check a access token revocation list. I anticipate the list will be empty the vast majority of the time. To further reduce potential performance degradation, I hash to tokens to about 40 characters using MD5 before revoking them. This capability allows me to have an hour long access token life and a refresh token with an 18 hour life without worry that I won't be able to remove a malicious user if the need should arise.
Personally, I don't see a way around keeping track of some user state on the backend. The trick is to do it in such a way that you can still easily add instances of your backend to scale your application.
The purpose of JWT tokens is that they are self-contained and live on their own for a short while. If that does not suit your requirements you can revert to another type of access token, namely an opaque one that requires so-called introspection at the Authorization Server (AS). You are right that (if the results of that call are not cached) that call will hit the AS every time and partly defeat the purpose of the refresh token but on the other hand, actively having to revoke cached access token results from each Resource Server that has done an introspection call will result in a management and overhead nightmare.
There's no silver bullet. You will have to choose the access token type, expiry and cache duration that matches your situation an security requirements best.

in ASP.NET Web API, How to de-authorize a user immediately after account lock-out or delete?

I'm building a new Web API application using OWIN cookie authentication (ASP.NET Identity 2.2) for security.
I'm new to the whole cookies thing, but I've got a head-scratching problem: How is a logged-in user immediately blocked from using the API if their account has been deactivated (either deleted or locked-out)?
This arises after a startling discovery that if I have a user logged in on a client app, and I delete their user account via a different app, they are still able to access the API (i.e. the [Authorize] filter still succeeds because their cookie is still valid).
Somebody please correct me if I'm wrong, but AFAIK, cookies are not stored on the server, so there is no way to "invalidate" the cookie.
Yes, if the user logs out, they won't be able to log back in again. Also, I understand that setting an expiry on every cookie upon successful login will mitigate the problem.
But what about the following scenario: a system administrator (let's call him JoeAdmin) gets fired or otherwise becomes untrusted and some other administrator locks out his account. If JoeAdmin happened to be logged in when he got fired and became disgruntled, he still has access to the system and can do some real damage.
In this scenario, how could JoeAdmin be blocked immediately?
JoeAdmin happened to be logged in when he got fired and became disgruntled
Also JoeAdmin could have saved the cookie value offline, awaiting for his account to be revoked, and then later restores the cookie value to his browser.
OWIN cookie authentication is not ideal if you ever need to immediately invalidate logins.
This is because all the state information about the user is stored client-side, authenticated with a secret only on the server-side.
That said, you could do something with Oauth2 refresh tokens like here. e.g. have an access token that expires after say a minute, which when expired the application has to use a refresh token in order to gain an access token for another minute.
This way, any revoked accounts are only exposed for a short time. However, you may need to deal with the complexity of out-of-sync clocks on client and server.
Long story short, if you need to secure your system in this way, traditional server-side tokens would be the way to go. They are more secure in this regard.
The risks with using OWIN cookies are very similar to those of using JWT's for authentication. See this comment and the associated question and answer.

Should I reuse OAuth 2.0 access tokens?

I am building an Authorization Server in terms of OAuth 2.0.
There is also a 3rd party web application (Client) which is using my Authorization Server. It's a regular web application, and the user may have several active sessions established with this application (for example, office and home machine, or just several web browsers on the same machine).
My Authorization Server issues an access token #1 (with or without the refresh token, that's not so important here) for Client once. When the user starts a new session with the Client, should the Authorization Server give the Client app the same access token #1 for that new session or should it issue a new #2 token?
My thougts:
From security point of view the new token might sound better, but then if the user wants to manage his authorizations, he will see a separate entry for each Client session, which might be messy.
For example, GitHub returns the same token for previously authorized clients, and on the "applications" page in my GitHub account I see only one entry per application, no matter how many sessions I've started, which is convenient.
However, this approach means that I have to store access tokens in Authorization or Resource server in the reversible way (plain-text or encrypted with some known key) instead of using irreversible hashing (like you usually do with passwords, storing salt and password hash from bcrypt, pbkdf2 or something similar).
Please be advised that I am not a security expert and this explanation
is my general idea of oauth. Reason why I mentioned this in the
beginning is because I see you are CREATING YOUR OWN AUTH SERVER based
on oauth 2.0 protocol, which means down the road some people might be
using your server for authentication, and thus I don't want you to
have the wrong concept.
The session-oauth mismatch
I want to clear this first that don't mix sessions and oauth. These are two separate things usually found working together IMHO.
Oauth protocol simply gives the apps/users with an access token via which the app/user can query your server for data associated with the token.
Session on the other hand depends on the application itself. Once some app received the token, they make a session out of it. When user logs in or logs out, the session is destroyed, not the oauth.
So what is the fate of oauth token?
Well from a server standpoint, each of your token should expire after a certain time period. That is it. Server does not know anything else. It gives you the token, then expires it after 'n' seconds.
However, the app may decide that it wants to revoke the access token. Maybe their website was hacked, or maybe they are done with all api calls. Then they can send a special request to your server telling you to force-expire the token.
So what should I do about user opening multiple sessions?
ABSOLUTELY NOTHING. As an oauth service provider, you are not concerned with sessions at all. All you know is that if the app asks you for a token, you give them one.
However, I will answer you question about sessions as well. Should you spawn different sessions for the same user? I would say yes. If you have same session, then if you log out from one machine, and refresh the page in second machine, since the session has expired, your other browser/machines will also log out naturally.
So how does github manages to not show extra entries?
Well I do not work for them so I don't know. But I guess that they will check each session, and if two or more sessions are associate with the same user, they know the user must be using many devices. Then when one of your devices sends some request to github, they can guess from the IP address your location, and if many of your machines are making requests from same place, you got to be using multiple machines. If not, then maybe some attacker is using your account as well.
This is how AFAIK banks predict malicious users - well not the only way, they sometimes also predict the pattern you are using to access bank records, and if that pattern is different, there are good chances that your account was compromised.
So now you may ask me, are you really sure that I should create as many tokens as the app demands me?
This is the part where I am not so sure. From what I have seen, oauth has two things. Google these two terms for more info:
Refresh Token: This token is not your access token. This token never expires, and once your access token is expired, you can use this token to get a new access token. This token is also to be kept secret.
Offline access type: Many oauth providers such as google and facebook also support this mode. This mode basically allows you to extend the expiry time of your access token. E.g. instead of normal expiry time of access token (e.g. 1 hour), for offline tokens you might have the expiry time of 1 year or so.
Answer to the question "Should I reuse OAuth 2.0 access tokens?"
Yes, the token is supposed to be used as many times as you need within the given expiry time (google sets it to 1 hour).
After it has expired, use the refresh token to get another access token and use it as many times as you need. Keep repeating the process.
If your users won't be online for you to start the oauth process, and you don't have the refresh token, then the app needs to have "offline" tokens.
Should I store my auth tokens?
You can if your app demands it, but it is nowhere recommended because of the potential to be leaked. Tokens are supposed to extract data within the given time limit and reissue the token when needed again. However, you surely can store them if you want.
"Offline" tokens, on the other hand, are expected to be stored. You can encrypt them if you like, but if the scopes are not too broad, I wouldn't bother at all.

Storing the OAuth credentials from DropBox securely in a Database for later use

I am building a web app which will use the DropBox API to save data to a users folder. There are 2 parts to the site: an ASP.NET MVC Front End and a Windows Service. At the moment, I was planning on dumping the oauth string and user Id from the authorisation request to database, and use that in both the service and website calls, but how should I store that information? Should I encrypt it or not? And if so, any recommendations on how? For example, if the database is encrypted, how do I store the Encryption key?
Do you want to always have access to the user's drop box account or only when they are loged in to your system ? I assume the former since you want to store the o-auth token. In that case see the encryption discussion below for why you can't really encrypt it. I'd suggest however, that you take the safer route and only access drop box either when the user is loged in or shortly their after (i.e. don't store persistent auth tokens )
The secure approach
When the user logs in, get an oauth token from the dropbox, use it to perform whatever actions they want and if necessary keep it around after the log out to keep doing tasks ( background sync or something). However, once that last task finishes, delete the token. This means that if your server is compromised only the loged in users or those that recently loged out are exposed. Its a mitigation, but its the best you can get.
I believe you can do this with o-auth without explicitly prompting the user for a new token every time. If not, I know you can do it with opendID, though I could see drop box not allowing that.
Finally, if neither of those works, you could store the o-auth key persistently encrypted under a key derived from the users password with say PBKDF2(with like 5000 iterations). When they log in, you decrypt it, use it, and then delete the cleartext copy. The downside to this is 1) password resets require a fresh o-auth token since you no longer have their key and 2) the user must log into your site itself and give you a password so you can derive the key. They cannot use openid.
Encryption
If you want continual access to the oauth tokem you can't really do meaningful encryption. As you said, where would you store the key ? For a web service, there is no good answer. For an end user system, the answer is derive the key from the user's password which you the must not store(this is what lastpass does). You can't do this because you want to have access to the data even when the end (wepapp) users are not loged in.
Ok, what about the sysadmin's password? Well since the server is running all the time, this is worthless since a compromise would still reveal the keys. Worse, reboots would take down your app because it needs the sys admin's password to decrypt its data and they are not likely their when the system crashes at 3am.
They make Hardware Security Modules that store keys and perform crypto operations with them, so an attacker could get the key because it never leaves the HSM. However, an attacker could just ask the TPM to decrypt the o-auth string. The best you could do was rate limit this so an attack could only get like 1000 tokens an hour (obviously that rate needs to be larger that legit usage). Given that HSMs are expensive and make hosting expensive because you need a dedicated system, this is not worth it.
In an ideal world, you'd use a TPM to hold the keys and have it only release the data if the system is not compromised. Unfortunately, TPM's currently only support verifying that the correct program (e.g. the boot-loader,then kernel, then user land program) was loaded. They do nothing if that program is compromised after it is loaded, which is the threat vector here. This might change in the next 5 to 10 years, but that does not help you now.

Resources