Safe Keeping Oauth Tokens in a Cookie? - node.js

I have been keeping my 3 legged auth tokens and the refresh token in cookies so then I can transfer them after reload. I am on localhost so I didn't have to think about security but soon enough I will be putting my web application on the internet. I know that you should only have a token with viewables:read as the only scope to prevent any snooping of the user's data. Can it be safe if I encrypt the token with my own encryption method or should I keep the token in a mySQL session on the server side? If I should make mySQL session, can someone give me a link to a tutorial on the mySQL session parser npm extension? I haven't got it to work in the past. Thanks.

If you have a 3-legged token that will give access only to that user data. If that token is viewables:read the user will be able to view his/her models, nothing else. You can use proxy on Viewer to avoid sending it to the client, see a NodeJS sample.
The refresh token is useless to that user, to actually refresh it the ID & secret are required (and the secret should be hidden, the ID can be exposed for BIM 360 provisioning, for instance).
Assuming the browser is not compromised and your cookie is configured to use only https, then the cookie is only exposed to the website that created it and protected during transfer.
I use cookie-session on my sample apps, like this.

Related

Stateless authorization of API endpoints with express and JWT

I'm creating a REST API to store some information about some items.
It is nothing highly sensitive or anything but I still want to properly secure it. Also in regards of maybe having to secure something else in the future.
To sign the users in I'm using OIDC with Google and Azure to retrieve user information from the user information endpoint. After that I want to store the user in a database along with their permissions. For them to access the API I want to generate and sign a JWT Access Token and Refresh Token. So far so good.
I want the acces to the API to be stateless (with the Access Token) for scalability. I'm not so much worried about the sign in process being stateless. The refreshing of Access Tokens via the Refresh Token also doesn't have to be stateless, but it would be nice to have.
I was reading through some other questions and articles online regarding XSS and CSRF. To me it all boiled down to two things:
Don't use local or session storage to prevent XSS-Attacks grabbing tokens stored there. Solution seemed to be to use cookies (http only cookies, samesite).
Don't use cookies as to prevent CSRF.
I'm now kind of stuck because the two options seem to recommend not using either.
I thought about how this might be solvable and was reading through OWASP recommendations mentioning generating a fingerprint during sign in and storing it in the JWT as user context.
In my mind I have the following process.
Sign the user in using OIDC and receive information about the user from the user endpoint.
Look up the user in the database and get their permissions.
Create a unique fingerprint for the user.
Store the fingerprint in a hardened cookie (http only, secure, samesite).
Create a JWT Access Token using the users id, permissions and an encrypted string of the fingerprint.
Create a JWT Refresh Token using the users id, permissions and an encrypted string of the fingerprint.
Sign both JWTs.
Return the Tokens to the client with the hardened cookie set.
Now if the user wants to access a protected resource he sets the Authorization Header with the Access Token and sends the request, which will then also include the hardened cookie. The server can decrypt the fingerprint from the Access Token and compare it to the fingerprint from the cookie.
If the user wants to use the Refresh Token to get an expired Access Token the fingerprint would also be validated before issuing a new Access Token.
Access Tokens would be short lived e.g. 15 minutes. Refresh Tokens would be long lived e.g. 1 day.
In my mind this solves both problems:
Leaking of the tokens would be useless without also having the fingerprint from the cookie or the cookie itself.
Leaking the cookie via something like CSRF would be useless as the Tokens would not be available.
Only if an attacker would simultaneously get hold of both he would be able to have access.
My questions are:
Am I overlooking something?
What would be a good way to generate this fingerprint? Use the "sub" from the user endpoint?
Thanks for your help already!

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.

How to protect the refresh token from hacker

I googled a lot on how to protect the refresh_token from a hacker because it will be stored somewhere in browser's local-storage/cookie, so a hacker can easily steal those tokens and I couldn't able to find a proper answer so I came here.
I understand that access_token will expire in less-time and we should use refresh_token to get a new access_token. But if the hackers steal the refresh_token means, he can stay as a login user for a long time, right?
Some people are saying, you can protect it using client_id and client_secret, but the hacker is going to access the endpoint of the API, which has the client_id and client_secret. So again, a hacker can get a new access_token easily.
So I am finding no way to protect the hacker from getting the new access_token.
Can someone able to guide me here, on how I protect the hacker from getting access to refresh token from browser's local-storage/cookie?
From the context of your explanation, you are talking about a browser based application. If this application is one that does not have a backend, then you do not have a secure place to store your long-lived tokens or client secrets.
From OAuth 2.0 perspective, these are called public clients. Thus protocol do not allow them to have a client secret. So they have a client ID and a redirect URL for client authentication (client identification). Implicit flow is one key flow suitable for SPA that runs on browser. By specification, they will not get a refresh token. Reason is their inability to protect such secrets.
But if you have a backend and have the ability to correlate browser session and backend storage, you can use a flow that gives your a refresh token and store it securely. But this require your application architecture to support such (ex:- Browser session and backend storage).
Also, rather than making end user to login every time, you may use the identity server's logged in state to skip log in. This too will rely on identity server's browser cookie and it's life time. For example identity server may have a browser session valid for 24hours. So your client will not see log in page when accessed thew application within the time.
You can try to secure the local storage using this library Secure-ls

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

Is there a secure way to connect to an IMAP server on behalf of a user?

I'm working on a web application which involves connecting to Gmail on behalf of a user to check for new messages. Is there a way to securely store the user's credentials so that they can still be recovered for the login, or is there some way to obtain a token for Gmail to use in connections?
EDIT: The application is meant to be used mostly with mobile users, so they won't be logging into the site frequently. Thus, storing information in a cookie isn't viable.
If you logged into GMail's web interface it gives you a token in the form of a cookie. If yYou could use that token and the web interface then you could access their email without storing their credentials. Of course that isn't IMAP access, and it expires (as a good token should).
Alternatively you could encrypt their credentials with a value you store as a cookie on their computer. Then when they access your site you can check their mail without ever storing the encrypted credentials with the key to decrypt it.
Neither is an ideal solution, but hopefully they get you moving in the right direction.

Resources