Vuejs + jwt

You may use HttpOnly flag for cookies to prevent Javascript code from touching your jwt.

1 Like

Yeah, the issue is not many people like authenticating via two-factor. It would be a barrier .

Well, if I set this flag, how my javascript would get the current token?

And if on API which has been built with laravel we somehow allow ajax calls only from a certain domain. So, whoever gets the token won’t be allowed to make a request since they don’t have access to our domain.

However, can they forge the origin?

Access-Control-Allow-Origin: http://mydomain.com for instance.

Well, the essence of HttpOnly is keeping Javascript code out of jwt storage, so even if attackers inject some JS code on your page with simple XSS, they won’t be able to steal jwt token away. Note that some advanced XSS attack may bypass HttpOnly protection. Read more at https://stackoverflow.com/questions/34817617/should-jwt-be-stored-in-localstorage-or-cookie. HttpOnly should only be considered as the last defense for basic XSS injections.

In our SPA application, server side reads cookie from HTTP header and user requests delete /auth/jwt on logout.

That is the issue. Our frontend site is plain javascript, so I can’t use server side stuff.
I have read the article you provided, but still not secure. Any simple script can catch cookie files, no?

Not really. Only your own javascript can read the cookie.

They still can’t read the values from the cookie. Basic CSRF is implemented by requiring a request to have both the cookie as well as setting a header or body value to a value from the cookie, proving that the cookie was accessed. Anyone can send a request to your API, but only scripts from your own domain can read the cookie and send the value.

This is all unrelated to JWT for the most part. JWT is just a string value - it doesn’t really change authentication, its mostly used for authorization (ie you can store user permissions client side and the server can trust that permission because the JWT is signed).

1 Like

Cool, great answer!
I just wonder if those nasty people can forge the domain to use the script. Lets say, they create the domain in the /etc/hosts file and point to the local machine. Then, use the domain to send request with the stolen token?

They shouldn’t be able to access anyone else’s token but their own.

No, I mean…

lets say if someone has broken the cookie and has stolen the token.

  • Would this person be able to make a request considering that the API will check the origin by Access-Control-Allow-Origin
  • Would this person be able to make a request forging the the domain?

If someone steals a user’s auth token they can do anything that user could do.

That is my point. So storing it in a cookie isn’t the best way, right?

https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

I’ve been there and my conclusion is, there is no safe place to store it. I mean, really safe!

Client === Not secure, simple as that.

2 Likes

Earlier this year I had a project with a comparable scenario (client-side javascript app only) where we had to store the token locally. My conclusion from that same Stormpath blog was that cookies are safer than localStorage (if never 100% safe), because they can be protected from XSS attacks. Quote:

“Stormpath recommends that you store your JWT in cookies for web applications, because of the additional security they provide, and the simplicity of protecting against CSRF with modern web frameworks. HTML5 Web Storage is vulnerable to XSS, has a larger attack surface area, and can impact all application users on a successful attack.”

3 Likes

Hello everybody!

I am a security engineer (~“whitehat hacker”), so ask me anything related freely.

So let’s go through this whole topic again:

Everything is safe against a remote attacker as long as you use HTTPS and there is no XSS on your page. Your main concern should be avoiding XSS.

If you have XSS on your page then basically everything is lost, the attacker will be able to hijack the user’s session one way or other, it does not matter if you use cookies, local / session storage or IndexedDB, etc.

These are the differences between the various techniques, but as I said, these won’t stop a determined attacker:

HttpOnly cookie

  • If you set the HttpOnly cookie, then you and the attacker cannot read this cookie from JavaScript.
  • Sadly the attacker can still use the user’s browser as a zombie machine and execute any action the user can, because if you have XSS then nobody can make distinction between the legal code (written by you) and the illegal code (written by the attacker).
  • Keep in mind that if your website is not protected against XSS properly then an attacker can use the user’s browser as a zombie while the user is on an unrelated (attacker created) website, like a really interesting funny cat videos website :wink:
    • ((The attacker can embed your website as an 1x1 pixel iframe into his cat videos website, so the user won’t see it your site, but the attacker can still control it))

Cookies vs. local storages

  • Cookies are encrypted with your OS’s password on Windows and OSX (at least in Chrome), while local storages are not. So if the attacker physically steals the user’s laptop but does not know the user’s password then he can read the JWT token stored in the local storage, but cannot read the JWT token stored as cookie. (HttpOnly flag does not matter here).
  • Keep in mind if the attacker can steal the laptop then everything is lost again probably, so it’s not really your responsibility.
  • Cookies are sent to the server. If the server does not need the token then you don’t need to send them through the whole internet.

What should I do?

  • Concentrate on XSS protection, that’s the 98% of the protection, the cookie vs. localStorage decision is like 2%
    • If you use only client-side code then you can store it in the local storage, this way you won’t leak incidentally to the server. Although it won’t be encrypted (thus protected against local attacker) that’s a rare attack scenario, I wouldn’t optimize for that.
  • Read about XSS protection (I heard this is a good resource: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet )
  • Test your website with various scanners, including but not limited to Mozilla Observatory: https://observatory.mozilla.org/ (sorry, I cannot link too much websites in this comment)
    • Follow their suggestions, eg. setup X-Frame-Options: deny, X-XSS-Protection: 1; mode=block headers
    • But keep in mind these are not silverbullets, a determined attacker will bypass these protections, not creating XSS in the first place is the key here

If you are using a safe framework like Vue.js to display data and don’t manipulate the HTML with other means (jQuery, innerHTML property, document.write, etc) and don’t do anything stupid then you have a good chance that you won’t have XSS and you don’t have to worry about where to store secrets.

17 Likes

Awesome answer. Thank you very much!
So, if a make sure that my website is protected agains XSS, I can safely rely on cookie right?

Cheers!

Yes.

Additional tips:

  • use Secure flag for the cookie and use only HTTPS (otherwise an attacker on eg. a free WiFi can see your user’s traffic and steal the cookie)
  • cookies can be set accessible for all subdomains (so not just for example.com, but every *.example.com). Don’t do that only if it’s necessary. Otherwise any XSS on any of your subdomains can cause problems. If you use a cookie handling library make sure it does not use subdomain cookies (eg. in Chrome it shows “.example.com” instead of “example.com” in the domain column of the cookies page).
4 Likes

Super cool mate! Thank you very much!