Software Architect & consultant (available for consulting), worldwide speaker, published author, workshops teacher and developer in Web/Cloud/Mobile/AR/VR/IoT/AI/Blockchain fields
You store them in memory, but not on the global scope. So they can be accessed only from your code or if an attacker reverse engineer your code. So you should never expose memory token getter function to the outside world. That's how you can prevent attacker from getting the token.
In memory, I have a getter function to get the token and every 15 minutes I do refresh_token call (silent refresh). All of this is written in the blog post in Silent refresh section
If you need to validate if your tokens were revoked or not that can be done by blacklisting them which is also described in the blog post in blacklisting tokens section. Session-based authentication is problematic in a microservices architecture. I referred to that also in blog post
If you only store your JWTs in memory, how do you deal with a user refreshing the browser? In my application I would like a user to be able to refresh the browser and automatically be logged back in.
Software Architect & consultant (available for consulting), worldwide speaker, published author, workshops teacher and developer in Web/Cloud/Mobile/AR/VR/IoT/AI/Blockchain fields
I covered that later in blog post. Short answer - refresh tokens and silent refresh. Please check the full blog post here: blog.hasura.io/best-practices-of-u...
Hello Vladimir, thanks for your fast reply and further info.
I am looking for a way to use JWTs in a safe way, and this blog provided a good base to get more information on how to achieve this.
I read your links, but am still not convinced that JWTs (without binding) can be protected from XSS theft and misuse.
I understand you should not store tokens in global scope, but somewhere in your JS-application you have a function to get the accesstoken. This function can store the token in some private property of an object, but:
via XSS I can create a cloned version of this version that does the same thing (see 2), but opens access to the acquired token to the hacker
and eventually the token should leave the private property to provide the token to (a http-client to) inject it in E.G. an authorization header. With XSS you can also inject a service that gets the accesstoken via the token-object.
I am aware that this can only be done with knowledge about the working of the code, that's why I called it a targeted attack, but when the accesstoken provides access to valuable resources, this will be done.
the (silent) refresh function you describe still looks vulnerable to XSS to me. You protect the refresh-token from getting stolen, but a malicious-script can call the /refresh_token API via the users browser, the cookie gets automatically applied, and now the script has an accesstoken it can publish to the hacker.
Of course CORS can be used to minimize the possibilities to inject XSS-scripts and to publish data to the outside world, but with analytic services, advertisement networks, and social-media integrations this still is very hard to prevent completely.
The best option I have seen is Token Binding but this isn't supported in browsers. You can try to implement something similar yourself with the JS-crypto functions, but then access to your API will be much harder to implement.
The safest way to provide access to your services is then by using session-cookies (although API calls can still be compromised in the same way with targeted XSS attacks; calling API's via the users browser that will automatically applies cookies, you can at least not access the API's from other systems after a token is stolen).
Software Architect & consultant (available for consulting), worldwide speaker, published author, workshops teacher and developer in Web/Cloud/Mobile/AR/VR/IoT/AI/Blockchain fields
I am not saying you are not 100% vulnerable, but you are way less vulnerable than in other solutions and without having a centralized token database.
As for cookie automatically applied when sent to malicious script, your cookie is http-only so it will be sent automatically only to the same domain thus reducing the risk of getting stolen. Also, it cannot be accessed through JS.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
You store them in memory, but not on the global scope. So they can be accessed only from your code or if an attacker reverse engineer your code. So you should never expose memory token getter function to the outside world. That's how you can prevent attacker from getting the token.
In memory, I have a getter function to get the token and every 15 minutes I do refresh_token call (silent refresh). All of this is written in the blog post in Silent refresh section
If you need to validate if your tokens were revoked or not that can be done by blacklisting them which is also described in the blog post in blacklisting tokens section. Session-based authentication is problematic in a microservices architecture. I referred to that also in blog post
If you only store your JWTs in memory, how do you deal with a user refreshing the browser? In my application I would like a user to be able to refresh the browser and automatically be logged back in.
I covered that later in blog post. Short answer - refresh tokens and silent refresh. Please check the full blog post here: blog.hasura.io/best-practices-of-u...
Hello Vladimir, thanks for your fast reply and further info.
I am looking for a way to use JWTs in a safe way, and this blog provided a good base to get more information on how to achieve this.
I read your links, but am still not convinced that JWTs (without binding) can be protected from XSS theft and misuse.
I understand you should not store tokens in global scope, but somewhere in your JS-application you have a function to get the accesstoken. This function can store the token in some private property of an object, but:
the (silent) refresh function you describe still looks vulnerable to XSS to me. You protect the refresh-token from getting stolen, but a malicious-script can call the /refresh_token API via the users browser, the cookie gets automatically applied, and now the script has an accesstoken it can publish to the hacker.
Of course CORS can be used to minimize the possibilities to inject XSS-scripts and to publish data to the outside world, but with analytic services, advertisement networks, and social-media integrations this still is very hard to prevent completely.
The best option I have seen is Token Binding but this isn't supported in browsers. You can try to implement something similar yourself with the JS-crypto functions, but then access to your API will be much harder to implement.
The safest way to provide access to your services is then by using session-cookies (although API calls can still be compromised in the same way with targeted XSS attacks; calling API's via the users browser that will automatically applies cookies, you can at least not access the API's from other systems after a token is stolen).
I am not saying you are not 100% vulnerable, but you are way less vulnerable than in other solutions and without having a centralized token database.
As for cookie automatically applied when sent to malicious script, your cookie is http-only so it will be sent automatically only to the same domain thus reducing the risk of getting stolen. Also, it cannot be accessed through JS.