17 ms·
Things to Use Instead of JSON Web Tokens
- sergior 9y agohey, author is missing the bit where you can disallow client to choose the algorithm. No need to read the rest...
- mrighele 9y agoIn some way he addresses that towards the end: > It's important to note that my experiment is not JWT. > When you reduce JWT to a thing that is secure, > you give up the "algorithm agility" that is a proud part > of the specification. I don't agree with him though, unless the standard requires to implement all of the available algorithms, one may choose to implement only those that he/she deems safe/worth.
- theprotocol 9y ago>I don't agree with him though, unless the standard requires to implement all of the available algorithms, one may choose to implement only those that he/she deems safe/worth. Agreed. I view this flexibility as a developer feature, not a client feature.
- kobeya 9y agoCorrect. Let's say you implement RSA2048 and server-side reject all other algorithms. Then during a security audit the crypto guy points out that RSA2048, while not broken per se, is not up to the generally-accepted 128-bit security threshold. You should use RSA-3078+ or switch to ECDSA. You decide to switch to ECDSA for the space savings. But what about all the deployed clients? Well since it's not actually broken, you continue to accept RSA-2048 for the next couple of years until something else permanently breaks support for old clients. Supporting client-specified algorithms lets you do a safe, phased-in upgrade without breaking compatibility or any fancy engineering.
- kevinburke 9y agoThe spec requires you to implement the "none" algorithm IIRC.
- mrighele 9y agoFrom a cursory read from the specs [1] I can see the following (Chapter 7.2): > Finally, note that it is an application decision which algorithms may > be used in a given context. Even if a JWT can be successfully > validated, unless the algorithms used in the JWT are acceptable to > the application, it SHOULD reject the JWT. From what I understand from the above, the server side can decide to _always_ reject the "none" algorithm and still qualify as a valid implementation. The fact that the "none" algorithm is implemented or not by the library becomes a detail. [1] https://tools.ietf.org/html/rfc7519 https://tools.ietf.org/html/rfc7519
- cappie013 9y agoExactly what I was thinking while reading the article. I'm using JWT for an API, and the server is choosing which algorithm to chose. Really don't understand why a client should bypass server.
- theprotocol 9y agoYou could even hit 2 birds with 1 stone by going with headerless JWTs (just strip the first segment).
- Freak_NL 9y agoKeeping the JWT format as-is is useful if you have signed (but not encrypted) tokens though; in a web browser you can use standard libraries to inspect the token and alter the UI based on a user's permissions (the final check is always the API's responsibility of course, but if there is no need to show the 'admin' link the client can do that).
- theprotocol 9y agoIf it isn't encrypted, the only thing the client needs to know is that it's base64 encoded in order to inspect it. You'd need the secret to verify the signing and you probably shouldn't have that on the client-side! So I still think the header is superfluous even for this use case. edit: in fact, the client needs to know that it's base64 encoded to even read the header in the first place.
- vertex-four 9y agoSymmetric signing is not, by far, the only use case for JWTs. Asymmetric signing, and encryption, are also well-specified and supported.
- theprotocol 9y agoGood point! It slipped my mind.
- ksri 9y agoI maintain a spreadsheet of the pros and cons of various authentication techniques - https://docs.google.com/spreadsheets/d/1tAX5ZJzluilhoYKjra-uHbMCZraaQkqIHl3RIQ8mVkM/edit#gid=0 https://docs.google.com/spreadsheets/d/1tAX5ZJzluilhoYKjra-u... JWT is extremely useful when you want a one-time use token to pass a claim to another system. For example, employee portal generates a link for a user to check their available leaves in the HR system. Since the user is logged in to the employee portal, they shouldn't have to login to the HR system. JWT is great for this use case. But for general sessions management, there are better solutions.
- vetinari 9y agoThe use case you mention is exactly the reason, why we have SAML2 and similar SSOs.
- wichert 9y agoIt appears to be much, much simpler to just integrate JWT into your system than deploy a SAML identity provider. I would love to see an easy to deploy decent SML IdP, but so far I have not found one. If anyone has any recommendations I would love to hear them.
- brazzledazzle 9y agoIf you're looking for a self-hosted solution I can't help but as far as a provider goes we've had decent success with Okta. Of course SAML kind of sucks no matter how you slice it and Okta seems to think the future is in standards like openID connect.
- sytringy05 9y agoThey dont exist! IMHO ADFS is actually the best of a bad lot. Your friendly Windows Admin can setup the SSO in a matter of minutes without having to know the spec inside out and upside down. The other platforms I've used or integrated with - Tivoli, Layer 7, Ping Federate, a huge hack job written in PHP - all took weeks/months to get working. That said I haven't tried Spring SAML recently, so maybe that is painless now. But probably not
- retrogradeorbit 9y agoThis is acronym heavy. Author needs to specify in the opening which JWT he is talking about. Java Web Toolkit? or JSON web token? It took me a fair amount of reading to work out which one he means. And even them I'm only pretty sure he means JSON web token, but I can't be sure because the Java Web Toolkit also connects to servers, and uses encryption, and all the other stuff he talks about.
- gant 9y agoPeople still use Java Web Toolkit? Okay, dumb jokes aside, they're clearly talking about alternative ways to authenticate, so I wouldn't know how you could conclude this was about anything but JSON Web Tokens.
- retrogradeorbit 9y agoPeople still use Cobol, mate. Just specify in the first sentence what you are talking about as full words. Is it that hard? Apparently it is.
- coldtea 9y ago>People still use Cobol, mate. Which makes sense. It has been a historically succesful language that served well for decades. JWT wasn't even good when it was new.
- deleted 9y ago[deleted]
- hdhzy 9y agoUsually people using the acronym daily process it as a single concept not even consciously thinking it's a compound term. Look at yourself: you used "Cobol" instead of "common business-oriented language" [0]. [0]: https://en.wikipedia.org/wiki/COBOL https://en.wikipedia.org/wiki/COBOL
- martin-adams 9y ago
- gant 9y agoOh hey, it's another "JWT libraries used to be terrible" article. Idiots shouldn't write authentication code. Especially when credentials are involved. Funny jwt-go was used as an example; it was never vulnerable to the alg-none attack: https://github.com/dgrijalva/jwt-go/commit/2b0327edf60cd8e04d7ee6670b165c9580a42392 https://github.com/dgrijalva/jwt-go/commit/2b0327edf60cd8e04...
- kevinburke 9y agoI cover this point in the article
- developer2 9y ago>> it's another "JWT libraries used to be terrible" article Dead on. Sure, some early JWT implementations were poor... during the first few months that JWT was gaining traction. That was over 2 years ago. You may as well write an article about how Internet Explorer is awful, while referring to qualities present in IE 6. Disclaimer: I still dislike IE/Edge, but no longer have pertinent reasons as to why I maintain that opinion. There is not a single valid criticism of JWT from a security perspective. The only criticism outside of security considerations I'd view as valid is that the length of the strings quickly becomes bloated for the amount of information contained within (ie: inefficient bandwidth and storage usage, the same complaint as with long cookie headers requiring more TCP packets).
- kevinburke 9y agoUsability and implementation errors are security errors http://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html http://blogs.adobe.com/security/2017/03/critical-vulnerabili... see the "X.509" section here https://www.npmjs.com/package/jsonwebtoken https://www.npmjs.com/package/jsonwebtoken https://twitter.com/bcrypt/status/583070541336195072 https://twitter.com/bcrypt/status/583070541336195072
- Freak_NL 9y ago> The problem with JWT is the user gets to choose which algorithm to use. Only if you completely bungle the implementation on the server-side. The 'none' 'algorithm' isn't supported by up-to-date JWT libraries with a good track record, and you should always limit the algorithms you'll allow on the server. So if you sign your tokens with a RSA-2048 key-pair, you would discard any token that isn't using that algorithm. Of course if you are building an API that blindly accepts whatever it receives from a user agent you are bound to create a security gap — but that holds true for anything users send you though, not just JWTs. JSON Web Token is not that hard to grok, and it isn't a 'foot-gun' technology (just practice trigger discipline — i.e., read the documentation). I'm a Java guy, so I'll limit my experience to the libraries available there, but of the four Java libraries available, three provide strict validation of the signing algorithm out of the box, and explicitly document this in their examples and documentation (I think the fourth does too, but I haven't tried that one myself). JSON Web Token is a neat standard that has a lot of good parts that can reliably be used to create and process authentication tokens. So if you are still worried about developers getting it wrong, then instead of saying 'don't use JWT', why not promote a safe subset of the specification instead and promote that? Call it 'iron-jwt' or something. It beats rolling your own solution. Or if you want to be particularly constructive and feel that developers are misusing this technology, write a sensible, short, to the point implementers guide for using JWT and spread the word.
- gant 9y agoOP literally just deleted a bunch of files from the repo and then went out of his way to break compatibility with normal JWT HS256 tokens by changing the typ and removing the alg argument. If you wanted to pull out other algos from jwt-go, deleting their implementations would've been entirely sufficient. There is a map that holds a alg-string to implementation that would've ended up with only HS256. Instead OP made sure these tokens can't be used outside their fork, and thus only in Go. ISHYGDDT.
- skrebbel 9y ago> ISHYGDDT For readers like me, this means "I seriously hope you guys don't do this."
- cheerioty 9y agoHuh? The alternatives listed make me wonder if the author actually knows what JWT is being used for.
- jlebrech 9y agosessionstore and give your client a cookie.
- jlebrech 9y agoJWT is just storing more info than you would with a cookie but pretending it's secure by encrypting it with an algorithm the browser has access to.
- rhinoceraptor 9y agoJWT are not encrypted, they include an HMAC signature to prove that the token claims (which are a Base64 encoded JSON object) have not been modified.
- alayne 9y agoJWT can be encrypted. https://tools.ietf.org/html/rfc7519#page-26 https://tools.ietf.org/html/rfc7519#page-26
- jondubois 9y agoAlmost all of the 'alternative' use cases mentioned by the OP are not what JWT was designed for. JWT was designed to authenticate users/entities by giving them a token which contains basic non-sensitive metadata about that user/entity. It's for authentication not for authorization. Sure, some implementations of JWT have had bugs in the past, but this hasn't been an issue for quite a while and it's definitely not an issue with the RFC itself. It's the same as if you blamed the TLS/SSL RFC for being responsible for the heartbleed bug in OpenSSL - It makes no sense. >> You might have heard that you shouldn't be using JWT. That advice is correct - you really shouldn't use it. This type of blanket thinking is dangerous. There are cases where JWTs are practically necessary and unavoidable. Whenever an extremist blanket idea like this catches on in this industry, it becomes a major pain to have to explain to people over and over why in THIS SPECIFIC CASE it is actually the best solution possible.
- Lukasa 9y ago> It's the same as if you blamed the TLS/SSL RFC for being responsible for the heartbleed bug in OpenSSL - It makes no sense. It makes some sense. Features are attack surface. Each extra feature or option your protocol enables is more code you need to manage. So careful decisions need to be made: just because you can easily specify a feature for many use-cases in your protocol doesn't mean you should, because once you spec it people might just use it. For heartbleed, for example, why was the TLS Heartbeat extension ever specified for TLS over reliable protocols? It serves no purpose: TCP has TCP_KEEPALIVE if that's a thing you need. But it was specified, and because it was specified it was implemented, and then it became attack surface that needed to be protected. It wasn't. So I guarantee to you that if RFC 6520 had been more restricted in scope, the Heartbleed attack would not have happened (or would have been a much more minor story, I can't remember if Heartbleed affected only the TLS and not the DTLS implementation).
- wvh 9y agoI've implemented some of OpenID Connect, "a simple identity layer on top of the OAuth 2.0 protocol". Combined with OAuth 2.0, it's one of those giant corporate specs (giant at least for security/crypto purposes) with way too many options so anybody can do anything with any algorithm and any kind of workflow. I wanted to go with a simple, minimal NaCl-based system but in the end did implement a lot of OpenID Connect in the hope it would make interoperability easier with existing client libraries. I don't want to write a client for each and every programming language other people in any related projects would want to use. That in my opinion is the value of something like JWT: you can tell people up front that that's the way they're going to get the user's ID data, no matter how much server or client implementations will be switched around. I feel that when faced with a spec like OpenID Connect and OAuth 2.0, it's not necessary to implement more than what is strictly needed. If you don't need all the flows and algorithms in your project, don't implement and don't accept them. The parts you implement should comply – why base it on a spec if you throw any interoperability out of the window – but don't waste months of trying to correctly implement all of a huge corporate spec if that doesn't make sense for the size of your project or organisation. Complete implementations might have value only if that's your main product and you need that line to sell it. I use JWT only as ID, not as session, allow only one server-chosen algorithm for signing, and rely on TLS for encryption. There's clearly a need for up-to-date "web-approved" standards to pass crypto-friendly data structures around – or maybe I'm just not familiar with any recent efforts. Normalising and serialising JSON is pretty error prone...
- qatanah 9y agoOne of the advantages in using JWT is that the verification is in the cpu level and not a lookup via disk. This may sound strange, but if you don't have a quick lookup cache or centralized cache, This would be a great advantage to use CPU.
- kevinburke 9y agoThis is not a cryptographically sound argument
- jarym 9y agoNever read such nonsense masquerading as an authoritative piece of information. Author clearly doesn't appreciate that the ultimate truth of any authentication scheme is you should not trust anything from the user. So what if you take away a clients ability to specify what algorithm a piece of data is signed or encrypted with - if you blindly just accept whatever a client did and proceed then you're always gonna find yourself vulnerable. Intel didn't use JWT tokens or pass a client header - they just trusted what the client sent and landed themselves in the same mess. I make the point to illustrate that what real security pros do is make sure basic checks like validating user input is done regardless of what specification or algorithm is involved.
- kevinburke 9y agoThese points are covered in the article, and the library I wrote makes it impossible to parse a token without performing verification with a secret key
- jarym 9y agoYes I read. However, you've failed to grasp a few things: 1. The client should not get to 'choose' which algo it uses, it merely states what algo it did use. Emphasis should be on the server to verify that the client didn't do (or claim to do) something bad. 2. What happens if in 5 years time the algo you've standardised on is suddenly comprisable? You've ripped out the mechanism that updated clients could theoretically use to signify that they're using a newer algorithm. Take for example Git and its recent SHA collision issue. 3. By emphasising that 'clients should not get to choose', you're making the case that the choice is of itself a weakness it is not. The weakness is often in how inputs are processed (and far more often than any weakness in algorithms).
- kevinburke 9y agoI point out numerous cases where the server made a mistake in verifying the algorithm specified by the client. This is the point of reducing the complexity of the interaction If you are using JWT and someone breaks SHA2, you still have to worry about downgrade attacks. To evade downgrade attacks, you'll have to detect the protocol the client sends, and reject tokens that specify SHA2 or below. Or, roughly the same position you'd be in with one good algorithm: still in need of a backwards incompatible upgrade
- ceejay 9y agoIf the specification requires the server to decide which algorithm to use a naive client, who doesn't know which algorithms are safe or not, is just as dangerous. As far as I know there are no algorithms that exist today that we can guarantee will never be broken in the future. So algorithm choice inherently must be decoupled from the specification. EDIT: Or a naive server implementation for that matter...
- deleted 9y ago[deleted]
- makomk 9y agoThis complains that JWT does not have forward secrecy, and then recommends NaCl's box primitive instead... which does not have forward secrecy either. (This isn't exactly drawn attention to in the NaCl docs for some reason.)
- ceejay 9y agoI was just thinking. What is a good way to phrase the problem in order to understand whether there are more pros / cons to having the client vs server decide which algorithms to use in a transaction. I haven't thought this through fully, but as far as I can tell ecosystems on the web evolve. And so I think it's probably a good idea that we architect things for the web in such a way that we don't inhibit that evolution. When you put a decision like encryption algorithm in the client's hands does it feel to anyone else that the security will evolve more rapidly, and thus remain more robust? When the client is deciding, there's a larger pool of people "voting" for what is an acceptable level of security. Even though a lot of those "votes" will be based on the default settings of a library, that library will over time become less popular as more and more people consider it unsafe. By the same token, if a particular service (server-side) does not keep up with that evolution, fewer and fewer people will use it as other (safer) services pop up.
- komerdoor 9y agoI am using JWT for my projects to keep stateless sessions between servers and for some other tokens (refresh, register, reset pass etc.). Of course extra security measures are required (MitM protection [HTTPS etc.], XSS / CSFR prevention etc.), but this has nothing to do with JWT. I use encryption with a frequently rotated private key to encrypt the part of the payload that only the server may read. A good read at: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage https://stormpath.com/blog/where-to-store-your-jwts-cookies-...
- unscaled 9y agoThe problems with JWT are not related to MITM, XSS or CSRF vulnerabilities. You'll have to address these issues regardless of the type of token you're using. The problems with JWT can be divided into two classes: 1. Too many options, making it easy to misuse. Even if you disallow the 'none' algorithm (like most newer JWT libraries), there are still many other ways to break it. e.g.: https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ https://auth0.com/blog/critical-vulnerabilities-in-json-web-... 2. Misguided cipher choice. AES-GCM (easy target for nonce-reuse), RSA, NIST P-curves. So in short, even if you're using encryption, JWT just makes it easy for the crypto itself to fail.
- komerdoor 9y agoI agree. Thank you for pointing that out. That is why I restricted my JWT code to only accept / use certain options. Of course I could still have chosen the wrong cipher for my specific use case and am aware that JWT will not solve this for me. What JWT is doing is actually not that special as it is just a standardized container (akin to MKV and supported codecs) inside which existing technologies can be used. Easy to write something similar if you know what you are doing. I did that before, but still missed some extra verifications already build into JWT. Of course, the chosen technologies allowed to be used inside a JWT can still be prone to vulnerabilities. I am not sure if that can be blamed on JWT. People should still think about which options to use.
- ath0 9y agoThis is a case where the high-level point - "insecure options shouldn't be configurable" - conflicts with a reality of crypto protocols: you have to make tradeoffs based on the best known attacks and the platform you're running on, and those change over time. The best hashing algorithm, HMAC algorithm, and signing algorithm to use on a mobile device in 2007 isn't the same as the ones you'd pick today. Any protocol expected to last 10 years should allow for the selection of an underlying crypto algorithm. Maybe "none" should never have been an option - but tying the algorithm to the protocol has pretty severe drawbacks, too. More broadly - JWT isn't just about the exchange between a single client and a server; the choice of "use cases" misses a very real constraint of multi-party protocols. Within the context of OpenID (or OAuth more broadly), it's about the relationship between an end-user, a resource owner, a client and an authorization server -- all of whom need to be able to interact with a token, and often offline.
- tptacek 9y agoThis is in fact not true: an HMAC-based design from 2007, even one that used SHA-1, would remain sound today. HMAC hasn't changed in something like 20 years, and works even with MD5 (we've had since the 90s to make the migration from MD5 and I obviously don't recommend anyone continue using it). To non-cryptographers, this idea that protocols need to be constantly ready to accept new ciphers in case there's a break in one of the old ones is a very big deal, so much so that every amateur crypto protocol design includes cipher suite negotiation as the centerpiece of the protocol. In reality, it's a minor concern. Which the exception of RC4, pretty much every TLS ciphersuite flaw has been the product of flawed joinery and not problems with underlying ciphers --- which is why the major breaches have forced us to move people not from one ciphersuite to another, but instead from SSL3 to TLS 1.0 to TLS 1.1. For an expert design example, look at Trevor Perrin's Noise framework. An even simpler idea: simply specify a single set of coherent cryptographic constructions, and then version the whole protocol --- if there's a serious break in your protocol, you'll almost certainly have to make changes across the protocol anyways --- and upgrade the whole thing.
- unscaled 9y agoGood writeup of what you should be careful with with regards to JWT. There are some inaccuracies there too. First of all, JWT doesn't support encryption at all - it's JWE that does that. It's an important distinction, since most JWT libraries I ran into don't feature encryption, so if you want encrypted tokens you'll need to use an extra JWE library, or a more full-featured JOSE library. JWE also support more than just RSA - it definitely does support Elliptic Curve Cryptography (although I would prefer if they chose Curve25519 instead of the NIST curves), and they are used with EC Diffie-Helman in a certain construction that actually gives you more forward secrecy than NaCl box. NaCl Box offers you no forward secrecy, whereas all the ECDH-ES algorithms in JWE offer you partial forward secrecy, which saves you when the sender key is leaked, but not when the receiver key is leaked. That's the best you can get: we can't have a two-way perfect forward secrecy in non-interactive protocol like JWT since we can't perform a direct negotiation of ephemeral keys between sender and receiver). Of course, we're actually comparing apples to oranges here: you can get the same partial forward secrecy guarantee with libsodium's sealed box (not in the original NaCl): https://download.libsodium.org/doc/public-key_cryptography/sealed_boxes.html https://download.libsodium.org/doc/public-key_cryptography/s... As for an alternative to JWT/JWE, I think it really depends on what people want, but I have slightly different suggestions: 1. For simple access tokens in low-medium load scenarios, access tokens stored in Redis are probably simpler to implement than JWT + revocation. 2. If you don't have any secret information inside the token, HMAC-SHA256. 3. If you have secret information, I'll actually go with libsodium's XChacha20-Poly1305 AEAD: https://download.libsodium.org/doc/secret-key_cryptography/xchacha20-poly1305_construction.html https://download.libsodium.org/doc/secret-key_cryptography/x... secretbox doesn't support AEAD, but you often have external data that you want to tie the token. It's very easy to implement exactly the same construct with XSalsa20, so it will really be just secretbox with AEAD support, but that's non-standard and you won't find any native library support. 4. Public signature of public data with Ed25519 (this is NaCl's crypto_sign). 5. Authenticated asymmetrically encrypted tokens: to get partial forward secrecy, the easiest way would be using sealedbox and then signing the result with crypto_sign. It's not the most efficient way to do this, but NaCl/libsodium don't have a tailored operation for this use-case, so you would have to use primitives directly. All in all, not quite clear cut, and nobody is making a library that does that for you, so it's easy to see where JOSE is coming from.
- palmdeezy 9y agoWhat makes this all worse is that companies like Auth0 and Stormpath have flooded search results with self promoting blog posts masked as tutorials. This just makes it harder for developers to learn the basics without getting product shoved in their face.
- dmix 9y agoI don't see a problem with companies writing tutorials and OSS libraries to share with the community. If there is an economic incentive for documentation to be written and free software to be created then what's the problem really? If the article is blatant self-promotion then I could see the problem with that and those articles don't get anywhere on HN/Reddit/etc so they won't rank well on Google either. But I've seen some high quality docs/libraries coming out of companies like that and it's a great thing. The aren't responsible for developers doing poor implementations of JWT. And other developers equally have a voice such as the OP if they have a problem with the choice of technology they are promoting.
- exabrial 9y agoI disagree with most of his points, but what really bothers me is the underlying message of his article. I don't think we should fool ourselves into thinking we can design a protocol that isn't susceptible to implementation problems. Did we get SSL/TLS right? No, we've failed a few times, but we're doing better. Why is that? People are paying attention more that ever to OpenSSL and now we have competition with LibreSSL and the like. Side note: The irony of his coupler example; it's a flawed spec, not flawed implementations... the implementations followed the spec but the spec was dangerous from the start. JWT is the opposite: good spec, but a long time ago some early adopters didn't get things right.
- deleted 9y ago[deleted]
- unscaled 9y agoI guess heartbleed gave everybody the wrong image, but most TLS vulnerabilities were vulnerabilities in the spec. The fixes to RC4, BEAST, SWEET32, POODLE, LOGJAM, CRIME, BREACH, BRICK, BORKED, BUSTED and whatever else you could think of - all involved changing the spec. Sometimes by adding mitigations, but mostly by banning TLS features. TLS is a legacy protocol. Nobody likes it very much, but it's such an established standard that you don't have much choice than trying to fix it. The same might happen to JWT, but in both cases we'll be fixing the specs, not just the implementations.
- exabrial 9y agoTLS1.2 seems to be pretty secure... I think upcoming TLS1.3 will be very secure, and it's supposed to decrease latency.
- staticassertion 9y agoYou could look at SMACK TLS as a few dozen examples of implementation specific features due solely to the complexity of representing TLS state machines. These aren't protocol weaknesses, they're weaknesses in the implementation due to complexities in the protocol.
- Gonzih 9y agoOne should always validate algorithm before doing anything with JWT on the server side.
- arrty88 9y agoAre there any examples of big JWT hacks which took place due to a vulnerability
- tscs37 9y agoIt doesn't seem like the author is actually proposing an alternative, rather, the only thing says is "Don't use JWT, here is how you can do X with Nacl" Even worse; It is suggested that to authenticate a user one should use TLS. That might be true for a login form, but not beyond that. Once you have logged the user in, you need to continue authentication on every request. JWTs are one way to put this information on the client side without having to put any much trust into it. The second example is a simple asymmetric encryption example which... for some reason JWT is not a solution for? I've used Ed25519 plenty of times with JWT (custom algo header in this case), so I see no problem there plus... I don't think this is what JWT is actually trying to solve. The third example is encrypted data to the client, which is also something JWT isn't trying to solve, this is what JWE is for. JWT is purposefully unencrypted and I'm not sure how many developers would actually pretend a signature is encryption. The last part is an actual example of JWT use cases, in which case however the author blabs on about the (in)famous "algo=none" bug a lot of libraries had. I've specifically used the Go library mentioned and strictly enforcing the algo is a nonbrainer if you are using a custom one anyway. On the other hand, I still use HMAC for a seperate token for short-term authentication over endpoints (to make blacklisting logins easier). So JWT simply gives me some flexibility in sharing common code for authentication, the same code can consume the long-term tokens and the short-term tokens and much more if needed in the future. I'm not saying JWT is the end all for problems, but it's rather easy ready-to-use solution for some of my problems. Why write a signature library when there is one ready to use that, with care, is safe to use?
- kevinburke 9y agoI address these points in the article
- saganus 9y agoThere's a lot of conversation on when should I use JWTs and when not to. But as alternatives go, has anyone tried using Macaroons? They've been mentioned in HN a few times but I've never seen the tech catch up, even though it looks like a very cool way to implement authorization. Is there any particular reason why? Here are some resources I've found and I think Macaroons is a very interesting concept. Even the paper is accessible to someone like me, without any real security or cryptography expertise. Research paper: https://research.google.com/pubs/pub41892.html https://research.google.com/pubs/pub41892.html A new way to do authorization: http://hackingdistributed.com/2014/05/21/my-first-macaroon/ http://hackingdistributed.com/2014/05/21/my-first-macaroon/ (This link has an invalid HTTPS certificate if that concerns you): https://evancordell.com/2015/09/27/macaroons-101-contextual-confinement.html https://evancordell.com/2015/09/27/macaroons-101-contextual-... After I found this, I've always wanted to try it out but haven't had the chance. Does anyone has any experience or comments about it?
- hdhzy 9y agoWow, what an interesting idea it looks like macaroons resemble HS256 JWTs (no asymmetric Crypto) with claims encoded as strings (except key-value pairs of JWT) that are interpreted by the verifier (you can build more complex claims like login time between X and Y). On the surface it looks like JWT and Macaroons are very similar.
- tptacek 9y agoExcept that you can't change a Macaroon header and convince either the recipient of a token or the server verifying it that it is instead a NIST P-Curve public key attestation, so they're really only similar if you ignore the many problems of JWT. It's the nature of a grab-bag metastandard that it can be twisted into a poor version of any related standard. That's the problem with standards like these.
- saganus 9y agoI'm not familiar with either the details of how JWTs or Macaroons are implemented, that's why I'm interested in a cryptographer or security expert comment on this. Do you think that Macaroons are a sane alternative to JWTs? or in general, any comments on using them for authorization instead of OAuth2 or any of the alternatives? Edit: I think I do understand that some of the problems with JWT is that they have a lot of moving parts so the attack surface is much greater as well as not helping the developer avoid getting shot in the foot. Macaroons by comparison seem much simpler to my untrained eye, in that they are "just" a chain of HMACs, so that any modification of the different sections of a Macaroon would render it invalid. So why would Macaroons be or not be a suitable alternative to JWTs or other auth methods?
- tptacek 9y agoIn cryptography, we have a concept of "misuse resistance". Misuse-resistant cryptography is designed to make implementation failures harder, in recognition of the fact that almost all cryptographic attacks, even the most sophisticated of them, are caused by implementation flaws and not fundamental breaks in crypto primitives. A good example of misuse-resistant cryptography is NMR, nonce-misuse resistance, such as SIV or AEZ. Misuse-resistant crypto is superior to crypto that isn't. For instance, a measure of misuse-resistance is a large part of why cryptographers generally prefer Curve25519 over NIST P-256. So, as someone who does some work in crypto engineering, arguments about JWT being problematic only if implementations are "bungled" or developers are "incompetent" are sort of an obvious "tell" that the people behind those arguments aren't really crypto people. In crypto, this debate is over. I know a lot of crypto people who do not like JWT. I don't know one who does. Here are some general JWT concerns: * It's kitchen-sink complicated and designed without a single clear use case. The track record of cryptosystems with this property is very poor. Resilient cryptosystems tend to be simple and optimized for a specific use case. * It's designed by a committee and, as far as anyone I know can tell, that committee doesn't include any serious cryptographers. I joked about this on Twitter after the last JWT disaster, saying that JWT's support for static-ephemeral P-curve ECDH was the cryptographic engineering equivalent of a "kick me" sign on the standard. You could look at JWT, see that it supported both RSA and P-curve ECDH, and immediately conclude that crypto experts hadn't had a guiding hand in the standard. * Flaws in crypto protocols aren't exclusive to, but tend to occur mostly in, the joinery of the protocol. So crypto protocol designers are moving away from algorithm and "cipher suite" negotiation towards other mechanisms. Trevor Perrin's Noise framework is a great example: rather than negotiating, it defines a family of protocols and applications can adopt one or the other without committing themselves to supporting different ones dynamically. Not only does JWT do a form of negotiation, but it actually allows implementations to negotiate NO cryptography. That's a disqualifying own-goal. * JWT's defaults are incoherent. For instance: non-replayability, one of the most basic questions to answer about a cryptographic token, is optional. Someone downthread made a weird comparison between JWT and Nacl (weird because Nacl is a library of primitives, not a protocol) based on forward-security. But for a token, replayability is a much more urgent concern. * The protocol mixes metadata and application data in two different bag-of-attributes structures and generally does its best to maximize all the concerns you'd have doing cryptography with a format as malleable as JSON. Seemingly the only reason it does that is because it's "layered" on JOSE, leaving the impression that making a pretty lego diagram is more important to its designers than coming up with a simple, secure standard. * It's 2017 and the standard still includes X.509, via JWK, which also includes indirected key lookups. * The standard supports, and some implementations even default to, compressed plaintext. It feels like 2012 never happened for this project. For almost every use I've seen in the real world, JWT is drastic overkill; often it's just an gussied-up means of expressing a trivial bearer token, the kind that could be expressed securely with virtually no risk of implementation flaws simply by hexifying 20 bytes of urandom. For the rare instances that actually benefit from public key cryptography, JWT makes a hard task even harder. I don't believe anyone is ever better off using JWT. Avoid it.
- yellowapple 9y agoSo we should stop using cell phones because one implementation happened to spontaneously combust. Got it. Or maybe - just maybe - the claim that specifications should be judged by their implementations is entirely nonsensical. The fact that Internet Explorer exists doesn't in and of itself mean that web browsing as a whole is a defective concept. The fact that single-ply toilet paper exists doesn't mean we should stop using toilet paper. Likewise, the fact that some JWT implementations are defective does not in and of itself say a whole lot about JWT itself.
- ZoneGhost 9y agoFor the record, JWT is a payload and format spec for JWS/JOSE, which is really what you're complaining about. JWT is merely a claims set and an optional dot-notation serialization of a single signature. JWT/JWS libraries that handle all the validation alone are treacherous. You should ALWAYS parse the JSON before hand, perform your claims and header(s) validation, and then pass the payload/header/signature. If anything, it's computationally less risky than running the signature blindly through a signature validation function and then checking the header.
- kevinburke 9y agoyou could also choose to use safer libraries and cryptographic primitives
- ZoneGhost 9y agoThere's nothing a library can add to make things "safer" when it comes to application-specific constraints. If I'm checking to make sure I only accept a specific algorithm, I'm not going to blame a crypto library for validating something that is technically accurate (short of maybe disabling the "none" algorithm by default). You should also be in possession of at least the public key beforehand, and rely on that for authentication, rather than anything in the claim.
- 10165 9y ago"..."algorithm agility" that is a proud part of the specification" (italics mine) No idea about "JWT" but maybe this is part of the psychology that keeps schemes like SSL/TLS in use. (Part.) Do you think there are people who are actually proud of achieving complexity in a specification or implementation?
- pmarreck 9y agoHe should release "JWT-H2O" i.e. JWT with HMAC 256 Only. :) (left a similar comment on his blog)
- deathanatos 9y ago> But the server and the client should support only a single algorithm, probably HMAC with SHA-256, and reject all of the others. If you have a centralized system dealing w/ authentication, this doesn't work, as now everything that needs to verify JWTs needs the secret. The support for RSA, instead of HMAC, is there to meet a different set of requirement. What people fail to remember is that JWTs — and the libraries that work w/ them — do not just wrap data to be authenticated. They also handle verifying the various claims on a token — is this token applicable here? is this token expired? — things relevant to an authentication token, not just a mere signed blob of data. The suggestion to leave those to be reimplemented by every single end-user is bad advice.
- kevinburke 9y agoMaybe not a great time to mention I also found errors in the claims verification in the one library I tested, and ended up ripping that code out as well
- luord 9y ago> implementation errors should lower your opinion of a specification. An error in one implementation means other implementations are more likely to contain the same or different errors. It implies that it's more difficult to correctly implement the spec. Discussion on cryptography and particular implementations aside, I think this is sound and I normally follow this when judging technologies.
- tracker1 9y agoThe implementations of JWT that I've mostly used... internal signing and validation only... the algorithm and public key are pretty much pinned down. If you do that, JWT is a pretty valid format... it's when you leave things open to "whatever" that the security issues come through. I don't have a problem with JWT, only in that having the signature method, etc configurable in the first place as an implementation detail is probably a bad idea.