7 ms·
> Anyway, no, because you need to parse a header to read the JWT, so you inherit all of the problems that stem from that. Can anyone enlighten me what point is
by mixedCase 7y ago
> Anyway, no, because you need to parse a header to read the JWT, so you inherit all of the problems that stem from that.
Can anyone enlighten me what point is the author trying to make? JWT is pretty damn standard so it's my go-to for signing objects.
- lvh 7y agoWe should write the "The JWT Problem" post one day, but this post isn't that, so I really don't want to derail the discussion. The short version is that there are flaws in the JWT specification that make certain bugs likely. A classic example of the "you have to parse a header to use the JWT" problem is the HS256 vs RS256 confusion bug, where your JWT library would interpret an allegedly-HS256 (HMAC) JWT using RS256 (RSA) key material. The JWT would get validated using the public key of the RSA pair, interpreted as an HMAC key. But the public key is, you know, public! So the impact of the bug is that everyone can forge JWTs. That is not a problem that can happen in well-designed schemes. We do have a blog post from last year that tells you what we think you should do if you want to be safe and you know what kind of abstract thing (e.g. signing, MACing, etc) you need: https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html https://latacora.micro.blog/2018/04/03/cryptographic-right-a... (Disclaimer: I'm the author.)
- thegagne 7y agoI have a need to provide an update service where client software (that I control) can request download files, but any other clients cannot download the files. Currently using a terrible method with hashed query strings based on date, path, and a secret, which are then validated and have an expiration. Also, HTTP, so yeah it’s broken, but it at least prevents drive by scraping. At this point we have no need for assymetric (don’t need to identify the requester, just need to prevent spoofing). What method of securing would you recommend?
- lvh 7y ago1. Step one is HTTPS. Since you control the client, ideally just one ciphersuite. Maybe pinning? But given that it's HTTP now, maybe this this is running in a production environment that's hostile to good ideas? (Of course, plain HTTPS as usually configured doesn't authenticate the client.) 2. Step two is a bit more complex. I assume your clients hold the secret, know what path they want to hit, and compute the key that way? Tell me a bit more about the clients: what are they implemented in? What do they run on? Can you reliably ship updates? (I'd prefer to have this discussion here but if you can't discuss publicly I'd be happy to take a look. My contact info is in my HN profile.)
- thegagne 7y ago> But given that it's HTTP now, maybe this this is running in a production environment that's hostile to good ideas? How did you know! ;) I’ll probably hit you up on the side, but there are multiple clients each with their own technical debt, and it’s an old solution, but I’m putting things in place now to make changes more possible, maybe per client app using separate hostnames, for example, so that we can transition to the new without breaking the old. I think most of the client apps actually hit a manifest API first that gives out signed urls. This already happens over https in most cases. Some may generate their own, but I’m not sure all the usage scenarios. I can’t give more details on the clients here, but let’s just assume they are diverse and difficult but not impossible to upgrade. It’s the kind of thing we want to get right the first time and has to work for a decade.
- lvh 7y agoOkiedokie. That sounds like catnip to me, so please do. Happy to sign (non-silly) mNDAs if that helps. Probably the most useful thing for me to know is: what's the algorithm for signing a URL? If everything uses a manifest API, can you just make that a random token instead of a signature, and store that token in a database somewhere with an expiry?
- comex 7y agoWhy not just use client certificates? (Not a rhetorical question. Client certificates seem like the “obvious” solution so I assume there’s a reason you’re not recommending them.)
- kccqzy 7y agoSimpler: just let everyone download an encrypted version of the files. Then only allow your client software that you control to decrypt the downloaded files. Encrypt the files using AES-GCM. If you trust that your own client software is distributed securely and won't run in hostile environments and be reverse engineered, just ship that AES key with your software. Otherwise it will get complicated fast.
- mixedCase 7y agoWell, it does makes sense to me that if JWT allows for both symmetric and asymmetric tokens that's a complexity detail that can be gotten wrong when implementing. Thankfully, JWT being quite standard and having momentum behind it I think there's a lower risk in recommending someone to pick a popular JWT library than telling them to roll his own simple scheme on top of HMAC (which is the article's recommendation and what JWT will end up doing regardless), specially when scale is considered. I know, I know I'm arguing for "worse is better", but I honestly can't imagine a clean solution to this that would be so good it justifies dropping a seemingly decent standard, leaving mountains of legacy and requiring the entire developer world to learn about yet another crypto scheme. But then again I'm no expert in that area, and I would love to read a post about it from someone who is.
- lvh 7y agoThe nice thing about HMAC is that it's so bulletproof and easy to use. There are no footguns you introduce by using HMAC directly instead of using HS256, and there are plenty you introduce by using HS256 instead of plain HMAC.
- jcranmer 7y ago> We do have a blog post from last year that tells you what we think you should do if you want to be safe and you know what kind of abstract thing (e.g. signing, MACing, etc) you need A little bit off-topic, but what is your opinion on NSS versus OpenSSL? Or LibreSSL and BoringSSL?
- lvh 7y agoWhat do you want to accomplish? Do you want good implementations of cryptographic primitives, or something else? As a general rule: OpenSSL, BoringSSL if you can get away with it, don't use NSS or LibreSSL. But that presupposes that using a library like OpenSSL was the right answer to begin with :)
- tptacek 7y agoI used to be a proponent of NSS, when people who were much more closely involved with TLS implementations were quite down on it. NSS was the first TLS library I really read "cryptographically" (it hosted the Bleichenbacher e=3 signature verification bug, which made Firefox vulnerable to signature forgery) and I found the code really easy to follow, unlike OpenSSL's. Ultimately, they were right, and I was wrong: in this space, you want a lot of attention and effort on your TLS library, and OpenSSL is the most seriously maintained TLS library. For the same reason: OpenSSL over LibreSSL.
- merlincorey 7y agoI would be interested to hear your thoughts on PASETO, which I increasingly see as a replacement for JWT -- I just haven't had a chance to use it in production yet, myself.
- lvh 7y agoPASETO is a marked improvement and doesn't have the specific problem mentioned here, by using versions instead of an attacker-controlled alg field. One of the things that makes "The JWT Problem" such a hard post to write (and not one we've already just written) is that the cryptographic flaws are but one problem; architecture implications are another. So, to say "yes go use PASETO" instead implies that something "like" PASETO or JWT is even the right answer, and in the vast majority of cases where we've seen JWTs applied at Latacora that has not been the case.
- deathanatos 7y agoHow is the (attacker-controlled, no?) version & purpose field in PASETO not subject to the same issues as the JWT header? (Are we just lucky that none of the currently existing version/purposes can conflict?) The issues folks have around JWT's header field always seem to be interface issues: libraries need to understand what keys they can use to validate, and what types those keys are, and validate them against the header. (Though, I do not know why there is a "none" algo. That does seem like a folly. Could we recon that in the RFC?)
- merlincorey 7y agoI believe the distinction is that with PASETO, the versions are by specification not backwards compatible. So, if my application supports v2 and you "forge" a v1 token, my application will not validate it.
- merb 7y agoactually you can just never send the header and always assume that the header is `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9` { "alg": "HS256", "typ": "JWT" } (or whatever algorithm you wish) of course only "internal" clients would understand the jwt that isn't according to the spec.
- geofft 7y agoYou can do that, but you carry a risk of someone developing an internal client one day that does actually trust the remote header, because they're using an off-the-shelf library. At just about everywhere I've worked, there have been efforts to do some sort of new implementation of a client to existing APIs, either because a new language / framework got cool since the API was originally designed, or simply because there's also a new server but you need backwards compatibility with old servers (The only exception I can think of is a brand-new startup.) "JWT, but you must roll your own implementation to avoid security risks" is strictly more dangerous than "Our custom signing system," because at least with the custom signing system, people are going to read your spec and not JWT's.
- merb 7y agowell you can use most JWT libraries with alg: none but specify the alg (so not none alg) it still is against the spec, but it works in over 70% of all libraries.
- random023987 7y agoAssuming a JWT implementation accepts only a fixed header (all header fields must be present and match, no additional fields can be present), are there any other issues with "just use jwt"?
- lvh 7y agoWhy would you do that? If you already know what the header is, just validate the tag and ignore what the header has to say.
- floo 7y agoI do like using JWT. But its point is to offer flexibility. If you fix the entire header i.e. use a single signature method, you might just as well concat that signature directly. In other words if you stop utilizing JWT, you won’t have JWT specific problems.
- SlowRobotAhead 7y agoNot for nothing, but JWT support in C is really bad. I have an embedded device that I considered JWT, but it didn’t look great for supported libs in C. So knowing JWT exists, this is still of interest to me.