Where can I store my JWT token in client side? - authentication

We have some options such as localStorage, cookies, in-browser memory to store our JWT, I am also aware that localStorage is vulnerable to XSS, and httpOnly cookies are vulnerable to CSRF and it will be lost on reload/refresh when JWT is placed in the browser.
I studied about the latter issue and come to the solution that putting Refresh Token in httpOnly cookie and access token in browser memory can save me to some degree.
But according to my use case, I have an Admin dashboard from which only authenticated person(basically admin) can make authorised API call. Also, in my WebApp we don't have user input field(text field), So I guess XSS and CSRF hard to attack. So, Can I put JWT Token in httpOnly cookie with expiry of long duration?
Is this a good solution for my use case?

Related

Is it safe to store jwt access token in httpOnly cookie?

I watched a guide where an author stored access token in localStorage and then he put the access token as Authorization header with value "Bearer accessToken" in every request through axios interceptor. But I am wondering why not to store access token in httpOnly cookie as we do it with refresh token. What would be the problem if any?
It's safer to store access tokens in HTTP-only, secure, same-site cookies (it doesn't matter if it's a JWT access token). It's safer because the value of the access token can't be stolen through a cross-site scripting (XSS) attack. However, when you keep the access token in a cookie, you won't be able to send it to an API in an Authorization header. The browser doesn't have a way of setting the authorization header, it only attaches the cookies. That means that you might need a piece of software that will sit between your front end and API, and extract the access token from the cookie (this can be done e.g., by an API gateway).
Remember also that storing access tokens in cookies leaves you open to cross-site request forgery attacks (CSRF), but there are well-established techniques to protect yourself from CSRF. It is also simpler to protect against CSRF than against XSS.

Why not store JWT access token in memory and refresh token in cookie?

A lot of questions have already been asked on the topic of storing JWT tokens securely when dealing with a browser-based application. The consensus seems to be that http-only, secure cookies should be used. However, many variations seem to exist on storing JWT tokens when both short-lived access tokens and longer-lived refresh tokens are involved.
I have identified the following variations:
1. Store both JWT access token and refresh token in http-only, secure cookies
Pros:
Access token and refresh token cannot be accessed from Javascript
Cons:
Introduces CSRF vulnerabilities so CSRF token must be added as well
The top answer here advises to add CSRF tokens: https://stackoverflow.com/a/37396572/6735966
2. Store a JWT access token in memory and refresh token in http-only, secure cookie
Pros:
Refresh token cannot be accessed from Javascript
Access token sent through Javascript so access token is not vulnerable to CSRF
Refresh cookie can only be used to obtain new access token. With the correct CORS setup, reading the access token from the response is not possible through a cross-site request by a malicious party. Therefore, this approach seems safe from CSRF.
Cons:
Access token can be accessed through Javascript (but access token expires quickly)
Recommended here but received a lot less votes than the top post: https://stackoverflow.com/a/63593954/6735966
3. Store a refresh token in memory and JWT access token in http-only, secure cookie
Pros:
Access token cannot be accessed from Javascript
Refresh token sent through Javascript so refresh token is not vulnerable to CSRF
Cons:
Longer-lived refresh token can be accessed from Javascript
Access token is vulnerable to CSRF
A similar approach is described in the top answer here: https://stackoverflow.com/a/54378384/6735966
Considering the pros and cons storing a JWT access token in memory and refresh token in http-only, secure cookie definitely seems like a good idea to me. However, even though there are many questions on this topic, none of the top voted answers even consider this approach. Therefore my question is: Why not store JWT access token in memory and refresh token in cookie and instead use one of the other approaches?
Storing the cookie in memory would work, but one issue is if you have multiple instances of the same client.
An alternative is to do it like they do in ASP.NET core, where by default the cookies are stored encrypted in the session cookie. However, this cookie can't be used to access any API's, as it is inaccessible from JavaScript. Also, to avoid the CSRF issues, you typically add the common antiforgery token/cookie to prevent CSRF attacks.
So, the most way is to store the tokens in ASP.NET Core is in the session cookie. But at the sametime, this make the cookie to grow quite a bit, so when you feel the cookie size grows to big, then you start looking at storing them in memory or in database/Redis storage.
In .NET for example, the support for this is already built in by using a SessionStore. The picture below tries to show how this works where the SessionKey is stored in the cookie and then tokens are stored in memory/backend.
Yes, this is how it works in ASP.NET Core and I am sure you can find the similar approaches in other platforms as well.
An alternative is to look at using the BFF pattern that seems to get more and more popular.

How to secure private routes in SPA while using httpOnly cookies

I'd like to secure my SPA private routes with JWT authentication. To make everything as much secure as it's possible, I wanted to use httpOnly cookie to store my access_token on the client-side.
Using httpOnly cookies protect me a lot from XSS attacks, but unfortunately this approach does not allow me to check if the cookie actually exists in the browser.
In this case - how can I implement some logic to prevent unlogged users to visit private, secure routes of my SPA?
Am I forced to use non-httpOnly cookies or localStorage for this?
Am I forced to use non-httpOnly cookies or localStorage for this?
No. Keep your access_token in a cookie with the httpOnly flag, and (if possible) with the secure flag.
Let's call this cookie session_cookie.
When a user does a successful login you could return 2 cookies: the session_cookie and another one which informs to JS the user has been authenticated (let's call as SPA cookie).
Your session_cookie is not accessible by JS so it's not vulnerable to XSS. This cookie is sent on each request to the server, which checks is a valid token, otherwise an unauthorized error is returned.
Your SPA cookie hasn't httpOnly flag so it's accessible by JS but the server doesn't use it to authenticate the user, so fake this cookie is useless.
Whenever you receive an unauthorized error on your SPA you can remove the SPA cookie.

How is "token auth" any different than "cookie auth"?

On the surface, it seems like "token auth" is basically the same thing as traditional "cookie auth".
Token auth:
User submits username/password to API
API responds with access token
Client stores access token for identifying user in future requests
Cookie auth:
User submits username/password to API
API responds with cookie
Client stores cookie for identifying user in future requests
It seems that token auth is basically the same as cookie auth, except that most HTTP clients already know how to deal with managing cookies automatically, whereas you have to manually manage API tokens.
What am I missing? What are the benefits of using token auth? Is it really worth the extra effort?
Whether the extra effort is worth it, depends on what you are protecting and who is consuming the API.
Token based authentication is much easier when your clients are non-browser based. So if you're targetting mobile applications, token based authentication is worth considering.
But also in a browser scenario it has some advantages. As the browser does not automatically send the Authorization header, security token are not vulnerable to CSRF attacks.
If your web application lives on another domain than you API, cookies will not be sent because of the same-origin policy. Security tokens are not affected by this.

How are cookies different from JWT and why are they considered worse than JWT?

I have been reading around using tokens for authentication. I, however, fail to understand how tokens (JWT) are different from cookies. Both will store the user info (as claims in tokens), have persistence defined and will be sent with each client request to the server.
Few questions that come to mind, in addition to the above -
Are JWT tokens not prone to Man in the Middle attack? If someone steals a token (on an unencrypted channel), can't they pose as the original user? (unless we add the user's IP etc in the claims)
I've read a few rants that cookies are not good for new-age mobile apps and tokens are the answer. Why?
Why are tokens considered more secure than cookies? What makes them more invulnerable to attacks?
Does a token needs to be issued by the server only, or one can receive a token from another OAuth provider and customize (add/remove claims) and reuse it?
Performance wise, cookies are 'bad' as they have a size limitation, that is why they just store the session ID (typically) with session data in server. This reduces cookie size. But JWT, the whole token needs to be sent, so if the token contains the session data as claims, then we'll be essentially sending this ever increasing token every time. If am getting that correct, isn't that bad performance of JWT as compared to Cookies?
Thanks
Are JWT tokens not prone to Man in the Middle attack?
Yes, you should use HTTPS to ensure that no one can see the JWT in the HTTP request headers. If someone gets the token, they can pose as the original user. The same thing is possible with cookies.
I've read a few rants that cookies are not good for new-age mobile apps and tokens are the answer. Why?
Most mobile apps don't use browsers to make HTTP requests. Browsers make dealing w/cookies seamless for web developers. For mobile developers, using JWT's can be less cumbersome than dealing w/cookies.
Why are tokens considered more secure than cookies? What makes them more invulnerable to attacks?
Tokens aren't necessarily more secure than cookies (a cookie could be signed, just like a JWT). The security benefits come from not being exposed to exploits which trick the browser into inadvertently using the cookies (CSRF attacks).
Does a token needs to be issued by the server only, or one can receive a token from another OAuth provider and customize (add/remove claims) and reuse it?
A JWT is signed with a secret that only the server/organization that generated it should know. So only servers that know the secret can verify the token is valid. While the server that generates the token doesn't have to be the same one that validates it, it doesn't make sense for you to customize and re-use someone else's token.
Reference