I've been reading Aaron Parecki's draft of browser-based apps' (meaning SPAs like those developed with React or Angular) authentication best practices with OAuth 2 as well as OWASP security guidelines, and it left me really confused:
localStorage
by default, which OWASP guidelines recommend against. Does it have some kind of extra protection? Should I put some extra digest in it and also put it in a cookie and match them?Some references:
To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading or writing) from JavaScript running in the browser.
The authorization server can contain this risk by detecting refresh token reuse using refresh token rotation. If your application uses refresh token rotation, it can now store it in local storage or browser memory. You can use a service like Auth0 that supports token rotation.
Securely store tokens In a web browser, there are multiple options to store tokens. You can store them in cookies or you can store them in HTML5 storage(sessionStorage or localStorage) or you can save them in the browser memory.
Store refresh tokens in a secure location, such as a password-protected file system or an encrypted database. Limit access to users who need the tokens to make API calls. If you believe that a refresh token has been accessed by an unauthorized user, delete it and create a new one.
TRADITIONAL SPA FLOW
In the traditional SPA flow it was standard to use iframes to silently renew tokens.
Meanwhile access tokens were best stored only in memory and should also be short lived. There were still threats of capturing tokens in transit, some of which are explored in this post of mine.
2021 UPDATE
There are two big changes to browswrs that are related to SPA token refresh:
Browsers drop third party cookies aggressively, meaning that traditional SPA token refresh no longer work reliably (eg in the Safari browser)
Browser cookies security has become stronger via SameSite=strict
cookies, and concerns about XSS threats (video) have increased
BACK END FOR FRONT END
So it is now recommended to store refresh tokens in HTTP only encrypted SameSite=strict
cookies. This is best done in an API driven manner, to avoid impacting the web architecture. See this blog post for some up-to-date best practices and links to resources including a React code example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With