6 ms·
Isn't JWT also a type of bearer token? Could you please provide some more detailed arguments about why JWT shouldn't be used other than linking its wikipedia ar
by aeleos 8y ago
Isn't JWT also a type of bearer token? Could you please provide some more detailed arguments about why JWT shouldn't be used other than linking its wikipedia article?
- mcbits 8y agoJWT is fine if "revoke" isn't in your vocabulary for the service. If you do need to revoke tokens, JWT becomes a racey contraption that requires synchronizing and looking up state on every request, the avoidance of which was the main reason to use JWT in the first place.
- kc10 8y agoIt's a common practice to add expiry timestamp for such tokens so each token will expire after certain interval.
- throwawaymath 8y agoThat's dandy, but it's a solution which is neither standardized nor native to JWT. It's also a weak, passive form of revocation instead of a robust, active form. How do do you revoke a token prior to timestamp expiry? In 2018 it is fully possible to use authentication libraries which natively support granular control for things like revocation using strong, turnkey cryptography. I would argue most people who think they should be using stateless and signed sessions for e.g. performance are heavily discounting the revocation liability and neglecting to optimize their lookups sufficiently (such as by caching).
- geezerjay 8y ago> That's dandy, but it's a solution which is neither standardized nor native to JWT. That statement is false. JWT were specifically designed to store a payload JSON object which among the many standardized fields include the token's expiry time, and JWT were specifically designed with a workflow which includes not only client-side token refreshing but also server-side token rejection that triggers client-side token refreshes. In fact, JWT token refreshes and token rejections feature in any basic intro tutorial to JWT, including the design principle that tokens should be discarded and refreshed by the client as soon as possible and also the use of nonces.
- throwawaymath 8y agoNo, it's not false. Tutorial "best practice" guidance does not constitute a standard. JWT does not provide native revocation. Neither refreshes nor expiry constitute revocation. Revocation is an active state change, not a dead man's switch.
- geezerjay 8y agoYes, that's patently false. The exp payload field is even specified in JWT's RFC along with the token rejection workflow. https://tools.ietf.org/html/rfc7519 https://tools.ietf.org/html/rfc7519 The same document also specifies the jti field which is the JWT's nonce.
- throwawaymath 8y agoAgain, expiry is not revocation. This is an uncontroversial fact - if you disagree, please advise me as to how you'd revoke a token prior to its timestamp-mandated expiration without augmenting it further. And the jti field is not intended for what you think it is. Anti-replay is not at all the same as revocation. Those are different things entirely. I certainly believe (and have seen) the jti field used in the manner you describe. But no, that workflow is not intended for revocation. Which makes sense given the design intentions of JWT, because anti-replay can be accomplished as a stateless process, while revocation cannot.
- geezerjay 8y ago> Again, expiry is not revocation. Issue and expiration timestamps are used along with nonces to enforce single use tokens. Once a token is used then the client is expected to discard and refresh the token. Implementations are also free to keep track of issued tokens and that does not pose any problem in the real world. > And the jti field is not intended for what you think it is. Anti-replay is not at all the same as revocation. Why are you expecting to revoke a token in a scenario where the token is supposed to be used once? Either the token is deemed valid and accepted or it's invalidated and rejected, which triggers clients to refresh the token and retry the request.
- kokokokoko 8y agoRevoking a bearer token is trivial and in all likelihood, revoking tokens is a very infrequent event. In most cases it is such a rare event that you can usually commit your blacklist to source code. If not a service to validate tokens against a blacklist is again trivial and will scale to all but the top 0.1% of organizations. And it only needs to be in the blacklist long enough for the period until the token expires. Yes, jwt is not ideal. But this talk that you should never ever use them and your service will be immediately hacked etc is silly internet bandwagoning. For a huge percentage of services jwts are just fine. Anyone reading this, please do not over think this advice and just ship with jwts if that is what you have.
- throwawaymath 8y ago> Yes, jwt is not ideal. But this talk that you should never ever use them and your service will be immediately hacked etc is silly internet bandwagoning. I never said you should never ever use JWT or that your service will be hacked if you do so. In fact, if you kindly reread what I wrote you'll see that I explicitly mentioned there are legitimate use cases for JWT. I am specifically refuting the use of JWT as an authenticated session management system. > Anyone reading this, please do not over think this advice and just ship with jwts if that is what you have. This is poor advice. 1) Authentication is sufficiently solved for most workflows and applications that you can use turnkey solutions for more secure and more performant authentication than JWT. 2) What exactly is the scenario you envision in which JWT is all someone has? Do you mean they're forced to use stateless session management, or that JWT is literally all they can do for authentication because nothing else is available?
- virtualwhys 8y ago> What exactly is the scenario you envision in which JWT is all someone has? Do you mean they're forced to use stateless session management, or that JWT is literally all they can do for authentication because nothing else is available? Good luck using session cookies with Cordova on iOS, for example [1]. In cases like these JWT is perhaps your only option. [1] https://issues.apache.org/jira/browse/CB-12074 https://issues.apache.org/jira/browse/CB-12074
- lmm 8y agoI'd argue that people who think they should be using caching are heavily discounting the consistency issues they will encounter (no doubt at the least convenient time), and may well end up reintroducing the same problem they're trying to solve. If you have revocable tokens accessed via an authentication lookup cache with a 5-minute expiry then you've spent a lot of time and engineering effort to have exactly the same problem as if you had non-revocable JWTs with 5-minute expiry.
- deleted 8y ago[deleted]
- gavinpc 8y ago> In 2018 it is fully possible to use authentication libraries So — getting back to the OP — which libraries?
- throwawaymath 8y agoNaCL, Fernet or Paseto.
- newman8r 8y agoyou can also blacklist existing tokens - but that's not without it's own drawbacks https://auth0.com/blog/blacklist-json-web-token-api-keys/ https://auth0.com/blog/blacklist-json-web-token-api-keys/
- CorvusCrypto 8y agoSame goes for any signed token scheme. You can still revoke JWTs if you give them an ID and keep a revoke list somewhere. Though as you said most use these to avoid datastore lookups. It's a trade off. Either time-limit signed tokens that can't be revoked with benefit of no lookups or implement revokation.
- jakelazaroff 8y ago"No revocation" is a dangerous constraint to have in an authentication session. What happens if a user's token is compromised? You have to either wait for the token to expire (if you implemented expiry) or log out every single user.
- CorvusCrypto 8y agoThat's exactly the trade-off. I'm not going to say it's a big enough negative to dismiss using the stateless signed token scheme because it depends on the needs of the application. But either way, if you really can't afford a database or cache layer lookup to see if a token is still valid, then you accept that by using a bearer token, that is only validated by signature alone, that it is possible a user will have their session hijacked without possibility of revokation. The usual way this is mitigated is by use of a small expiry time (I've commonly seen <=5 min) and a revokable refresh token. This still gives a hijacker a possible 5 minutes (assuming 5 minute expiry) if a user revoked the refresh token, but it does mitigate the damage while still reducing DB lookups since you only do a lookup in token refresh. Hope that clears things up. Again your application needs should drive these decisions.
- tyldum 8y agoIndeed. However, this is just a building block and not a library solution. Combined with a revocation list you are good. And use something like OpenPolicyAgent to implement it, adding a lot of other possibilities as well.
- geezerjay 8y ago> You can still revoke JWTs if you give them an ID and keep a revoke list somewhere. You don't need the ID. You can simply store the token's signature. In fact, some implementations store the whole JWT to avoid roundtrips to the auth service, and revoking the token is just a matter of flipping an attribute in the database.
- jondubois 8y agoIf you use a realtime transport like WebSockets, you could keep automatically re-issuing a fresh JWT with a very short (e.g. one minute) expiry every 50 seconds; just push them at an interval to authenticated clients. That way your banning mechanism would only have a one minute a delay. No need to revoke tokens; just let them expire. In such a system, a user would be logged out after one minute of closing the connection... Probably good enough for online banking. In a way, this is safer than standard sessionId-based auth because once you've issued the token, you don't need to worry about scenarios where the user has gone offline suddenly. There are very few systems that need banning with down-to-the-millisecond accuracy.
- dullgiulio 8y agoYou don't need JWT in this case. You can use a normal token with short expiry and some mechanism to keep it fresh as long as the user doesn't exit the application.
- jondubois 8y agoJWT is simpler to implement and more scalable than the sessionId approach so why would you use the more complex solution to get an inferior result? With JWT, you only need to do a single database lookup when the user logs in with their password at the beginning... You don't need to do any other lookup afterwards to reissue the token; just having the old (still valid but soon-to-expire) JWT in memory is enough of a basis to issue a fresh token with an updated expiry. It scales better because if you have multiple servers, they don't need to share a database/datastore to manage sessionIds.
- groestl 8y agoWith WebSockets, you also have just one lookup when opening the connection. No scalability issue here.
- jondubois 8y agoThis is not accounting for reconnect scenarios. With sessionId, if the user loses the connection and reconnects, there will need to be another DB lookup to verify that the sessionId is valid. This is not the case with JWT. The validity of the JWT can be checked without any DB lookups. Also, this is a security consideration because a malicious user could intentionally send fake sessionIds to make us DoS our database. With JWT, verification of the signature only uses CPU on the workers which are easier to scale.
- dagoat 8y agoI thought the problem with JWTs was the whole “stateless JWTs”.
- CorvusCrypto 8y agoI can elaborate a tiny bit. It's been mostly a rocky road in library development as well as some confusion in the jwt specification. Basically the JWT spec is poorly designed for lay-programmer use and some folks are implementing the spec wrongly or are just configuring their systems that use properly-implemented libraries in dangerous ways. For instance you need to choose the algorithm carefully and then be careful not to accept any other specified algos as it can cause some interesting attacks (specifying symmetric algorithm when the token was meant for asymmetric ones can lead to valid signing using the public key if the system allows it). Also Technically a user can specify a "None" algorithm that doesn't do payload verification, which tbh all backends SHOULD drop tokens specifying this. JWTs as bearer tokens aren't bad in their own right, but if you aren't careful you can screw yourself and therefore many security experts avoid them for use in securing systems. Plus a lot of people mistake it for an encrypted token which it isn't. You can imagine how bad that can get. Tbh I'm with the parent commenter. I avoid them, but if you avoid common pitfalls they should work for your system no problem. I'm on mobile and can't be arsed to gather sources, but you can search the claims I made and you'll see several articles about these problems. There's even a defcon talk about a new proposed standard (called Paseto I think) that starts by highlighting the major issues with JOSE and JWT specifically.
- mixmastamyk 8y agoTptacek shits on them every time it comes up. Unfortunately I can never quite comprehend what he says to do instead.
- icebraining 8y agoHe suggests KISS: you can probably get away with plain old server-side auth, and if you really need client-side tokens, use something simple that just encrypts and signs them: https://news.ycombinator.com/item?id=13612941#13615634 https://news.ycombinator.com/item?id=13612941#13615634
- Aeolun 8y ago> Something simple that just encrypts and signs them Like JWT? I feel like that argument goes around in circles.
- icebraining 8y agotptacek's point is that JWT is not simple at all: https://news.ycombinator.com/item?id=13866983 https://news.ycombinator.com/item?id=13866983 https://news.ycombinator.com/item?id=14292223 https://news.ycombinator.com/item?id=14292223
- geezerjay 8y ago> I feel like that argument goes around in circles. I feel that the problem is that some users are talking about stuff they know nothing about, but still feel compelled to be very vocal and opinionated.
- ad-hominem 8y agoJWT's are NOT encrypted by default. They are cryptographically signed. That is totally different. If you get somebody's JWT, you can get everything stored in the token as well. If you want it to be encrypted, you have to encrypt the token (presumably following JWE).