Usage of JWT after logout - security

I have a query, is it possible to use current JWT after the user is logged out?
Scenario: I have a set of private APIs that needs authorization token to access the endpoints. Here I have a web application where I need to log in and get the JWT. I keep the token aside and from the active session I press the logout button and my session is needed to expiry even though I am able to use the JWT to access the endpoints, how will this happening is this the right approach or can I raise this as a bug?

How this is happening?
The session details might be stored in JWT itself and there is no server side state for the same. Every time you are sending the JWT, they are trying to decrypt it, then validating the claims present in it and providing the required access. Since, the JWT itself contains its expiry information, they are unable to invalidate it. It will be expired after specified time decided at the time of token creation. They might be just clearing the cookie at the time of logout.
Is this the right approach?
Depends. It's tradeoff between speed and security. In order to revoke the token access, there should be a server state maintaining the set of access/revoked tokens. If the application is not storing any confidential/sensitive information, its a design call for them to opt for a server state. If the site is on https and free from XSS, the only way to get the token somehow is by gaining physical access to the device. If the expiry time of access token is less than 20 min, the risk is minimal. But it mostly depends on the nature of application. For example, this is not a right approach for a banking application.
Can I raise a bug?
You should to confirm the hypothesis. There can be a possibility that they actually have an infrastructure to revoke the access tokens but its faulty as of now.

Related

Access/Refresh token confusion

I've been doing a lot of reading on this subject and I can see that there are many different opinions and approaches to authenticating using JWT.
My understanding is as follows:
In its simplest form, a JWT authentication mechanism should:
Verify username and password.
Create a signed JWT access token containing information (depending on the app's needs) on the user.
Send that token in the response.
The client then stores the token (which from my understanding there is some debate whether a secure cookie or localStorage is more secure), and sends it with each request's headers.
The server can then authorize the user using middleware verifying the JWT. No state, all information in contained within the JWT.
Assuming the JWT has no expiration (or perhaps a very long expiration date, maybe a couple of months), it sounds good because I can provide the user a persistent logged in state for a long time. The concern is, to my understanding, if the JWT was to be stolen, it is essentially an unlimited access card and a huge security breach.
So that's where the refresh token enters, the server issues both refresh and access tokens (refresh token with a long/unlimited expiration and the access token short).
The server database holds some kind of table of valid refresh tokens (so that if one is stolen it can be invalidated easily) and when issuing a new access token, validates the refresh token.
This also adds the need to add some sort of countdown mechanism on the front end where a refresh request is to be sent to the server prior to the access token expiration date so that the user won't be logged out.
And my question:
Why? If we go through all the trouble of creating a db table for refresh tokens, why not just make a table of valid access tokens and invalidate them if needed? How is that less secure than using refresh tokens?
Thank you
Access tokens aren't primarily used to provide extra security, but to provide efficiency and decoupling.
An access token can have a very short lifetime - maybe even less than a minute - but be used to authenticate multiple requests to different services within that time. Those services don't need to have any access to the authentication database, because they can trust the access token until its expiry date; that makes them faster and simpler.
For instance, if you're using a dynamic page with lots of AJAX requests, that might run in very quick succession. Those AJAX calls might be implemented as serverless functions (e.g. AWS Lambda), or as standalone scripts in different programming languages on different servers, or you might just want to make them as efficient as possible, and avoid any database access. The only information that needs to be shared between them is a public key to verify the signature on the JWTs they receive.
From a security a point of view, this is a trade-off: on the one hand, an access token for a user whose access has been revoked can still be used until it expires; on the other hand, the long-lived refresh token is transmitted much less than a traditional session token, so there are fewer chances for it to be intercepted.
To address your concrete concern:
This also adds the need to add some sort of countdown mechanism on the front end where a refresh request is to be sent to the server prior to the access token expiration date so that the user won't be logged out.
No "countdown" is needed. The code that has access to both tokens simply looks at its current access token before using it; if it has expired, or is about to expire, it requests a new one using the refresh token. It then gets a new access token, and probably a renewed refresh token - the expiry date on the refresh token represents how long the user can be idle before they are automatically logged out.
We don't need to make a table of access tokens and it is dangerous to secure.
We have to save only refresh token and add one field for valid/invalid in the table. And send access token and refresh token to the client side.
The clients send access token with each request's headers.
The server can authorize the user using middleware verifying the JWT.
After some time, the access token will be expired(access token's expired time is shorter than the refresh token's expired time).
The client sends refresh token to server.
Then the client will get new access token using refresh token(refresh token should be recreated, in other words, we can use only one-time refresh token, we have to update table of refresh token with new refresh token).
The client can get new access token and refresh token.
I hope it will be help you.

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.

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.

What is token-based authentication?

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.

Resources