14 ms·
How to Use JSON Web Tokens
- Dowwie 8y agoJWTs are radioactive. Proceed with caution.
- fastbeef 8y agoI keep hearing this. Is there a good writeup available?
- tstieff 8y agoThe 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 https://news.ycombinator.com/item?id=12332119
- jon-wood 8y agoAt 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.
- pluma 8y agoThe 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.
- jayd16 8y agoIsn't that basically oauth?
- StevePerkins 8y agoYes. In a web setting (the most common use case for JWT), they are typically issued during an oauth dance.
- lkschubert8 8y agoIt'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.
- danesparza 8y agoOn using JWT's for sessions (which I think most folks assume would be a primary use case) I found this: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-fo... Also: it's very easy to abuse JWT tokens by storing them inappropriately... https://stackoverflow.com/a/27301616/19020 https://stackoverflow.com/a/27301616/19020
- m3nu 8y agoJWTs 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?
- deathanatos 8y ago> 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. My current favorite writeup on this is https://portswigger.net/blog/web-storage-the-lesser-evil-for-session-tokens https://portswigger.net/blog/web-storage-the-lesser-evil-for...
- beardedwizard 8y agoCSRF 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.
- fenwick67 8y agosamesite 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. https://caniuse.com/#search=samesite https://caniuse.com/#search=samesite
- CiPHPerCoder 8y agoBlog post: https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-ba... DEFCON CPV talk: https://paragonie.com/files/talks/NoWayJoseCPV2018.pdf https://paragonie.com/files/talks/NoWayJoseCPV2018.pdf + https://youtu.be/RijGNytjbOI https://youtu.be/RijGNytjbOI Alternative design that isn't radioactive: https://paseto.io https://paseto.io Apologies if this wasn't more readily available or commonly known. I'm worse at marketing than I am at engineering.
- tenaciousDaniel 8y ago[bookmarks] Thanks a lot! This is exactly what I needed.
- StevePerkins 8y agoMost of the "discussion" on this topic spins out of this blog post: https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-ba.... Which unfortunately is: 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).
- CiPHPerCoder 8y ago> 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. There was a recent (November 2018) talk at London Gophers about JWT Alternatives (slides here: https://speakerdeck.com/hako/exploring-alternatives-to-json-web-tokens-jwt https://speakerdeck.com/hako/exploring-alternatives-to-json-...). 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 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 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.
- netvarun 8y agotptacek posted some good commentary on this a while back - https://news.ycombinator.com/item?id=14292223 https://news.ycombinator.com/item?id=14292223
- dkarl 8y agoThis 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.
- ynniv 8y agoThey'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.
- andybak 8y agoThat's the conclusion I've come to. I wished someone would have saved me a few brain cells and told me that when I first heard about the damn things.
- schnable 8y agoThis 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.
- danesparza 8y agoThere are other ways to pass claims -- like using bearer tokens in the HTTP header, or using OAuth 2. (All with TLS, of course)
- sprt 8y agoYes, JWTs don't bring anything new to the table. In fact, most articles promoting their use don't even explain why you should use them. This is cargo cult programming at its utmost.
- orf 8y agoThere are many ways to do many things. That doesn't make it cargo cult programming. Encoding your claims as a JWT is useful because there are many libraries that work with this, it's a known format (and one that's not tied to any particular transport), and is really good for creating stateless authentication systems using asymmetric keys. If you're interested in the differences between JWTs and something like OAuth (which really are two different things entirely) then you can visit https://google.com https://google.com and type in "JWT vs Oauth2". Answers will appear on your screen.
- schnable 8y agoJWT is just a standard for bearer tokens (including those used by OAuth 2).
- danesparza 8y agoI originally thought so myself. But RFC 7519 (https://tools.ietf.org/html/rfc7519 https://tools.ietf.org/html/rfc7519) is different from RFC 6750 (https://tools.ietf.org/html/rfc6750 https://tools.ietf.org/html/rfc6750) -- and the two don't mention each other's implementation.
- leejo 8y agoRFC 6750 describes the format of Bearer tokens: https://tools.ietf.org/html/rfc6750#section-2.1 https://tools.ietf.org/html/rfc6750#section-2.1 # it happens than JWTs fit the format, so they can be used. The spec is vague enough here that you can stuff almost any string you want into the header, as long as it has sufficient entropy that it is near impossible to brute force. Of course, JWTs introduce their own concerns, as discussed in other comments.
- endiangroup 8y agoA small Go library we wrote to centrally manage distributed session tokens such as JWT inspired by CAS: https://github.com/endiangroup/compandauth https://github.com/endiangroup/compandauth. Main highlight is central revocation, locking and unlocking of distributed sessions The core concepts can be translated into any language that supports integers, happy to reference any alternative implementations.
- michelpp 8y agoThis is a good Javascript-centric writeup. This caught my eye thought: > Since JSON Web Tokens (JWT) are not signed using asymmetric encryption ... You don't have to, but can of course sign your JWTs with asymmetric keys, and many libraries support this. Third party token issuers (firebase, google, auth0) require asymmetric, since they're clearly not going to share a secret with you. Asymmetric also provides two-way token verification: The issuer signs the token with a private key, and receivers of the token can then verify that the token is legitimate using the issuers "well-known" public key.
- gregmac 8y agoI've dealt with and used JWTs in a few different applications, and all of them have used assymetric keys, and used as tokens passed between different systems. Keeping the private key only on the issuing system is more secure (or even essential, depending on what you're doing). If you're authenticating on the same system, you could get away with symmetric, but then the use of JWTs may no longer make sense vs just using a random key stored persistently on the server (eg, for session cookie, "remember me" or "forgot password" token) -- I actually can't think of a case where using JWTs makes sense if you have access to persistent storage. By storing the random value you can also revoke it server side, which you can't do normally do with JWTs.
- KaiserPro 8y agoJWTs are useful, but there are a few things that are not immediately obvious. 1) They are signed not encrypted. Anything you put in there is public readable, unless you encrypt your token after you generate it 2) you can accept a range of encryption types, don't. Stick to one type and disallow any token that doesn't conform (this protects against people making their own tokens with 'None' as the signing algorithm) I am surprised at how naive the JWT spec is. Why in this day an age is encryption a default for the _payload_? Also, why on earth is 'None' allowed as a signing algorithm? Thats just a cookie..
- manigandham 8y agoTo be clear, cookies are an HTTP header field that can carry any text data you want. You can pass plain text, JWTs or any other encrypted payload (which many web frameworks do automatically). JWTs aren't comparable to cookies, they're just a standard way to sign data.
- pkulak 8y agoHis or her point was that if you don't sign and/or encrypt, there's no benefit over a standard cookie.
- techslave 8y agonot sure if that was the point or not, but it's wrong. even if you did sign/encrypt, that's not a benefit over a standard cookie. you can easily sign or encrypt a 'standard cookie' as well. the benefit is the portability that comes from a standardized and widely used data structure.
- kbenson 8y agoYou say that as if cookies haven't been a standardized and widely used data structure (key-value store) for decades.
- 8y ago
- sjroot 8y agoThis page doesn’t have any discussion of strategies for expiring JWT, one of the biggest security issues with this auth mechanism. Even the code sample doesn’t include an expiration.
- redbeard0x0a 8y agoThe JWT has a built-in field called exp, which is the time the token is expired. This is built in. However if you need to 'expire' a JWT token early, there isn't a good way to do it. If your token has a JTI, then you could add a blacklist for that JTI (say in redis, with a TTL until the token's exp time). But that is left to the implementor.
- sjroot 8y agoThe page mentions the ‘exp’ field, but doesn’t use it in its example. I was suggesting the author point out the fact that, if someone gets a hold of a JWT without an expiration, then your system is in quite a bit of trouble.
- shkkmo 8y agoIt is up to your implementation if you consider JWTs without an exp field to be valid. Our implementation requires a number of fields that are optional in the spec.
- crescentfresh 8y agoSo that's what JTIs are for!! I disabled [generating] them in our app, I couldn't figure out what purpose a unique-identifier-per-jwt would have, when you could just use the jwt itself to uniquely identify itself.
- incadenza 8y agoMy issue here is that expiring JWTs involve adding state! The whole point of JWTs is stateless authentication, so I’ve never understood the advantage over sessions unless revoking tokens is never an option.
- ape4 8y agoMaybe in 2019 we'll stop using JSON/JS for everything
- java_script 8y agoYour wish has been granted. 2019 is the year of YAML as a serialization format and the return of CoffeeScript. Disclaimer: I am a genie.
- andybak 8y agoCan we go back further and have Django/Rails as the new hotness with Pjax/Turbolinks for the extra cool kids?
- jondubois 8y agoI think storing JWTs might make sense for some advanced scenarios where you have multiple services with varying security requirements but when you store JWTs, you lose a lot of the benefits of having a stateless token which doesn't require a database lookup. A possible alternative is to just make the JWT expiry very short; like one hour; then you don't really need to explicitly invalidate the token. With a real time bidirectional transport like WebSockets, you can make the JWT expiry even shorter; like 10 minutes and you can auto refresh it by pushing a replacement token to clients every 8 minutes or so. If the expiry is so short, you don't need the ability to invalidate tokens. Getting your laptop stolen while you are logged into a service which relies on JWT is like getting your credit card stolen; it will probably take at least 10 minutes for you call your bank to disable it.
- deleted 8y ago[deleted]
- groestl 8y agoAn hour could be much much too long, depending on what service you are protecting. It's long enough that even assuming that token theft is a non-stealthy operation, and the user reacts immediately, the attacker has a lot of time to execute his attack. For things like Facebook, this could include slowly scaping all user data and spreading the infection vector to other users. As for websockets: session integrity is handled by TLS, and invalidation can be handled by closing the TCP connection. Authentication needs to happen only once, on connect.
- jondubois 8y agoStoring JWTs in a store or DB is difficult because you need to manage them and that means accounting for all possible edge cases. You can't always detect when a WebSocket/TCP connection has closed from the back end. For example, if your WebSocket server crashes suddenly, all active JWTs that you keep in your external data store will be orphaned and they won't get cleaned up until you run a separate cron job (which adds a lot of complexity). Storing JWTs in a hashmap in memory is also not ideal if you have multiple processes/servers because it doesn't account for WebSocket lost connection and reconnection edge cases; the client could reconnect to a different server/process than before.
- EGreg 8y agoI used to just follow whatever people said in oAuth and oAuth 2. No longer. Once I started questioning why we need all these tokens, when we will anyway have to look up access information in some database, I got pretty much no satisfying answers: https://security.stackexchange.com/questions/161734/why-does-oauth-and-oauth-2-have-access-tokens-at-all https://security.stackexchange.com/questions/161734/why-does... The token may as well just be an AUTENTICATION token, such as the app’s id with timestamp signed with the shared secret. (Or even better, an asymmetric private key, where the shared secret is replaced by TWO keypairs, one from app-to-platform and one from platform-to-app.) Then you use this app id to look things up in an Access Control List (ACL). Then stuff becomes easy. Forget all the oAuth crap. The app is just another user with an ID in your system. Users may grant access to other users, for different streams of data. The access can have various read/write/admin levels etc. It can be changed anytime. Finally, users can have LABELS (or Roles) which determine in one fell swoop what an app can do. That is similar to “scopes” in oAuth. I don’t just talk about it — this is how we handle it in our platform: https://qbix.com/platform/guide/access https://qbix.com/platform/guide/access
- deleted 8y ago[deleted]
- superasn 8y agoOne of the biggest advantages of JWT is that is saves up on database reads which can be significant when you have million+ logged in users. I think that is probably thinking of time when you had to do everything yourself (host your own mysql server, create indexes, cache, etc). Now you can easily save your sessions using stuff like DynamoDb.. it costs almost nothing and read times are blazing fast even when there are millions of rows. Doesn't make a lot of sense to use JWT after this.
- amenod 8y ago> Now you can easily save your sessions... True. > ...using stuff like DynamoDb.. Well, yeah, if you want to be tied to AWS and use a difficult to manage technology which is only useful in a few niche cases, DynamoDB is absolutely the right choice </sarcasm>. Otherwise Redis, Memcache or even Postgres would be a better choice. After all, session management is only a (small) part of data persistence problem.
- superasn 8y agoYes of course. That was not my point DynamoDb was just something off the top of my head. You can easily use redis or even any nosql db for that. My point was about the main advantages of JWT being fast with millions of users isn't really that big deal anymore.
- amenod 8y agoCool, sorry if I jumped the gun... I recently had to deal with some SW using DynamoDB for no special reason, so I'm a bit touchy about it. :)
- TekMol 8y agoAt first JWTs look cool because you can log in users without managing session data on the server. Then you think about how a user can actively log out. Then you add session management to your server but call it 'token invalidation'.
- andrewstuart2 8y agoThis is a problem you have with any federated token-based identity solution. Distributed logout is a hard problem which can basically be reduced to cache invalidation (insert N/N-1 hard things in CS joke here).
- tptacek 8y agoThis is a little like saying "this is a problem you have with ANY identity solution that looks like JWT". Yes, that's true. The reason people complain about JWT is that (a) it's the most popular solution of this shape, and (b) people use it without understanding why they're using it or whether the tradeoffs work for their application. They usually do not. Witness everyone saying that the important feature of JWT is that it's standard and interoperable, as if that was a mandatory feature of most token-based authentication schemes; in fact, the "portability" of JWT is a security liability for --- I'll hazard --- the overwhelming majority of applications.
- andrewstuart2 8y agoWould you say then that confidentiality is always preferable to availability? I'm not quite sure how you'd achieve any sort of high availability over time without interoperability at some level. Presumably, if it has any place, that interoperability would belong at the lowest level of a protocol stack, with each successive level tuning acceptable parameters for their application.
- tptacek 8y agoI don't understand this question. I don't think it's very common in real-world applications to deliberately trade confidentiality for extra availability, though negligently and subtextually making that trade is endemic to our industry.
- kevinburke 8y agoLast year I helped several different companies switch off of JWT onto JSON encrypted with secretbox, which was much more appropriate for their use case(s). No risk of accidentally using an insecure algorithm or sending secure data unencrypted to the client. Local storage is not secure.
- B-Con 8y ago> Note: Yes, both these methods are synchronous. But, given that neither of these methods require any I/O orNetwork requests, its pretty safe to compute them synchronously. Found this amusing. Are node devs so used to async that disclaimers like this are necessary?
- kevinburke 8y agoyes, Node is single threaded so any one thread that blocks the event loop for a significant amount of time becomes a significant performance bottleneck. Generally functions like bcrypt require an asynchronous API.
- firemelt 8y agoIs it safe to put jwt in local storage?