I'm currently assessing the security of an application using Oauth2 authentication.
During the Oauth dance, when authenticating with user John Doe in browser A, one of the requests is:
GET https://siteImAssessing.cxx/?code=LongOAUTH2AuthorizationCode
What I've noticed is that I can copy and paste that request in a different browser (browser B) and I become John Doe in that browser as well without the need to enter John Doe's credentials. (I receive fresh JWT tokens in browser B as well)
Would this be considered normal Oauth2 behavior?
The value of code expires after 5 minutes and when the user refreshes the browser window in either browser A or B.
Thank you,
No, you should not be able to be John Doe in both browsers. The authorization code can only be used once (see https://www.rfc-editor.org/rfc/rfc6749#page-27). The code should be invalidated after it is used to get a token.
If you can copy the request and successfully execute it from another browser (session), it means the authorization server is not invalidating the code after it was used. You may want to file a bug with the vendor of the authorization server.
Related
I have a project that uses node-oidc-provider and angular-oauth2-oidc.
However one thing is wierd, refresh token request uses prompt=consent (I know it is by spec) which returns 303 with location including code in the hash, the token is refreshed but it looks like terrible UX if SPA appplication refreshes in middle of user interaction, is this expected behaviour or is something in my configuration wrong?
Is there any way to get refresh token through backchannel like AJAX request (I would like to avoid iframes if possible)? I can't find any specs on how it should work.
OPTION 1
The traditional SPA solution is to use an Authorization Code Flow (PKCE) redirect on a hidden iframe using prompt=none. This prevents refreshing the SPA since it runs in a mini app as in this code. This is no longer reliable though, due to recent browser restrictions that drop the SSO cookie - eg in Safari.
OPTION 2
Another option is to use a refresh token grant message in an Ajax request. But this relies on storing a refresh token in browser local storage to get past page reload issues. And this is not considered secure and is not likely to fare well in PEN tests etc.
OPTION 3
The preferred option these days is a variation on option 2 where the refresh token is stored in a secure HTTP only encrypted cookie. It is possible to issue cookies via an API, if you want to avoid impacting the web architecture, though it is a little tricky. See this Curity blog post for more on this approach - and this code sample.
I'm using Identity Server 4 version 3.1.2. I logged in with a user information in Chrome and with another user information in Firefox in the same computer. If I copy the first user token saved in Chrome Cookies and paste it to the Firefox Cookies (replace with second user token) and refresh Firefox (pressing F5), Firefox logged in user will be changed to Chrome user and it is a security issue. What can I do to prevent this problem?
There is nothing you can do to mitigate this issue for sure. You may check if the user agent header is what you expect it to be, but then someone will fake the user agent header with a plugin and you are back to square one. All the other headers can be bypassed in a similar fashion.
(Although if you decide to trust the user agent header then this is the solution for you).
Checking for IPs, sockets, TLS sessions has proven to generate to much problems to be considered a solution at all.
I'm developing a new web app with NodeJS and ReactJS and I'm using JWT for authentication. The client side sends a request to /login using axios.post(), the server checks the data entered by the user and returns an access token with an expiration time of 5 minutes and a refresh token. I use Redux to save tokens at the app level state. On next requests, the client side sends back the token to the server.
My questions are:
1) Is there a way to open multiple tabs and recover the state of the first tab opened and when the user logs out of a tab, he is logged out of all tabs? (Facebook uses this method)
2) Imagine I connect to the website at a friend's place and when I leave I forget to disconnect, is there a way to disconnect from all the devices when I get home? (Facebook uses that too)
3) Is it possible to automatically delete the tokens in the app level state after X seconds / minutes only when tabs are closed and continuously refresh the access token otherwise?
Thank you in advance
No answer to your post after 9 days. Too bad, let me help you out.
To get the closest representation of what you want i would use a SameSite Cookie.
They're always on all Tabs and you can also expire them after a period of time.
Cookie will get deleted and you'll be logged out.
In order to work with devices you can use a blacklist on your refresh tokens, although this is against the principles of JWT it is still a possibility.
SameSite Cookies spread over all tabs
The Cookie can be send with all requests in the header (use strict mode)
Deleting the Cookie results in a logout
Blacklisting the Refreshtoken JWT will result in a logout of the user aswell.
Would recommend you to read about the SameSite cookie (strict). You'll be surprised because there's not alot of people who know about it.
If i can be of any help feel free to contact me through DM.
I have an MVC app, like explained here: https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-aspnet-mvc
From Javascript I make AJAX calls to some Action that uses Google API to get message from Gmail.
At first everything works fine, but after some time I keep receiving
Error:"invalid_grant", Description:"Token has been revoked.", Uri:""
Can someone explain to me what that means and why I am getting this error ???
Cheers
Error:"invalid_grant", Description:"Token has been revoked.", Uri:""
Means just that the user has revoked your access to their data you will need to request authentication again.
One thing you need to remember is that while testing. If you request access from yourself you grant it get a refresh token, do it again you get another refresh token. They both will work. You can do this up to 26 times and have 26 technically live and active refresh tokens for an application. Once you do it the 27th time the first one will stop working normally you just get an invalid grant error.
Token has been revoked normally means that the user has revoked access in Google but it might be different with Gmail.
Update 2021:
Invalid grant means that the token you have no longer works. As of 2021 google has made a change which will cause all refresh tokens to expire after seven days if the project that created it is still in the testing phase. The solution is to move your project to production and then your refresh tokens will last longer then seven days.
I'm a little confused about Basic authentication in regards to web browsers. I had thought that the web browser would only send an Authorization header after having received an HTTP 401 status in the previous response. However, it appears that Chrome sends the Authorization header with every request thereafter. It has the data that I entered once upon a time in response to a 401 from my website and sends it with every message (according to the developer tools that ship with Chrome and my webserver). Is that expected behavior? Is there some header I should use with my 401 to infer that the Authorization stuff should not be cached? I'm using WWW-Authenticate header currently.
This is the expected behavior of the browser as defined in RFC 2617 (Section 2):
A client SHOULD assume that all paths at or deeper than the depth of
the last symbolic element in the path field of the Request-URI also
are within the protection space specified by the Basic realm value of
the current challenge. A client MAY preemptively send the
corresponding Authorization header with requests for resources in
that space without receipt of another challenge from the server.
Similarly, when a client sends a request to a proxy, it may reuse a
userid and password in the Proxy-Authorization header field without
receiving another challenge from the proxy server. See section 4 for
security considerations associated with Basic authentication.
to my knowledge, Basic HTTP authentication has no ability to perform a logout / re-authentication. This along with the lack of security of HTTP Basic authentication is why most websites now use forms and cookies for auth solutions.
From RFC 2617:
If a prior request has been authorized, the
same credentials MAY be reused for all other requests within that
protection space for a period of time determined by the
authentication scheme, parameters, and/or user preference.
From my experience it is quite common to see browsers automatically sending the Basic credentials for subsequent requests. It prevents having to do an extra round trip for additional resources.