They're a complicated solution to a problem that you almost certainly don't have. Storing session data in a private datastore using a long random session identifier as the key is simpler, more secure, and more flexible than JWT.
This meme is getting out of hand. Yes, JWTs may be inappropriate compared to putting a session id in a cookie, but there are many uses for JWTs outside of web app session handling. There are a couple serious implementation pitfalls to be aware of, but the bottom line is that JWT is a convenient and standardized way to construct a secure bearer token.
Despite the pitfalls, most folks that need a bearer token format (not just a web session) are probably better off using JWTs than rolling their owns solution.
1. A bit unnecessarily abrasive and hysterical in its style, and
2. Comes from a PHP consulting firm, promoting their own alternative proposal (which hardly anyone else seems to discuss or use). So I think #1 above is really about drawing eyeballs and selling services, more so than providing clear information for a newcomer to follow.
JWT does have its issues, though. They basically break down into two points:
1. Because of its distributed nature, there's no built-in way to invalidate a JWT prior to its natural expiration. You have to roll your own approach for this, typically some sort of whitelist or blacklist mechanism (which defeats some of JWT's advantages).
2. By default, the spec and its major library implementations allow JWT's to specify a number of different signing algorithms (including "None"!). This is dangerously nonobvious for newbies.
Best practice is to configure your code to only allow a limited number of algorithms (i.e. one).
> Comes from a PHP consulting firm, promoting their own alternative proposal (which hardly anyone else seems to discuss or use). So I think #1 above is really about drawing eyeballs and selling services, more so than providing clear information for a newcomer to follow.
Keep in mind that PASETO didn't exist until the middle of 2018, so the main reason "hardly anyone else" seems to use it is precisely because it takes time for standards to be adopted.
If you take a look at https://paseto.io, you'll see that there are implementations of PASETO (our proposed alternative) in multiple programming languages by other companies and individuals. All of these implementations are open source and under very permissive licenses (MIT or ISC).
Additionally, a great deal of time and effort went into the PASETO documentation, so that developers can understand not only how to implement it themselves, but also why it was designed the way it is. https://github.com/paragonie/paseto/tree/master/docs
Given all of the above, is it really fair to write PASETO off as an attempt to sell services?
Claiming that the original article is meant to sell services doesn't make sense either: If developers keep using unsafe tools, they will continue to be less secure and I'll have an easier time selling "make your products/services more secure" services to developers. The best thing to do, to meet such an incentive, is to say nothing publicly and let the easy money keep rolling in.
So one of two things is happening:
1. You don't correctly understand our intentions.
2. We're really bad at understanding our own incentives, and it's a miracle we've been in business for 4 years.
I mean, your homepage is pretty damn lacking and you even put something like this without putting any sources 'This has led to many security experts declaring boldly, "Don't use JWT!"'. This just looks like a poor attempt at making something 'better'.
The parent comment isn't very helpful, but from what I understand people dislike JWTs because it makes it hard to invalidate a session without some sort of work-around. For example, you can use 2 tokens, one short lived, and one long lived to get around the invalidation problem, but then you will need to occasionally validate that both tokens are still valid, and that state needs to be stored, and now you're storing some state, which is semi-contradictory to the purpose of a stateless-token. Here's a more detailed write-up from another poster -- https://news.ycombinator.com/item?id=12332119
The way I understand it the only sane use for JWTs is for short-lived delegation of authorisation.
E.g. a user wants to talk to service A but access to that service requires certain privileges. Instead of authenticating with service A, the user authenticates with service B (e.g. using a long-lived conventional session mechanism that requires DB lookup), which issues a token the user can then pass to service B (which trusts service A the info is valid and needs no lookup to process the token). JWT standardises a format for that token.
Most uses of JWT in the wild however seem to be for authenticating the user of a (web) app with the backend of that same app, so the token is passed from the backend to itself (via the user). This use case is better suited for conventional session tokens.
At work we use JWT strictly within our own infrastructure, and opaque tokens for requests coming into our API gateway. This gives us a single point to check tokens are still valid, after which a JWT gets passed back to the backing service. The actual service internally can trust that the token it received is still good to use, in many cases not needing to do any further queries to get user details as their encoded in the token.
It's a combination of the other comments response about having to still manage state for invalidation and the issue with the none algorithm. JWTs specify the algorithm their signature was encoded with in the alg field of the header. There was a decent portion of JWT libraries that by default honored the alg : none. This would allow the algorithm field to be changed to none even though the JWT had a signature and the libraries would successfully validate the JWT.
This is the best explanation I've seen. I think many commenters mean to say something similar but don't give enough context. Here's my phrasing of what I take away from tptacek's comment:
JWT is designed to be customized for a variety of use cases, which means programmers using JWT are rolling their own security scheme, including choosing cryptography from a practically unrestricted field of options. This is known to be a recipe for disaster. A good standard should provide an expert-validated scheme for a specific use case that gives end programmers assurance that if they comply with the standard, the scheme will fulfill its intended use case. This means standardizing separate use cases separately; therefore, JWT is at best a technology that experts could use (but probably wouldn't) to devise specific standard solutions for specific use cases which would then be appropriate for end programmers to use.
JWTs can be read by every script you add to your site, making XSS attacks easier. A cookie with the HttpOnly flag prevents this. I also found cookies easier to use, since the browser handles them and you don't need to attach headers to each request.
Any other important concerns or which way is recommended currently?
> JWTs can be read by every script you add to your site, making XSS attacks easier. A cookie with the HttpOnly flag prevents this.
You're confusing JWTs (a standardized token / means of representing claims) and JavaScript localStorage (a storage which can be read by scripts, partitioned by origin). The two are completely orthogonal; you could store a JWT in a cookie, if you wanted to.
> JWTs [… make] XSS attacks easier. I also found cookies easier to use, since the browser handles them and you don't need to attach headers to each request.
The browser handling them automatically means you need to think about CSRF, which I think largely negates the benefits.
If your site is vulnerable to XSS, a cookie won't save you; the XSS attacker just makes the necessary authenticated request using an AJAX.
CSRF is mitigated by using the samesite cookie flag. XSS is mitigated by httponly, except where XSS makes legitimate requests to domains specified by the cookie.
This article describes some of the most vulnerable ways to use a JWT in 2019, but please let's stop talking about none algorithms.
samesite doesn't appear to work in Safari, IE or Edge sadly.
EDIT: apparently it's a bit more complicated than that: IE11 on windows 7 doesn't support it, and Safari < iOS12 doesn't support it. Still seems like a significant-enough chunk that you can't rely on it.
Considering the alternative is local storage, and I can include traditional csrf tokens, it still feels like a partially supported samesite flag with httponly is a solid defense against xss and csrf and doesn't lead to a road of dangerous tech debt.
if you're wrapping the JWT in a cookie, then it's effectively a session cookie. In that case, the client side difference between JWT and session cookies are effectively moot.