@jhipster/developers any opinion on this ?
Here are some links about this question :
http://stackoverflow.com/questions/35313384/jwt-cookies-https-csrf
« However, making the session token cookie httpOnly and secure still leaves you vulnerable to CSRF attacks”
There are techniques for preventing CSRF attacks. I would recommend reading this OWASP page on CSRF attacks and preventions.
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
Yes, we already have CSRF protection in JHipster session based auth and it should of course also be used here.
I'm surprised we are vulnerable to those attacks, and we first need to check if that's correct or not.
Then, as @cbornet says, we have a built-in protection for session-based auth, so we would just need to reuse it.
Actually, this is the continuation of #2584 discussion : as @sdoxsee pointed out you can't have a "remember-me" with OAuth2, former x-auth, or JWT without a server-side proxy (which would probably be the gateway in MSA) or else you are vulnerable to XSS
@cbornet tough question :) it's complicated to me...
@dsyer seems to advocate for almost always using the session: https://spring.io/guides/tutorials/spring-security-and-angular-js/#_but_what_about_my_custom_token_implementation_it_s_stateless_look
In this case it doesn't seem to be so much to protect against XSS explicitly as it is to leverage existing security infrastructure vs "roll-your-own".
Then there's https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/ where the case is made for authentication with token's over cookies (but with plenty of controversy in the comments)
Dominick Baier, an expert in this area and the one from whom I first heard about Open ID Connect a couple years ago, seems to reaffirm in the face of http://alexbilbie.com/2014/11/oauth-and-javascript/ that the implicit flow (which, like JWT or OAuth2 "resource owner password credentials flow" that jhipster currently uses, exposes the access token to the browser...thus XSS) is fine: https://leastprivilege.com/2016/01/17/which-openid-connectoauth-2-o-flow-is-the-right-one/#comment-75583 (also see the article in which the comments are made).
I personally like leveraging spring security's session because it
On the other hand, if you use the session, I don't think your backend API is mobile-friendly. With microservices, there is the BFF (Backend For Frontend: see http://samnewman.io/patterns/architectural/bff/) pattern where you'd have a different gateway for each frontend (be it browser, IOS, Android, etc.). So, in the case that it's not easily feasible to use the session (e.g. mobile), have a new gateway for that frontend that is token-based.
To answer shortly: no, it's not safe, you are vulnerable to CSRF attacks, as the attacker can use the localstorage to get access to the token.
@cbornet I'm closing this as I think we have the answer!
But then, shouldn't we remove the remember-me with JWT ?
Note that storing the token in sessionStorage limits the risk of XSS to the lifetime of the session but it doesn't eliminate it !
Maybe there could be another option: use the usual AngularJS XSS Cookie protection with a server-side session, like we do with session-based authent.
Pros:
Cons:
Just an update to say that the http://alexbilbie.com/2014/11/oauth-and-javascript/ article has been pulled. Apparently @alexbilbie no longer stands by some aspect(s) of what he was suggesting in this older article. From what I remember, the article was claiming that using implicit oauth2 flows (or more generally, keeping the token in the browser) was inviting XSS attacks and that a thin server-side proxy should be used. I reached out to him on twitter and he has new thinking on the matter...that he hopes to post about soon. https://twitter.com/alexbilbie/status/743475042273624065. My guess is that the risk of JWT exposure in the client is not as big as originally thought?
I know this a really old issue, but I consider it as non-answered, since pointing out that none of the storage options are (completely) valid for security. And most google searches usually point to this URL, I encourage you to consider and review a splitted token approach.
Hi @Frondor, yes I agree that storing tokens on local/session storage has a vulnerability if your site is compromised by some malicious code in a dependency or from code in CDN, but the entire premise of this being less secure is based on the assumption that there is malicious code running on your domain, it wouldn't work if the code is in an iframe so lets exclude those cases.
So let's consider that someone managed to inject code into your site via CDN or via an NPM dependency. Now here are all the things they could do using that JS code (Please note that I'm not a security expert, this is based on my understanding of what can be done with JS)
So IMO if there is malicious code injected on your site, then losing JWT tokens are not your only concern, If I can inject code into someone's site within their domain, I can do a lot of harm regardless of what security(JWT, Session, Oauth) you have implemented, so I'm not sure how any other methods suggested will help in this case?
I do agree that not having tokens in storage will reduce the attack surface a teeny weeny bit
@deepu105 Don't forget about browser extensions accessing every website's Web Storage. Your app dependencies may be clean from untrusted code, but your user browser can be compromised. Does it?
If that's the case, I don't think the XSS attacker can access the in-memory js instance of your app. Then, a proper Content Security Policy should do the job.
When your app becomes a XSS victim, I agree that stolen access tokens are just one of your concerns, but still a very important one, I shouldn't be ignored in my opinon.
@Frondor yes I agree, I'm not trying to say that its not a problem, my point is that if you are an XSS victim then you are compromised regardless of how you store your JWT key. Browser extensions can read html forms as well(Lastpass for example)
Btw i'm not sure if extensions can read the local storage of the app due to same origin policy
So my point was that trying to fix only JWT in localstorage doesn't necessarily secure you against XSS attacks. If I'm an attacker my first attempt would be to read login details from forms. The solution is to ensure that you don't open yourself up to XSS attack, this is rather hard problem and only way is educating users.
So fixing this particular issue of JWT alone doesn't solve the issue IMO and just complicates the setup further. Anyway i'm not against changing this if there is a nice solution without much overhead and if everyone else agrees
By the way, we could also use other tricks to make it more difficult to use the tokens even if stolen, one way I could think is
This still doesn't solve the issue but it makes it much more difficult to use the tokens without knowing the source code of the application
Still, the injected script can listen for authentication responses (overriding XMLHttpRequest for example) and get the token before the app can even encrypt it.
And my head just exploded :laughing: your example made me think about that method... And now I can't think on a solution for that (intercepted responses). So my question now is, is it possible for an embedded script to listen to your in-memory app XHRequests and get the body contents?
ANYWAY, if that's possible, the approach I linked is still valid and circumvents that, because even intercepting your app responses, he can't access the _other_ part of the _splitted token_ stored in the _httpOnly_ cookie :open_mouth: :boom:
@Frondor yes thats another way to do it, and I guess its possible as well