I'm developing a serverless application on AWS and a static frontend using Svelte.js with Sapper. For user management I'm using AWS Cognito User Pools. Cognito returns JWT tokens when performing auth actions, and so this naturally leads to the ever devisive issue of where to store these tokens client-side.
I've read about the various pros and cons of using localStorage vs cookies and how the first option opens one up to XSS vulnerabilities while the second is vulnerable to CSRF. I understand that localStorage can be easily accessed by a malicious script and that it's risky to store sensitive information like JWTs there. I also understand that using HttpOnly prevents javascript access to cookies and hence why they should be more resillient to XSS attacks.
But while reading the OWASP guide to CSRF prevention I came across this interesting statement:
However, any cross-site scripting vulnerability can be used to defeat all CSRF mitigation techniques available in the market today (except mitigation techniques that involve user interaction and described later in this cheatsheet)... It is imperative that no XSS vulnerabilities are present to ensure that CSRF defenses can't be circumvented.
Yet, there is another statement from the same guide that states:
Please note that tokens by themselves can mitigate CSRF
And this made me very confused. Which is it? Are all CSRF prevention techniques outside of user interaction vulnerable, or are token based techniques acceptable?
And if they are not valid, and since CSRF prevention relies on XSS prevention, doesn't this imply that storing JWTs in cookies offers little to no more security than storing them in localStorage? If there is an XSS vulnerability in my app, doesn't this mean that any CSRF defenses I've set up are effectively useless?
If that is the case, then why go through the trouble of handling cookies and CSRF prevention when I already need to prevent XSS in the first place?
Can someone help shed some light on this issue please? Is there a way to properly use JWTs that doesn't expose one to XSS attacks? Are token based techniques like the synchronizer pattern or the encryption pattern really effective?
Thank you.