JWT + OAuth2 + ADFS 3.0 + Mobile + API - mobile

I’m building a mobile app and API secured with JWT tokens issued from ADFS 3.0. The mobile app is registered as an OAuth2 client with ADFS. I’m concerned someone could intercept the JWT token and use it to access the API maliciously.
My question is will this be enough to secure the API?

the token is indeed sensitive but this is mitigated by a few factors.
The token is passed in the Authentication Header. This is why you need to only pass it via an https call because the header gets encrypted at that point and is secure.
The token is only valid for a while .... and you can set this value to whatever you want. I had them setup for 1 hour for example. Even if someone does get a token, they can only use it for that time after which it becomes invalid.
You will need to secure the method of generating the token as well. Keep the ClientID and ClientSecret safe. Don't pass them in a URL for example as that can get intercepted.
If you do all this you will be as safe as anyone can be on the internet.
One final point from me, some people like to store the tokens in a database. I would recommend against it. Keep them around in your client app, yes, in a secure way so you can reuse them until they expire, but don't use any traditional storage which can be stolen, hacked etc.

Related

Confused on why not store access token in local storage

I have an application that uses react to authenticate. With the Okta library, it by default stores the id token and access token in the local storage. I then grab the access token to make an .net api call that is protected by role authorization.
I'm having difficulty understand the issue with XSS attack. My understanding is that they can inject javascript code to do something with the access token. They are only able to get their own access token by logging in normally. Why is it an issue if they are doing something with their own access token? In addition, can't the access token be found in the network call, so it's not really hidden to begin with?
Can anyone provide me with an example or explain the gaps in my logic? Thanks!
My understanding is that the access token here will be stored in the browser (I'm not super clear on the differences between cookies and local storage but correct me if I'm wrong). When you do that .NET API call the browser knows to pass along the access token. The issue is that websites can include arbitrary JavaScript that runs on your browser, i.e. that arbitrary JavaScript can execute HTTPS requests from your browser using your access token.
In this way, the malicious agent wouldn't be creating their own access token, but instead using yours in arbitrary ways that might give them access to whatever private data you have stored behind your .NET API.
The avoid this, we limit the domains that can access our APIs. Typically, you might see APIs only allow requests from the same domain name. For example: if you API is accessible at mywebsite.com/api then it would only allow API requests from mywebsite.com.
edit:
Forgot to answer the "isn't the access token not hidden because it's included in a public HTTPS request" question. There's a couple of potential solutions here. On websites that use TLS (i.e. you're accessing with HTTPS), you know the public key of the website you're intending to send data to. You can use that public key to encrypt your access token and only the website will be able to decrypt it (with their private key). This way, your access token is kept secret between you and the .NET API.
In an XSS attack there is nothing that prevents the attacker from reading values in local storage. Unless there are countermeasures such as CSP to prevent exfiltration, an XSS attack can be used to steal access tokens.
When cookies have the HttpOnly flag set they are not accessible by script. The browser will attach them on relevant requests as intended.
When requests are encrypted using HTTPS the headers will be encrypted and thus hidden.

Is it safe to store access token in next-auth session?

What I want is to access the customer details in the client side in next.js and I need to pass the customer access token to the backend API. Using next-auth, I was able to store the access token to the session but is it safe or is it better to use the next.js api route and use getToken function? I'm still a beginner in frontend security, I don't know if I'm just being a paranoid but I can't find a topic/post that states it is completely safe.
So by default the session strategy is set to jwt, which means your session is encoded / signed and safe to store sensitive info in.
However, NextAuth.js can be used to automatically put that accessToken you get from your OAuth provider in the JWT token via the jwt callback. Therefore you can pull it out anywhere with the getToken() method you mentioned and authenticate against Google APIs for further use (get drive contents, contacts, etc, etc, etc).
Check out this example for how to do that in the jwt callback: https://github.com/nextauthjs/next-auth-refresh-token-example/blob/57f84dbc50f30233d4ee389c7239212858ecae14/pages/api/auth/%5B...nextauth%5D.js#L67

React & Express JWT Auth: Is it safe enough to store access tokens in Cookies?

I've spent a few days trying to figure out a secure authentication method for SPA/React (client-side).
Most of the tutorials I've read in the wild contradict each other.
One says have to store in Cookies another in Local Storage, one says don't need to use refresh token, one says have to use a refresh token.
I'm building a React SPA app for the frontend and Express for the API (backend). Both are stored in the same domain:
React: example.com
Express: api.example.com or example.com/api
Is it enough to secure my application by using Cookie (access token JWT):
httpOnly:✅
secure: ✅
sameSite: strict
without refresh token
This matches the answer here: https://stackoverflow.com/a/57779076/11340631
The question is:
Is this safe enough?
How long does it take to set the expiration of the access token?
Is this as per Oauth recommendation?: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps
What if my access token is stolen? For example, my friend is using my PC and he stole my cookies and use it in his PC browser.
I really hope to get the answer here, any answer is appreciated.
It's safe against extracting the token with Cross Site-Scripting, but, without other security controls it might be prone to Cross Site Request Forgery (cookies are automatically attached to a request). Is API accepting key in the cookie or must it be sent in the Authorization Bearer header?
My concern is, that if you're not using refresh token, the access token must have a relative long expiration. OAuth2 was not intended to be used to authentication alone, but together with some session-like solution, for example OpenID Connect and SSO.
The shorter the better, unless it can be revoked any time server-side. If there's no way to revoke the key, the 5 minutes expiration date is, in my opinion maximum. That's why refresh token and session-like endpoint is the must.
OAuth is not designed for web application client's authentication at all. That's the common anti-pattern in many projects I've pentested. https://oauth.net/articles/authentication/
I'm glad for your awareness of such a threat. Access tokens must either live very shortly, or they must be revoked server-side in a some way, for example by utilizing some kind of revoke-list. Or the refresh token with server-side-like session endpoint should be utilized.

Bearer Token authentication and JWT

I've been provided with a REST API which has authentication type bearer (Security Scheme Type: API Key, Header parameter name: Authorization) and which i use to authenticate the user and then fetch other data (i will only create the front end using react).
As a first step the user logs in and i sent his/her username-password to the prementioned REST API and get back an access and a refresh token.
Is anything wrong with storing these 2 tokens in a cookie in order to use them in subsequent requests? How does JWT comes into play regarding these 2 tokens? Is JWT of any use to me in this situation?
There's nothing wrong in storing the tokens in cookies, but if you're planning to have a Single Page Application with React it should be enough to store these tokens in memory. Once the user refreshes the page you can either make them sign in again or perform a silent login in the background to get a new set of tokens. In both cases the session kept on the Authorization Server should kick in and you should get new tokens without the need of user interaction.
Your tokens will be much safer if you don't keep them in cookies.
JWTs are not a requirement for access and refresh tokens. If you don't have to use them I would recommend going with opaque tokens. That said, since you do not have control over the API you might be limited to the format required by the API. If you don't want to be limited by this format you can set up your own gateway which you can use to perform token exchange or introspection and forward requests to the API with proper tokens (something which is called a Phantom Token pattern.
From my understanding of the question, you are using an identity provider which provides you with access token and refresh token for the users. That means it is a authentication as a service REST API at works here.
The REST API requires an authorisation header to be passed along with the username-password to exchange for access token and refresh token for the users. (correct me if I'm wrong) In this case, you might want to keep the authorisation header away from the users (consult the authentication as a service documentation).
You call the REST API with payloads (the user-password) along with headers like this:
Authorization: ACCESS_TOKEN
However the ACCESS_TOKEN is the one provided by the vendor for you to use the REST API. On success call of the REST API, it should return you with a set of access token and refresh token. You can then use this access token and refresh token to safe guard your own API, API that you control to provide service to your users.
The access token and refresh token might just be JWT tokens (again consult the vendor documentation).
Also if you are using an authentication as a service REST API, check the documentation if they provide a client sdk. In that case, it should show you the best practise of handling the access token and refresh token it returned.

Can someone explain HttpContext.Authentication.GetTokenAsync("access_token")

I have implemented an ASP.NET Core MVC Client using Hybrid flow, and I am wondering what the HttpContext.Authentication.GetTokenAsync("access_token") does.
If you need more background on my question:
The instructions for accessing an API from with an ASP.Net Core Client App Controller Action are generally as follows:
var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var response = await client.GetAsync("http://localhost:5001/api/stuff");
There is magic in httpContext.Authentication.GetTokenAsync("access_token") :-)
I am wondering what this function might be doing. Is it decrypting the access token from a cookie in the MVC App Domain? ... from the ID4 Domain?
I am sorry but I have been unable to find sufficient documentation on what this does or finding the cookie the access token may be in. I have looked here:
https://learn.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.authentication.authenticationtokenextensions
Does anyone know what it does? A link to more thorough documentation is a totally appreciated answer.
TU!
You can store arbitrary tokens in your authentication cookie in and that method simply returns one with a given name. Actually setting that would have happened during the sign in process. So in short, it comes from the authentication cookie for your client application and would typically be set at the point of sign in using IdSrv4.
It's a way for the client webapp to confirm separately whether the user really did authenticate with IdentityServer (the user comes to your webapp, the webapp forwards the user to IdentityServer for authentication). The id_token comes back with the user to your webapp in a browser cookie, basically when your webapp sees that id token, it does an independent check with IdentityServer, and if it represents a valid user authentication, you'll get an access token back. You can use that access token to get user claims from the userinfo endpoint.
After all of the above, you can take one of the claims and use it as a key for your application's roles/permissions.

Resources