11 ms·
Why JWTs Suck as Session Tokens (2017)
- blattimwind 8y agoBesides various other issues (design and implementation-wise) and the fact that it's a useless optimization anyway, minting tokens is just such a headache in general. Avoid it entirely if at all possible. If you think you need JWTs or similar tech, you don't need JWTs or similar tech.
- _sdegutis 8y agoEDIT: I misunderstood what was meant by minting tokens, my entire comment is pointless. Save yourself the time. What's the headache about minting tokens? You create a new uuid() on the server, store it in the DB in its own table which has references to accounts, keep an isValid field next to it for server-side invalidation, and store it in localStorage in the client. Is there a security flaw or something in this?
- blattimwind 8y agoSo you've minted a token, stored that in the DB as well, and every time you see that token you verify the signature and then you look the token up in your DB to see if it's still valid. You do realize that at that point you could've just handed out a random string instead and avoid (1) creating and verifying signatures and (2) the size inflation created by those signatures, because you're not even getting any of the theoretical advantages of minting tokens.
- _sdegutis 8y agoIt is a random string, I just created it with uuid(). Nothing was ever verified. Is minting tokens an official term that has to do with JWT? I thought it was just short-hand for the process I just described.
- blattimwind 8y agoMinting tokens specifically refers to JWT-like constructions AKA "[probably-RSA-]signed cookies". Generating a sufficiently (16-32 bytes) long string of randomness and using just that as a session ID stored in a database is a perfectly fine technique, scales well enough and is quite hard to get wrong.
- ad_hominem 8y agoIf you're just handing out the random string without signing it (or performing some other constant-time comparison when validating), you're vulnerable to timing attacks
- tebruno99 8y agoWhen you hit a critical size your database can no longer handle the throughput of the lookups. You'll then install memcache or some other tech and the stack JUST FOR handling the tokens is a majority of your datacenter load. Most startups and projects never hit this size, they usually fold before that level of growth. It is much lower than one would assume though since every request made to an API has to do the lookups etc.
- blattimwind 8y ago> When you hit a critical size your database can no longer handle the throughput of the lookups. If your data store(s) can't handle the load of looking up a ~32 byte token (that is, if you are sane and not using JWT), then how exactly are they supposed to hold up to whatever your business logic part of the app is doing?
- randomdata 8y agolocalStorage can be vulnerable to XSS attacks in cases where cookies are not.
- pram 8y agoYou can put a JWT in a cookie :V
- 11235813213455 8y agobut then it's not a http-only cookie, so same problem
- jondubois 8y agoOMG, where do people get this info? It's BS. As an attacker, if I have successfully injected my JavaScript code into your webpage, I can make HTTP requests on your server to do whatever I want with that user's account (their cookie containing their Session ID will automatically be attached to those malicious requests; so they will look like real requests from that user). And yes, this attack also works with httpOnly cookies; I don't need to be able to read the cookie in order to use it. The httpOnly flag is practically useless; I don't think any hacker worth their salt would want to steal session IDs for later use (session IDs and JWTs have a way of expiring quite quickly); usually with an XSS attack, you want to do the attack in-place from inside the victim's own browser.
- bobberkarl 8y agoWhat would you recommend then?
- blattimwind 8y agoRead some bytes from /dev/urandom to hand out as a session ID and put them in a database.
- nickthemagicman 8y agoThought this was the panacea for serverless authentication
- mothsonasloth 8y agoI have used JWTs only for mobile sessions. Else I opt for the gateway pattern (a service handles authentication and then forwards requests to other microservices).
- unquietcode 8y agoThis is ridiculous. It's 2018 and you're complaining about a few MB of bandwidth and a few seconds of CPU time? The whole point of JWT is that they are basically cookies for places where using cookies uniformly is not feasible. The author's solution is to go back to using cookies, which just doesn't work well enough. I'll stick with tokens for now thanks.
- cwyers 8y ago> It's 2018 and you're complaining about a few MB of bandwidth Ah, yes, 2018, the Year Where Everything On The Internet Is Connected To A Cable.
- lostcolony 8y agoIt's 298 bytes per page request given the example he gives (your token can be smaller or larger depending on the data in it). It's 24 MB of bandwidth to the -server-. Your server -better- be behind a decent broadband connection, or what are you even doing? 1/3rd a kilobyte per page request to the -client-. 1/3rd a kb is a blink of an eye even on modern dialup.
- pythonaut_16 8y agoIn this case the article is talking about 24 MB of additional bandwidth used by the server to serve 100k pageviews using JWTS
- neop1x 8y agoWhy do you think it has to go skyrocket forever?! I am already really disgusted by how big applications are nowadays, how bloated, slow, memory-hungry and inefficient they are. Every saved MB counts.
- Mister_Snuggles 8y ago> ...a few MB of bandwidth and a few seconds of CPU time Many people are on cell phones with low data limits. A "few MB", let's say 3MB == a few, represents 0.1% of someone's data limit. Sure, it's not that much on its own, but it adds up. Likewise, a few seconds of CPU time is fine if you're on the latest iPhone, but if you're in a developing country on an inexpensive Android phone that few seconds of CPU time is going to turn into a world of hurt. This cavalier attitude towards bandwidth and CPU time is outright hostile to certain classes of users.
- wolco 8y agoVery weak reasons for not using jwt. If 24 megs a month is the reason you could easily remove an image from a high traffic page to get the sake savings. You are hitting the database anyways reason applies to a limited subset of of use cases. Sessions are simplier use them on multipage websites. SPA or apps jwt is perfect.
- have_faith 8y agoI like to keep things lean where I can, but saying I have to pay 24mb per 100k requests doesn't sound like a huge deal. And like you say, keeping an eye on your image sizes will net you much bigger savings.
- joaomsa 8y agoHow to people usually get around file downloads and initial page loads with JWTs (besides signed urls), since you can't control and preempt these requests to also send the JWT?
- faitswulff 8y agoComments ITT are not particularly charitable. The author says: > It’s important to note that I don’t hate JWTs. I just think they’re useless for a majority of websites. ...and lays out a nuanced perspective of when they're an improvement over cookies at the end.
- gramstrong 8y agoI think anyone who gives an article the now cliche "Why [popular thing] sucks" doesn't care about receiving charitable responses. His use case at the end is describing microservice architecture. Microservice architecture is trending, ergo JWTs are trending. I don't see the problem.
- AndrewSChapman 8y agoI've read several articles along these lines now I tend to think the arguments are pretty weak. In this media rich age, the data size argument is a bit silly. The "you're going to hit the database anyway" argument whilst probably accurate in most cases, doesn't invalidate that JWT allows for one or more fewer database hits on every request. Having built-in integrity checking is definitely a feature. Just because you can do it without JWT doesn't mean that it's not useful that JWT does it. IMHO the biggest argument against the use of JWT is that you can't easily invalidate JWT sessions. Should you need to dump a users session or if the information contained in that session token has become invalid then you might be in trouble. For my use cases so far however this hasn't been a problem. JWT is a fine solution for quite a lot of use cases. As with everything tech, just be aware of the limitations and choose wisely.
- kodablah 8y agoI concur with the author about session usage of JWT since it has little value (and if you did, just use it for it's signing feature and still have it just contain a random session identifier). The reasons for defending it in that use seem to be about what's not bad, but rarely about what's good. But JWTs have value for API tokens as they can embed an expiration date for the caller in a known format. But the idea of stateless JWTs with a bunch of valid data for use on successive calls by the server is a bit much. You should contact your auth store of record per invocation for various reasons. Like you said, be aware of the issues with chosen sig algorithms and be exact on what you choose and just leverage JWT as the format, not blindly following the generation libraries without investigation.
- madeuptempacct 8y ago"about session usage of JWT since it has little value " Two weeks ago, I stood in front of a room full of senior developers and architects and asked them "How will we avoid making a leading 'Does the user have permissions?' call or wrapping the request in a try catch in case the user doesn't have access without JWT claims. They all got mad. Then they conceded that they don't have a solution. Do you have a solution? If not, you can't replace JWTs.
- sologoub 8y agoThe unencrypted nature of these is something that gets overlooked a lot of times. If you are transmitting metadata about some item, such as a song or a video, that’s one thing, but when it’s user info and the payload is not encrypted, you end up essentially leaking that data. Other issues arise when you throw in logging and crash reporting - you may not even realize that that JWT session token just got logged and now you have user data where it doesn’t belong.
- donatj 8y agoThe offered solution to use a centeral memcache/Redis server is exactly why we moved to JWT. First memcache and then Redis sessions were a continuous centeralized source of failure we could remove, and honestly didn’t scale very cleanly approaching millions of users. Removing moving parts from our stack was a major win. That’s not to say JWT is without thorns, but overall it’s better than a centeralized point of failure.
- gm-conspiracy 8y agoI am curious about your experience with Redis and millions of users...what were the issues you experienced?
- donatj 8y agoIn particular we weren't storing a ton per session, but were having to spin up more and more instances or suffer port exhaustion. We go from about 25,000 request a second during the day to 200 at night, and there was no good way we could find to autoscale it. We scripted the build up process based on time and sometimes it wasn't meeting demand. It was taking a lot of devops time. I'd had an experimental fork of our application using JWT floating around for a while and my manager made it a priority. It's never needed any maintaince and had been a real improvement for us.
- swlkr 8y agoI learned this the hard way, and a whole host of other lessons trying to ship side projects as fast as possible alongside a full time job.
- jondubois 8y agoYou learned the wrong lesson.
- lainga 8y agoI couldn't get a clear answer out of the article: is the author for or against JWTs for authentication purposes?
- lossolo 8y agoThe main and only argument against JWT tokens for me in context of user sessions is that I cannot revoke them if I block user account.
- Declanomous 8y agoWell you can block them, it just means you lose advantages of a JWT, like not requiring a database hit.
- lossolo 8y agoThis is the main issue, there is no point in using JWT tokens for me in context of sessions. I can just use standard solution and keep normal tokens in Redis if I need to make db call anyway.
- epicide 8y agoHave a relatively short expiration time. Or, if you want to have more immediate revokes without having a ridiculously short expiration time, keep a list of blacklisted tokens that you clear at least every <refresh time> seconds. At the end of the day, JWTs still have to be accepted by the server, which you have complete control over.
- lossolo 8y agoI can't run short expiration times. Well, If I am running distributed system then blacklisting dosen't solve anything for me. I would need to sync blacklists or keep them in database which defeats the purpose of using JWT for sessions already, as I could do what I do now, just keep normal tokens in Redis and check them on every request.
- Polyisoprene 8y agoAssuming blacklisting happens infrequently, you would have a few orders of magnitude fewer entries and could keep them in-memory on each server and have them fetch them all once every X seconds instead of for each request.
- _em6m 8y ago"it's going to be 304 bytes (...) instead of 6 bytes!" O...M...G... I mean... Let me check again what year it is. Please stop writing bullshit just because you can have a blog for free...
- phyzome 8y ago« If we store the ID in a cookie, our total size is 6 bytes. » No. What? No. You can't compare a signed JWT with a bare user ID. The proper comparison is a signed JWT vs. a cryptographically random session identifier with sufficient entropy. It's still smaller than the JWT, pretty much by definition, but make the right comparison, please.
- lostcolony 8y agoHe -does- indicate "For storing a simple user session, that is a ~51x size inflation on every single page request in exchange for cryptographic signing (as well as some header metadata)." So he admits that the signed part is the tradeoff. But I totally agree with you, barely mentioning that, when that's the whole point (JWTs are used for authentication/authorization, not just easily faked identification), is incredibly disingenuous. Never identify users on the client side with something that isn't cryptographically secure. Somewhere, you or another developer will end up implicitly believing that ID is trustworthy, and you just introduced a critical security flaw.
- phyzome 8y agoA pretty common approach is to just give the user a version 4 (random) UUID as a session ID, which is 36 bytes in standard format. 304 / 36 = 8.4x, which is a much less impressive inflation.
- jondubois 8y agoI've read so many of these anti-JWT articles, and I don't think I've ever come across a single reasonable complaint against them. What is wrong with people? I've even read security reports by supposedly reputable security consultants also claiming that JWTs are bad but their arguments are hand wavy and make no sense. >> Let’s say that your website gets roughly 100k page views per month. That means you’d be consuming an additional ~24MB of bandwidth each month. Negligible. >> You’re Going to Hit the Database Anyway Yes, but less often. So your DB will be able to service more users overall. For some use cases, we're talking orders of magnitude more users.
- danenania 8y agoInability to do immediate revocations is a real drawback and a valid complaint. If a trusted machine with a privileged token on it is compromised somehow, it will likely take the attacker some time to search for and discover the token. If you use centralized auth and you realize there was a breach before this happens (say from monitoring/anomaly alerts), you can revoke the token and prevent unauthorized access. If your token is JWT and it doesn't expire for another 45 minutes, you're in much worse shape. This isn't the only factor to consider, but it's an important one.
- mathnmusic 8y agoInability to do immediate revocations comes with all stateless, signed tokens (for eg: the way Rails uses cookies). I don't understand why JWT gets the bulk of these criticism when signed stateless cookies are quite prevalent.
- CiPHPerCoder 8y ago> I've even read security reports by supposedly reputable security consultants also claiming that JWTs are bad but their arguments are hand wavy and make no sense. https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ https://auth0.com/blog/critical-vulnerabilities-in-json-web-... https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html https://blogs.adobe.com/security/2017/03/critical-vulnerabil... These were critical vulnerabilities enabled by an error-prone cryptographic design that broke real systems. Don't pretend it's hand-wavy.
- coolMeme 8y agoWow, such cool meme faces. So glad I read that.
- InTheArena 8y agoNot a huge fan of this article (despite being a huge fan and consumer of Okta). The author is making a number of assumptions that are bad architectural practices these days. These include: 1) Stateful services everywhere (assuming you always have a database) 2) That you are only doing interactive sessions, and not web services 3) That you have a single issuing authority that is non-federated For stateful CRUD applications that don't need to scale, and have a centralized authority, by all means, use session cookies. If, on the other-hand you have a application that needs multiple authentication sources, has a API on the other end that doesn't want to know a separate authentication path, or run stateless functions, JWT is a fairly good choice. For most modern applications, session cookies create far more problems then the simple universal decision to use JWT across the board.
- clhodapp 8y agoWith http 2, repeatedly sending the same header value over a persistent connection should cause just a pointer to the previous value to be sent so I don't really buy the size argument here.
- istvanp 8y agoOne of the biggest downsides in my opinion is that session invalidation becomes non-trivial. Your best bet (assuming you don't want to do any additional network requests) is to reduce the session length to the smallest amount you (or users, depending) will tolerate and perform some kind of re-authentication; i.e. force a logout and do a fresh login or check if they can get a new token based on the old one transparently. For example, a user changing their password should kill all tokens that are in use immediately for good security. You can't do that with JWT. All tokens will stay valid until they expire.
- deleted 8y ago[deleted]
- imtringued 8y agoI haven't used JWT but the way you solve this is by having a refresh token that lasts several days that lets you "login" without a password. The refresh token is then used to get the real session token with has a low expiration, perhaps 5 minutes. When the session token expires you just "login" again. But honestly I don't see the need for the vast majority of applications. Most frameworks cache the permissions, etc on login so the database doesn't have to be accessed on every request.
- drinchev 8y agoBiggest complaints about JWT is the inability to sign out a user. You can, yes, delete the cookie on the client side, but if the JWT is stolen you can’t be sure that it won’t be used again ( invalidate ). Same happens on reset password, where by the book you need to sign out the user from every device. Good luck with that having standard JWT implementation.
- pkulak 8y agoIf you have your tokens take more than an hour to expire, you're doing it wrong.
- drinchev 8y agoRefreshing a specific token can not be blocked on the server side. If you do, it’s already stateful.
- pkulak 8y agoIf that's the case, then why refresh? Might as well just hand out forever tokens, which, you're right, makes less than zero sense. The point is that you have two tokens, one a refresh token and one a stateless token. You revoke the refresh token on the server, which means the next refresh attempt will fail.
- ortekk 8y agoThen why not just use "refresh token" as a session token?
- pkulak 8y agoBecause it's stored and that would require a round trip to your auth server on every request. Plus, its security requirements are far higher than the access token, so you don't want to be flinging it all over the internet. It only ever goes between your users and your auth server.
- hakanito 8y agoJWTs are good for a bunch of things, one example being when you do NOT want to hit the database on every request, to speed up latency.. eg. in high-throughput IoT setups where you want to validate or discard the request before touching any DB at all
- daveFNbuck 8y agoMy employer just started using Okta and I find it hard to take anything they say about security seriously after seeing some of the obvious bullshit in the immediate user-facing aspects of their product: - allowing security questions to reset passwords - allowing sms resets of passwords - allowing sms 2-factor in combination with sms resets I understand that my company is largely at fault for enabling these, but it's scary that they're even options. It's also pretty stupid that their password requirements are 8 characters, mixed case, and at least 1 number.
- devicenull 8y agoPW requirements are defined by your company as well.
- daveFNbuck 8y agoNow I'm even more disappointed with my workplace :(
- jf 8y ago(Disclaimer: I work at Okta) One thing I've learned at a visceral level is how different threat models are from one organization to the next. And while I agree that the things you brought up don't meet my personal standards for security, there are many organizations where those features are acceptable given their use case.
- daveFNbuck 8y agoUnder what threat model do you need 2 factor authentication but it's ok if both factors can be bypassed by SMS? There may be some legitimate use cases, but I don't think companies that need to farm out their security to a third party will usually be in the best position to make this call.
- jf 8y agoAs I recall, for some consumer facing applications, the concern isn't about targeted attacks, but more about automated attacks that try to re-use passwords. In a scenario like that SMS is to slow down automated attacks. Keep in mind that I don't endorse that approach! Just giving an example of a narrow case where that applies. That said, I appreciate your feedback and will personally take your feedback to our product group.
- peterwwillis 8y agoThe reason why you should limit cookie sizes is request round trip. A typical GET request involves multiple headers, including cookies. Cookies are sent for every request for any resource for a given domain. The more cookies you have, and the bigger they are, the bigger your request. The bigger your request, the more likely it is to take longer to send and receive it. The more of them you send, the more latency accumulates. When The Cookie Crumbles https://yuiblog.com/blog/2007/03/01/performance-research-part-3/ https://yuiblog.com/blog/2007/03/01/performance-research-par... Reduce Cookie Size https://developer.yahoo.com/performance/rules.html#cookie_size https://developer.yahoo.com/performance/rules.html#cookie_si... Performance Limits https://stackoverflow.com/a/6963585 https://stackoverflow.com/a/6963585
- malodyets 8y agotldr; JWTs are a premature optimization (and are often a de-optimization) in the context of user sessions. That's all the writer is saying, and I think he said it quite well.
- neop1x 8y agoYes. It simply doesn't "solve" a particular "need or problem". It just tries to be a fancy modern alternative to tokens not really solving anything.
- tialaramex 8y agoThe model the author is complaining about is far too widespread unfortunately. I've seen a much worse incarnation at a huge corporation that I won't name but whose identity sleuths can doubtless figure out. Here's how this goes: When a user authenticates, the system sends them a public key encrypted blob inside a cookie. When the user makes further HTTPS requests the blob will be sent back, the system can decrypt it with the private key and get back the data inside. Components of the system would squirrel away per-user data inside this blob and so the cookie might get updated as they surfed around the site or did things. One day, people behind a local component using this contraption asked me for some "advice". They'd "filled up" the blob and there didn't seem to be a way to add more data but they needed to store something else, I worked for a different part of the company but I knew about cryptography, what should they do now? They'd found that there didn't seem to be a "cipher mode" option for public key cryptography... And so that's the point where I couldn't decide whether to laugh or cry, after that I spent a few hours on international conference calls basically telling people that they're idiots and nobody should have even _designed_ this let alone built it. Part way through that I explained that encryption doesn't magically mean bad guys can't change the inside of the blob AND that it doesn't magically prevent bad guys from stealing blobs they found in one place and using them elsewhere. So what is this even for? In mitigation the engineers who built it explained that, er, actually the first thing they do with the blob after decrypting it is to check their session database to ensure all the data matches up, if not it's invalid and the user just gets logged out silently. Thus, at the end of the day, it's just functioning as a session ID checked against a database anyway. All this cryptographic effort is in fact completely wasted and achieves nothing in practice except to make the system far more complicated and fragile. Brilliant. /facepalm
- aaaaaaaaaab 8y agoSounds like a good way for job security.
- JepZ 8y agoWell, one argument against cookie based sessions is that they get send automatically which opens a large attack vector for CSRF. (yes, you can store JWTs in cookies too, but that is kinda uncommon)
- mythz 8y agoStoring JWT's in a HttpOnly Secure Cookie is common and recommended for Web Apps. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage#where-to-store-your-jwts https://stormpath.com/blog/where-to-store-your-jwts-cookies-...
- crazy5sheep 8y agoReally, why ppl keep saying JWT cannot be invalid? isn't it simple enough to use a redis bitmap to store the info? each token only takes one bit, how many tokens you can have, 1 Billion? 120MB is more than enough. What you save here is the time and resource you hit the database.
- blattimwind 8y agoIf you have a revocation list for JWT tokens, you could just as well just use session IDs, avoiding all issues with JWTs.
- crazy5sheep 8y agoBut you can not store anything in your session ID. JWT can carry a small amount of data that's need by my service. I only need to validate JWT and check if it's been invalidated. Then I can go ahead to perform by business logic. I don't want to hit db to get all these data. Yes you can argue why not just store them in redis too, but with JWT I only need One bit.
- deathanatos 8y ago> In fact, in most web authentication cases, the JWT data is stored in a session cookie anyways, meaning that there are now two levels of signing. One on the cookie itself, and one on the JWT. This sounds like a bug in someone's implementation of JWTs; most JWTs are not signed twice. It's thus not a valid criticism of JWTs. > If you’re building a simple website like the ones described above, then your best bet is to stick with boring, simple, and secure server side sessions. Instead of storing a user ID inside of a JWT, then storing a JWT inside of a cookie: just store the user ID directly inside of the cookie and be done with it. This is conflating two very different things. Sticking with boring, securing server side sessions… sure (though we're eliding how one would actually implement that, but let's assume it's by sending a sufficiently long, unguessable token in a cookie) but then we continue with "just store the user ID directly inside of the cookie" — no! The point of the JWT is the authenticate the user; just sticking a user ID into a cookie doesn't do that; the user could just change the ID in the cookie to whatever, and be done with it. I'd hope the author means "stick the user ID into the session-side storage" (that's associated with the client in some means, likely by an unguessable token as mentioned earlier), but earlier in the article we make the same mistake: > If we store the ID in a cookie, our total size is 6 bytes Except, no, you're going to need to store that server-side, and send a token, which will realistically be 16 bytes, not 6. The comparison mostly still stands, since there isn't a significant difference between 6 and 16 bytes. > For storing a simple user session, that is a ~51x size inflation on every single page request in exchange for cryptographic signing (as well as some header metadata). It's not a 51x size inflation on every request. That datum is 51x larger, but the request itself includes plenty of other things. This concern will diminish greatly as HTTP/2 is adopted, I think: HTTP/2 is capable of compressing headers, but in addition to that, multiple requests sending the header can essentially say "let's call this header header #1 and then reference it w/ that number on subsequent requests, greatly reducing the transfer required for common, repetitive headers. If you're on AWS, ALBs support it, so it should be very accessible for most folks w/ browsers. (Client-side programming libraries are another thing, but it'll get there.) > You’re Going to Hit the Database Anyway The point is that you can hit the database one time less; yeah, you might need the user object, but you might not. But the suggested alternative of using server-side storage requires a DB lookup in addition to looking up the user object: we've got to first translate the session token in the cookie into a user ID, and then from there get the user object itself. (Perhaps you can, in some cases, JOIN these if you're using a relational DB; but it still bites you if you don't need the user object, and even if you do, the additional disk read isn't going to be faster than checking a signature. If you're putting just the user ID in the cookie, and signing it, you're just re-inventing JWTs. Perhaps you'll save a few bytes, but you lose out on what are hopefully more robust, feature complete libraries, and a common, familiar format.
- throwme_1980 8y agohow is this even at the top ? has anyone actually read the content
- lvh 8y agoWe see JWT a lot. It's usually an accident and not really solving a problem. Some notes for this blog post: - It does not cover the worst issue with JWT (IMO): you don't get revocation by default. Some vendors use JWTs and still have revocation, but they do this via CRL management. CRL management is not easier than a session in a database. - In the context of OAuth2, JWT is often a bearer token. This introduces a number of subtle flaws that OAuth1.0a did not have. Notably, in OAuth 1.0a, if I steal your credential for service X, I can't do anything with that without also having service X's credential. In OAuth2.0, it's a bearer token, so game over. You could argue this is an OAuth2.0 flaw -- or perhaps not even an OAuth2 flaw, because OAuth2.0 doesn't force you to do this. But OAuth2 and JWT make it the obvious choice, and so this model is now ubiquitous. - It uses the phrase "signing" a lot. In JWT, signing usually means MACing, specifically with HMAC-SHA256. in other contexts "signing" often means using asymmetric cryptography: a separate verification and signing key. JWT supports both -- because JWT, in its folly, supports everything.
- DannyBee 8y agoMost people here seem to fail to understand that apps rarely get slow and bloated through a single decision. It is tons of 1% or 0.1% decisions. Reading arguments here that this decision doesn't matter for size reasons, decoding performance, etc, is silly. You can argue the same thing about any of the other 100 individual decisions that, in the aggregate, made your app slow and bloated.
- deleted 8y ago[deleted]
- jsd1982 8y agoThe size argument ends up being dominant when storing JWTs in browser cookies because cookie storage size per domain is seriously limited. I know Chrome limits total cookie storage to 4kb, including cookie names.
- asimpletune 8y agoCouldn’t this just be an argument against session tokens in general? I don’t think I saw anything negative mentioned about JWT that wouldn’t be true for any session token. I guess you could design a binary-first token format that’s smaller than JWT, that’s true.
- ajsharp 8y agoThat was a whole lot of chewing for very little meat. If this article were a tweet, it could've been "use cookies instead of JWT's bc is if all you need is a UUID for a database lookup cookies work just fine, and are prob encrypted using symmetric encryption just like JWTs." Respect to the author for trying to generate some content for the company blog, but the end result ultimately comes down to a relatively trivial decision in order to save a few bytes.
- tptacek 8y agoThe one example this author gives for an appropriate use of JWTs isn't really any different than his previous ("bad") examples. In it, he suggests the case of an ensemble of services coupled to an authentication service, with an SPA front-end. The front-end obtains a JWT from the auth service and uses it to make API requests of the rest of the ensemble. Because the requests are "small" and "frequent", there's a savings to be had in using stateless authentication for them. But SPA applications (and, for that matter, classic AJAX applications) have been making small, frequent API requests for 15 years. There is a standard solution to the problem of repeated session database lookups: caching. And in the unlikely instance of an application with significant enough usage that session lookups are problematic but no preexisting caching strategy, the standard answer here is simply to move sessions to a fast lossy database like Redis. All the previous problems with JWTs remain in play in the author's "good" example. There are better reasons to avoid JWT than are provided in this article, but it does a fine job of communicating the fundamental nut of the problem. You can easily do better, both for performance and for security, than JWT does. Chances are, your framework's existing session store already is better than JWT. Rails, for instance, has had stateless signed cookies for something like a decade. We recommend you avoid JWT. If you want to be cool and use a non-default session token format, look into Macaroons.
- mst 8y ago"Look, if you just store the user id in an unsigned cookie it's only 6 characters." Um. Yeah. Also completely insecure. I know he mentions signed cookies shortly afterwards but the way that part of phrased seriously made me twitch, especially coming from an auth provider's blog.
- neop1x 8y agoVery good point, thanks for the writeup. Maybe JWTs are good for specific cases but as most people relally use DB for other stuff anyway, it doesn't really bring up any practical advantage. They are just "cool" and look clever so people probably started using them without proper reasoning. This resembles NoSQL and an attempt to burn oldschool SQL servers with hopeless attempts to go back later where more complicated "join-like" requirements emerge.