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

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.

Related

Is Safe JWT Store in Req. Session?

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.

MERN-stack with react-router user authentication without redux

I'm currently trying to implement some authentication for my application, however, I have a quick question.
I set up some basic authentication on the backend, which sets a token and sends it to the frontend where it is saved in a cookie.
I read that the token is sent to the server any time I'm making an api-call, but I have trouble understanding how I'm supposed to do that.
I just read this question on stackoverflow and it seems as if the person that answers this question simply suggests two helper-functions which check if there is an item called token.
This seems like a bit of a security risk to me. Couldn't anyone just set an item called token which any random value in the local storage? Thus this person would gain access to protected routes?
If so, how would you make sure that the JWT is actually authenticated?
So, to break it down, my questions are:
Is what the answer above suggests a security risk?
How exactly to you send JWTs with your api-calls and how are they verified?
Is what the answer above suggests a security risk?
Your api should return a 401 error if a random token is used so you can handle this 401 error by clearing the token value in the cookie/local storage.
Edit: To prevent the user to access private routes with a self entered token value you may want to make an api request to check the token in the auth function of your private route (this is optionnal as a fake user will not be able to fetch the api anyway, btw keep in mind that the client have access to the javascript app code so he will always be able to "read" the restricted pages, unless you do SSR, that's why your sensitive data have to be server-side)
How exactly to you send JWTs with your api-calls and how are they verified?
Depends on your server side implementation i.e. jsonwebtoken or passport and passport-jwt works great.
On client side you'll send your jwt in the Authorization header of each request with a prefix like JWT or Bearer (depending on passport config).
Example using fetch :
fetch('/api', {
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ...'
}
});

CSRF Token Storage by sailsjs

I am working on enterprise solution using sailsjs as nodejs framework. Security is integral part of implementation. Apart from SSL, CORS, we are also using sailsjs CSRF implementation. I am still evaluating how secure is it to use this token. Can anybody guide on following:
Where sailsjs stores CSRF token? Is it encrypted? How secure is it to use?
You'll need to do some work to validate that your tokens are not accessible to untrusted servers; they should respond only to GET requests, and they should not but accessible via AJAX, nor should CORS headers be enabled.
PillarJS has an excellent readme on CSRF. It says about CSRF tokens:
CSRF Tokens
Alas, the final solution is using CSRF tokens. How do CSRF tokens
work?
Server sends the client a token. Client submits a form with the token.
The server rejects the request if the token is invalid. An attacker
would have to somehow get the CSRF token from your site, and they
would have to use JavaScript to do so. Thus, if your site does not
support CORS, then there's no way for the attacker to get the CSRF
token, eliminating the threat.
Make sure CSRF tokens can not be accessed with AJAX! Don't create a
/csrf route just to grab a token, and especially don't support CORS on
that route!
The token just needs to be "unguessable", making it difficult for a
attacker to successful within a couple of tries. It does not have to
be cryptographically secure. An attack is one or two clicks by an
unbeknownst user, not a brute force attack by a server.
Also consider this from Sails.js docs which gives a real-world example of how they operate:
CSRF tokens are temporary and session-specific; e.g. Imagine Mary and
Muhammad are both shoppers accessing our e-commerce site running on
Sails, and CSRF protection is enabled. Let's say that on Monday, Mary
and Muhammad both make purchases. In order to do so, our site needed
to dispense at least two different CSRF tokens- one for Mary and one
for Muhammad. From then on, if our web backend received a request with
a missing or incorrect token, that request will be rejected. So now we
can rest assured that when Mary navigates away to play online poker,
the 3rd party website cannot trick the browser into sending malicious
requests to our site using her cookies.
And finally, Sails.js uses the Connect CSRF protection middleware. Tokens are stored on a per-session basis, and therefore are not stored in a database nor is (double) encryption needed. Here's another excellent SO answer on the subject: Why does Express/Connect generate new CSRF token on each request?

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

How to persist bearer token on client side

I'm trying to get my head around claims based authentication in ASP.NET Web API 2. In my application I use the VS 2013 template, which implements OAuth 2.0 and uses bearer token (JWT as I remember). My question is - what is the best way to persist token on the client side. In his book Badrinarayanan Lakshmiraghavan describes bearer token as
A bearer token is like cash: finders, keepers.
Therefore, is it safe to save it to a cookie? Doesn't it mean that whoever will steal the cookie will get full access to the application? On the other hand I could encrypt the token using hash just before saving it to the cookie. Would it be safe enough? Are there any other alternatives? I've seen few questions asking similar question on stackoverflow, but have never found satisfying answer.
is it safe to save it to a cookie?
No. Cookies can be stolen via XSS attacks (and other vectors)
Also, this might be susceptible to CSRF since a cookie will be submitted automatically with any request.
I could encrypt the token using hash just before saving it to the cookie
This will also not work. Hashing is not a secure way to encrypt (and moreover does not allow decryption)
Are there any other alternatives?
Basically, you should give the token to the user over a secured connection (HTTPS) but they should manually submit it for security (again over HTTPS)

Resources