Is Safe JWT Store in Req. Session? - node.js

i have a question about MERN Stack (Mysql,Express,React,Node). I confused about storing Jwt token (in Cookies,Localstorage or as session in request).
What iam asking is Is Safe Storing JWT On Request Session ?
Can someone explain how to store token in Single Page App ?
Thanks Anyway ...

When we do a successful login we get an access token. In this case, it is a JWT token. When we get this we need to keep it somewhere to use it for the future use of the user. We normally store that in LocalStorage. You can find more info about LocalStorage here. We also can use SessioStorage, Cookies as well. But Cookies only can contain 4KB of data and SessionStorage will go away when the browser is closed. That is the reason for me to go with LocalStorage. But you can choose it depending on your application requirement.
When sending a request with a token, I use the Authorization header.

It's safe to store JWT cookie at the client and even more in this day and age it necessary for scalability.
What should you use?
Session - This is the "old" way of doing things and no in use anymore. The session saves a state on the API server and that is a bad thing for scaling.
Localstorage - A good choice for mobile and web applications. The idea here is that you as the client developer are responsible for keeping track of JWT (save it on login, remove it on logout)
JWT-Cookie - is the best for ONLY web application. It's the same idea of Localstorage but now the server is responsible for setting and removing the JWT from the client using the Set-Cookie header.
Note: You can implement both Localstorage and JWT-Cookie side by side.

Related

Storing JsonWebToken in frontend

So, I'm right now learning Node.js and I have few newbies doubts. I tried to search here and also in Google and I couldn't find my answer. I'm doing a Jwt Authentication and sending the token through header to my frontend which I'm rendering using handlebars as a view engine, my question is, how can I store that token and sending back through headers in every request? and What's the best way to do it?
Depending on chosen token expiration policy, you can choose different options. As previously said, token may be of course stored in localStorage.
The more secure option is keeping the token in memory. I would strongly suggest using short-lived JWTs and require them to be re-issued regularly (e.g. via an OAuth2 refresh token flow).

Why can't I store an oauth refresh token in the browser?

I want to store an oauth refresh token in the browser. The reason I want to store it there is so that the app can refresh the access token and let the user continue their session uninterrupted. I also want to eliminate the need for any kind of cache on the server to store the tokens, thus making it stateful.
I'm told that storing the refresh token in the browser is wrong because it's insecure.
I think it's OK because:
The tokens would be stored in httpOnly, secure session cookies so they shouldn't be vulnerable to XSS or man in the middle attacks and they will be discarded when the user closes their session.
All communication to the server is done via HTTPS
The refresh token can be invalidated if suspicious activity is detected
Most importantly you can't use the refresh token unless you know the client secret which would be known only by the server.
Am I wrong to think it should be OK? Please explain why!
Storing the tokens in an httpOnly, secure cookie is probably the best you can achieve security-wise. The problem sometimes is that an httpOnly cookie is not good enough due to other (non-security) reasons as Javascript obviously does not have access (that's the point). So people sometimes want to store tokens in other browser stores like localStorage, or slightly better, in JavaScript objects, both of which are significantly less secure than an httpOnly cookie (but still may be good enough for some applications).
Storing the token in an httpOnly and secure cookie makes it pretty much equivalent to a session id, and its security will also be the same in this respect (obviously other aspects may be different).
Actually you can store your token in the browser, you just need to know which store mechanisms fits better with your solution. For example in the local storage is the least safe of all, if you have the backend and your Single Page App at the same domain I would recommend you using the cookies.
Auth0 website has some recommendations about it:
We recommend using the Auth0 Single Page App SDK. The Auth0 SPA SDK
handles token storage, session management, and other details for you.
For further details click here.

Authorization (and security, in general) for web and mobile apps of the same service

Help me to understand how to implement proper security for web and mobile apps, which would be enough for my case.
What I have:
Backend. Some sort of Stateless REST API, which consumes and produces JSON text. Does not store any kind of state.
Web application. Main portal to the service functionality.
Mobile applicaiton. Provides a reduced a set of functions to users of the service
I am not going to store any state on the backend. Instead, I am going to delegate this to both mobile and web browser applications.
Now here comes the question of security. How do I properly secure that?
Since session mechanism does not really work for me, I decided to go with JWT.
In my JWT I am going to store user Id and some other information like, for instance, user's privilegies.
For mobile app, I am going to send this token as a part of a response and the app will store it inside its secure store.
Each request it will send this token as Authorization Header.
For web app, I am going to send this token via HttpOnly cookie. This token, thus, will be included in every request from the client.
The problem now is a possible CSRF-attack. To address that I thought of the following. Each user "session" will be associated with CSRF token.
Since I can't store this token on the server (remember, stateless API), I can send it as encrypted (again, with JWT) token to the client via HttpOnly cookie and non-crypted in a regular cookie.
Now, every request the web client will use non-crypted token from the cookie and send it back to the server. The server will check if this token matches from the Encrypted one which is stored in HttpOnly cookie.
Also, I am going to use different URL endpoints for web and mobile web apps. What for? In order to keep auth mechanisms described above separate - I believe this will help me to keep the service secure.
Do you think it is an OK solution? What problems do you see here?
Thanks in advance.
In general, what you described looks good and pretty standard. However, if I understand correctly, the CSRF protection is flawed.
To make sure I understand correctly: a csrf token would be stored in an encrypted httpOnly cookie, only to be sent back to the server as reference. Another cookie would have the same value but unencrypted, in a plain (non-httpOnly) cookie, and the server would compare these two. What's the point? An attacker would still be able to create a webpage to have a user make an request to your website, and both cookies would still be sent.
The reference cookie is ok to be in the httpOnly cookie for reference, but the other one should not be a cookie. It could for example be a request header value that you add to all requests. The client could receive it in a response, but not as a cookie. With jQuery in the web app, you can use the beforeSend hook to add it to all subsequent requests as a header. This way an attacker could not make valid requests from another domain.

how to deal with access token and refresh token in client side

I am creating a website using AngularJS client side and communicating in REST with a backend (in an other domain).
To authenticate every calls, I pass a token through the header of each HTTPS call : "Authorization : Bearer access_tokenXXXXXX"
When the token expires, I am able to create a new one thanks to a refresh_token.
The access_token and the refresh_token need to be stored client side, because the browser needs to have it in clear text before setting it in the HTTP request header.
My questions are :
Question 1 : What is the recommanded way to store the access_token and the refresh_token to make it available to the browser so it is relatively secure? (I have quiet sensitive data like personal pictures)
Question 2 : What are the recommanded lifetime (= time before it is not usable) for access_token AND refresh_token? (FYI I refresh the token after a 401 response, and my app is a social app)
Question 3 : Do I have an architactural issue? Should I change it in order not to have JavaScript using token at all, and use HTTP-ONLY cookies?
Thanks :)
Geoffrey
UPDATE :
I finally chosed to go for HTTP-ONLY cookies. I am using Django Oauth Toolkit so Django is waiting the authorization in the HTTP header, and not in a cookie.
To solve that, I am using a Middleware that gather the token of the cookie and set it in the header. It should also allow me to re-authenticate the user (with the refresh token) before the access_token expires.
I think you're right in asking question 3. Definitely use HTTP-Only cookies, that's the safest type of browser storage.
As described in the links provided by smwikipedia, using HTTP-Only cookies helps defend against XSS. To also defend against CSRF you should check out this AngularJS mechanism.
The actual format of the cookies can be JWT or anything else.
The answer to question 2 really depends on your users' sweet spot in trading off between tight security and convenience. You know your users best so it's really your own judgement call.
I am facing similar questions to yours.
I am developing a service layer for both browser-based and non-browser clients. I plan to use JWT (JSON Web Token) to authenticate both.
It's too long for a comment so I post it as an answer.
For question 1, according to here, they recommend to store JWT token in cookie due to security considerations.
For question 2, here is a thread about expiration handling for JWT.
For question 3, I have no comment yet.

Node Js refresh auth token

How can you provide example for refresh node js auth token? I mean by what the parameters can I refresh auth token? For example if I can refresh it by login and password then where should I store this params for single-page app? As I understand store it in cookie is not good idea for security, localstorage is not good also because some of browsers not supported it. So maybe someone know another way for refresh token?
Cookies are a very secure storage mechanism, if used correctly. Local storage should never be used for authentication information. OWASP has a great write-up on storage security:
https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Storage_APIs
To quote the important parts:
Do not store session identifiers in local storage as the data is always accessible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.
[With local storage] There is no way to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies, every object is shared within an origin and protected with the Same Origin Policy. Avoid host multiple applications on the same origin, all of them would share the same localStorage object, use different subdomains instead.
Back to your original question: where to store the refresh token? Answer: In a HttpOnly cookie. This prevents the cookie from being stolen by XSS attacks, and it makes it very easy for your server to issue new access tokens (using the refresh token) because the server will have access to both at the same time, on the same request.
You can add another layer and encrypt the entire refresh token that is stored in the cookie.
Caution: when using cookies, you also need to protect yourself against CSRF attacks
I’ve written at length about front-end security and JWTs in these two blog posts:
Token Based Authentication for Single Page Apps (SPAs)
https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/
Disclaimer : I work at Stormpath, our service gives you a secure, hosted user database with many features. Our express-stormpath module makes it very easy to get started with login and registration flows for your application. We are in the process of writing a new release, and it will be using access tokens in the way that I describe in this answer.
I created AuthToken model that contain these fields:
user_id, access_token, refresh_token, access_token_expiration
After successful user login, server side will send refresh_token and access_token to client side and store it to localstorage(cookies for old browsers).
And all subsequent requests will be sent with access_token(I use header x-access-token for $httpProvider in angular).
When token expires, client needs to send refresh_token for updating access_token, refresh_token and expiration date. Since I use sockets I can refresh access_token if it is expired in any request(for this I send z-refresh-token header also for each request) so I shouldn't send any extra request and I can keep current user request, just will return tokens via socket event after it was updated.
Hope this helps

Resources