
Things you should know about Token-based Authentication - thepose
http://blog.auth0.com/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies
======
mixedbit
I think token based authentication for API calls is great, but for browser
based usage cookies are extensively studied and well understood mechanism that
is IMO a much safer option.

You wrote that XSS is much less risky that CSRF, but 'based on our experience'
argument is not really strong. For example OWASP study lists CSRF as easier to
prevent than XSS:
[http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%...](http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%202013.pdf)
To me this makes sense, XSS vulnerability can be introduced anywhere in your
application code, CSRF can be dealt with in a single middleware, which greatly
simplifies prevention.

How about https only cookies? Can you enforce that tokens won't ever be send
over http? Can your enforcement work in a presence of XSS (as is the case with
a combination of 'secure' and 'httponly' cookie flags).

With tokens it is easier to do authenticated cross origin requests. But a new
mechanism may be vulnerable to a new class of vulnerability, where a web app
will be tricked to make such requests to evil domains (it may sound
unrealistic, but remember that CSRF was discovered many years after cookies
were introduced).

Cookies can also require no server side state. You can put signed, encrypted
content in them and many frameworks support this, which shrinks a list of
token benefits a bit.

I do think that token based approach is more elegant from the architecture
point of view, because you don't need to deal with two different
authentication schemes to support browser traffic and API calls, but I'll
still stay with cookies for browser auth.

~~~
jfroma
The [OWASP] recommended approach to solve CSRF is with a Synchronizer Token
[1].

Basically render a token with a hidden input with your form associated with
the user session and as you mention use a middleware to validate the token on
every request.

So, let's talk about Syncronizer Token and "Single Page Applications" which
was the topic on our first blog post. The recommended way for this is to get a
token the first time and use the token in a header in every AJAX request. [2]

So, you now have cookies that are vulnerables to CSRF and a token in your
javascript scope, in the same way you have the JWT.

If you think XSS is that common, the http only cookie+synchronizer token is
more work and equally vulnerable to CSRF.

While with JWT you can stole my token if the site is XSS-vulnerable, but you
can't trick me with the browser to do things I didn't meant.

I still consider XSS is easy to prevent than CSRF, you just need to escape
user inputs always which is what every major template engine does by default.
Usually you get the common syntax which does ESCAPE the user input.

Why OWASP states the contrary? I have one word: php. I blame php, wordpress
and wordpress plugins. Consider that half of the internet runs on wordpress.

[1]: [https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_(...](https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_\(CSRF\)_Prevention_Cheat_Sheet#General_Recommendation:_Synchronizer_Token_Pattern)
[2]: [https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_(...](https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_\(CSRF\)_Prevention_Cheat_Sheet#Encrypted_Token_Pattern)

------
jfroma
In case you missed, this is a follow up of our first blog post:

[http://blog.auth0.com/2014/01/07/angularjs-authentication-
wi...](http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-
vs-token/)

and

[http://blog.auth0.com/2014/01/15/auth-with-socket-
io/](http://blog.auth0.com/2014/01/15/auth-with-socket-io/)

We are here to answer any question about this one.

~~~
skybrian
FYI, your blog doesn't render properly with the Disconnect extension:

[https://chrome.google.com/webstore/detail/disconnect/jeoacaf...](https://chrome.google.com/webstore/detail/disconnect/jeoacafpbcihiomhlakheieifhpjdfeo)

(The code sections don't highlight or don't show up at all, etc).

------
mixedbit
Am I right that for browser use case this mechanism can be used only to
authorize access to resources that are requested with JavaScript?

For example, I can't use an 'img' HTML tag to include images that require
authorization, because browser won't set a Bearer header while requesting
images?

~~~
woloski
For images that are protected you can use this approach

[http://blog.auth0.com/2014/01/27/ten-things-you-should-
know-...](http://blog.auth0.com/2014/01/27/ten-things-you-should-know-about-
tokens-and-cookies/#file-downloads)

~~~
mixedbit
But with tokens in URLs you can do CSRF.

~~~
jfroma
No, you need the signed token for the link, that will only works for that
particular url (protocol, host, path, query), for a breve period of time and
only for GETs. As mentioned in the blog post, you can check hawk bewits:

[https://github.com/hueniverse/hawk](https://github.com/hueniverse/hawk)

------
acjohnson55
Cool post! Auth is one of those things I never really want to dig into, so
it's great when someone makes something that demystifies things a bit.

~~~
jfroma
thanks, glad it helped!

------
arethuza
So with JWT you package up all of your claims into JSON, protect that with
HMAC (and encryption?) and give that to the client.

With opaque bearer tokens you effectively have the same claims but these are
stored on the server (e.g. in a database) and keyed by the opaque token value.
The claims never leave the server.

Is that roughly correct?

~~~
woloski
Yes, that's correct.

~~~
arethuza
So to get the advantages of the JWT approach you _really_ have to trust the
content of the tokens you receive - if you start validating everything and
scrutinizing the claims made in detail (especially against a database table of
issued tokens) you might as well use an opaque bearer token?

~~~
woloski
Yes, I don't think there is a one-size-fits-all answer. It will depend on your
use cases. You can always start small using JWT and move to database backed
tokens when you get a better idea of your architecture, use cases and
authorization needs. For the user, it will still be opaque and bearer.

------
canadev
Is there a way to make token-based authentication useful in the browser when I
am not using JS to send my requests?

e.g., can I get the browser to send the auth header when the user clicks a
link after having signed in? Suppose I'm not using any JS on my page at all,
or the browser has JS disabled.

~~~
jordan0day
I think you generally just fall back to using normal website auth
(cookies/session/etc.).

If you really don't want to do that, you could probably work up something like
the author discusses in item No. 5, and generate query parameter "tokens", and
append those query params to every link on the rendered page.

------
blinduck
On a somewhat related note, does anyone have a recommendation for a good
introduction to the different types of web based authentications?

I've just started working with AngularJS with a Django backend and
authenticating users has been one of the biggest issues I've faced so far.

~~~
jfroma
in addition to our first blog post:

[http://blog.auth0.com/2014/01/07/angularjs-authentication-
wi...](http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-
vs-token/)

Jose Paddilla is using it with django and he wrote a blog post:

[http://jpadilla.com/post/73791304724/auth-with-json-web-
toke...](http://jpadilla.com/post/73791304724/auth-with-json-web-tokens)

and he wrote the backend for django:

[https://github.com/GetBlimp/django-rest-framework-
jwt](https://github.com/GetBlimp/django-rest-framework-jwt)

I hope this help you.

~~~
blinduck
Thanks! Will check these out.

------
jpdlla
Great stuff guys, keep it up!

