I'm using GData's AuthSub so that my administrative application doesn't need to store user/password information. I just came to the point in the documentation where I learned how to exchange the first, single-use token, for a session token (http://code.google.com/apis/accounts/docs/AuthSub.html#AuthSubSessionToken). And then this statement jumped out at me:
You can ignore the expiration date, which is not currently used; session tokens effectively do not expire.
Would someone care to explain how a non-expiring token is not a security issue? What does "effectively not expire" really mean? Theoretically if a malicious application manages to obtain one of these tokens, can it continue to use it regardless of password changes? Is it possible to see what session tokens have currently been issued on a Google account?
In short, my paranoia has taken hold, and I need a big smart person to comfort me!
EDIT: You can manually revoke tokens at https://www.google.com/accounts/IssuedAuthSubTokens
Yes, in fact if a session token never expires it is a vulnerability is recognized by CWE-384 , If the session takes a really long time to expire then it is a violation of CWE-613. Both CWE pages give a great explanation of the vulnerability. I do not know the specifics to this applications, but normally a Session token can be used to immediately authenticate without need for the username/password.
Related
Using Spring Security and JWT:
Is there a way to invalidate the token if it's from a different
device?
How am I supposed to know whether the token provided is a stolen one
? I can easily copy and paste the entire token and provide it
Thanks
Im going to answer this as simple as possible without trying to have a full blown discussion.
Is there a way to invalidate the token if it's from a different device?
No. This is one of the major big reasons why you should not be using JWT's as sessions. They are issued, and then most often their integrity is validated by checking the signature and then, no more.
Session cookies have all their info stored server-side, which means you can invalidate a session, server side, and when someone presents the cookie you can say NO.
Tokens have a lifetime that you can check, but since most implementations are stateless, we have nothing to invalidate server side, so we can't invalidate the JWT. It has to "time out".
There are probably custom solutions etc out there but all major implementations work this way. Owasp talks about different solutions built in token revocation
This problem has been mentioned several times, but developers dont seem to care.
JWTs are dangerous for user sessions
Stop using JWT for sessions
Stop using JWT for sessions part 2
Why JWTs suck as session tokens
How am I supposed to know whether the token provided is a stolen one ? I can easily copy and paste the entire token and provide it
you can't. How do you know someone hijacked your facebook account? well you report it to facebook that it has been hacked. You can't know who is in possession of any token at any time just based on tokens alone.
Thats why we have certificates (TLS), we have other security measures like CORS, CSRF, ip whitelisting, usernames and passwords etc.
This is what is called Zero Trust If someone presents the token, you have trust that they are who they claim to be unless you want to start whitelisting IP-address (but they can be spoofed with vpns etc)
Security is difficult, and sadly you have now understood the difficulty with it.
Token stealing is a thing, you must instead focus on making sure no one can steal the token.
If we pose a question "Why not use a non-expiring access token, and not bother with a refresh token?", the answer would probably be "Because if an access token is stolen, the malicious actor has X time (the lifetime of the said non-expiring access token) to perform malicious acts on behalf of the user that token was generated for." So the way that problem is solved, as far as I understand, is by, on successful authentication, sending the user a token-pair of a short lived access token, and a longer lived refresh token. I don't see how this isn't just an attempt at circumventing the original problem. The problem apparently lies in the theoretical possibility of the access token being stolen. So that if it ever is, it's validity expires quickly, so the malicious actor can't be authenticated for a long time. In this hypothetical situation, if whoever can steal the access token, why can't they steal the refresh token instead? The usual answers I got were something along the lines of:
"You have to store the refresh token in a safe place." This makes no sense to me. Why wouldn't I store both the access token and refresh token in a "safe place"?
"The access token has a higher chance of being stolen because it's used more often than a refresh token". In this case, I suspect that "stolen" means "sniffed", as in a Man in the Middle attack. I have a few sub-questions about this one. 1. Why is this applicable? Aren't HTTPS headers/body encrypted? If HTTP is assumed in this question, why are we even talking about protecting against vulnerabilities? Which leads nicely into: 2. In practice, how does this "sniffing" of requests look like? Why wouldn't the malicious actor be able "sniff" every single request being sent, and eventually find the refresh token one?
"In a microservice environment, the access token is sent to all services, while the refresh token is sent only to the authorization service/server." This sounds like the most valid of all, but I still have a question. What difference does this make? It sounds like the authorization server is assumed to have greater security than other servers? I guess it makes sense only when taking a statistical approach, because to steal an access token, any of the X servers need to be exploited, while to steal a refresh token, only one server needs to be exploited. Although this is just my assumption, and it somehow doesn't fit in with the point of this security concept. Also, it doesn't seem like this concept was created to solve a server issue.
I guess my question is:
"If we assume that there are any inherent vulnerabilities with the concept of the access token, or with using it, or with how it's stored etc... What makes the refresh token less susceptible to these vulnerabilities?"
Whilst the security properties of both the access token and the refresh token "at rest" are the same indeed, the difference is that "in transit" a refresh token is easier to secure than an access token because of the way it is used, as explained below.
Firstly the access token is only ever sent to the Resource Server(s), the refresh token is only ever used towards a single Authorization Server. A Resource Server is considered less trusted in many scenario's (the Authorization Server is - by design - a trusted component for the Client) and as you mention, there may be a lot of them which may have different levels of security that apply to them.
Secondly, the refresh token flow towards the Authorization Server may use a "rolling refresh" of the refresh token which means that at the time of access token refresh, a new refresh token is issued as well, which invalidates the old refresh token. This is a pretty common implementation pattern for Authorization Servers.
Lastly, and perhaps a bit of a long shot, the access token is used in many more requests than the refresh token so the chances of any vulnerability that applies to the transport layer (timing attacks) are proportionally increased.
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.
what are the reasons that the access_token instagram becomes invalid. I've noticed that there is no time expiration of the token?
Does someone know how to avoid it?
thanks a lot for your replies
Your all answers are given here in this document:
https://www.instagram.com/developer/authentication/
Important
Even though our access tokens do not specify an expiration
time, your app should handle the case that either the user revokes
access, or Instagram expires the token after some period of time. If
the token is no longer valid, API responses will contain an
“error_type=OAuthAccessTokenException”. In this case you will need to
re-authenticate the user to obtain a new valid token. In other words:
do not assume your access_token is valid forever.
So Token expire in two case
User revoke access
After some time (No specific time interval)
Does someone know how to avoid it?
No. Ther is no way to avoid it because that is for security reason. Avoiding it is compromising the security of the user and Instagram definitely don't want that.
So the only solution (And proper way) is to handle OAuthAccessTokenException
I previously asked a long question regarding the security of JWT tokens but I want to focus specifically on JWT token revocation here. I am using JWT as my primary authentication mechanism for authenticating mobile clients of a mobile application. My question is: Is it worth implementing token revocation? Currently, I am using a short lifetime for my tokens and I am relying on TLS to prevent tokens from being stolen by unauthorized users. I have not implemented token revocation. But basically this means that if a token is stolen somehow, there is no way to revoke it. What concerns me more is that when a user logs out of the application, the last token they were using still works if I can't revoke it. And it also means that I cannot place a limit on the number of tokens a user can request since I'm not keeping track of any tokens that are issued. I've seen many applications that just store all issued tokens in the database, allowing them to revoke and regulate tokens. But this just seems to defeat the purpose of using JWT. Is it worth adding such complexity or is my current system secure?
Thanks in advance. I appreciate any help.
Whether it's worth it is difficult for anyone here to assess. It depends on what you are protecting and what risks you're trying to mitigate.
You can use reference tokens if you deem it necessary to be able to revoke the tokens. It does force the services consuming these tokens to talk to the authorization server which degrades scalability and introduces a single point of failure.
There are initiatives being developed to prevent token theft. Take a look at the Token Binding Protocol and Proof Key for Code Exchange by OAuth Public Clients.
I think you should consider the possibility that someone can extract a token, regardless of how you've secured it. It exists on a device you have no control over.
Rather than pass along a token, why don't you negotiate a secret key with the client and your server? They can use that key to sign their requests to your server and you can keep track of those secrets -- even revoke them if someone signs out. This allows you to keep expirations on the signatures low, so even if they are captured they are only good for a couple minutes.