News for hackers. Stuff that matters.
Re:How not to sign a JSON object by mixedCase on Wednesday July 24, 2019 @12:59PM (#20517158)
> 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.

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @01:10PM (#20517287)
We 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-a...

(Disclaimer: I'm the author.)

Re:How not to sign a JSON object by mixedCase on Wednesday July 24, 2019 @01:37PM (#20517569)
Well, 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.

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @01:49PM (#20517708)
The 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.
Re:How not to sign a JSON object by random023987 on Wednesday July 24, 2019 @04:22PM (#20519248)
Assuming 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"?
Re:How not to sign a JSON object by floo on Wednesday July 24, 2019 @06:47PM (#20520821)
I 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.

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @06:42PM (#20520772)
Why would you do that? If you already know what the header is, just validate the tag and ignore what the header has to say.
Re:How not to sign a JSON object by thegagne on Wednesday July 24, 2019 @01:45PM (#20517654)
I 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?

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @01:53PM (#20517763)
1. 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.)

Re:How not to sign a JSON object by thegagne on Wednesday July 24, 2019 @02:58PM (#20518455)
> 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.

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @03:01PM (#20518479)
Okiedokie. 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?

Re:How not to sign a JSON object by comex on Wednesday July 24, 2019 @03:36PM (#20518832)
Why 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.)
Re:How not to sign a JSON object by sytringy05 on Thursday July 25, 2019 @01:11AM (#20522732)
It's a fair question, but in my experience client certs run into all manner of roadblocks in corporate or complex environments.

TLS terminating LBs/WAFs/<things> that cant authenticate the client cert or pass the public key through to something that can, dealing with key/cert expiry, nobody to run the PKI infra with any interest managing identities of things that aren't AD computers, you name it.

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @03:42PM (#20518898)
Yeah, my default would absolutely be client certs. That's where my question about "an environment hostile to good ideas" comes from -- I was assuming the lack of HTTPS was there for a reason.
Re:How not to sign a JSON object by tialaramex on Wednesday July 24, 2019 @09:05PM (#20521731)
Mmm. I really like mutual auth (TLS client certs) but one caveat:

Now somebody needs to manage the resulting PKI.

Even what looks like the no effort case, where you punt to the Web PKI and have all the clients use Web PKI certs (ie client1.example.com needs a cert with SAN dnsName client1.example.com like a web server would have but making sure the EKU for client auth is asserted) means now you have to either keep pace with us, or risk an impedance mismatch if our policies change in a way you're not OK with.

If you use one or more private CAs there's a tension between on the one hand the convenience of it not being your problem, and on the other hand the risk that it turns out you were just engaged in theatre and there's, for example, an unsecured SCEP server that will happily give any adversary with network access an authorised certificate with whatever identity they ask for...

Re:How not to sign a JSON object by kccqzy on Wednesday July 24, 2019 @02:03PM (#20517877)
Simpler: 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.

Re:How not to sign a JSON object by jcranmer on Wednesday July 24, 2019 @01:59PM (#20517820)
> 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?

Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @02:32PM (#20518170)
What 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 :)

Re:How not to sign a JSON object by tptacek on Friday July 26, 2019 @01:48PM (#20536683)
I 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.
Re:How not to sign a JSON object by merlincorey on Wednesday July 24, 2019 @03:11PM (#20518598)
I 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.
Re:How not to sign a JSON object by lvh on Wednesday July 24, 2019 @03:19PM (#20518672)
PASETO 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.

Re:How not to sign a JSON object by deathanatos on Wednesday July 24, 2019 @09:36PM (#20521871)
How 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?)

Re:How not to sign a JSON object by merlincorey on Sunday July 28, 2019 @12:57AM (#20545921)
I 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.

Re:How not to sign a JSON object by merb on Wednesday July 24, 2019 @03:44PM (#20518922)
actually 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.

Re:How not to sign a JSON object by geofft on Wednesday July 24, 2019 @04:22PM (#20519249)
You 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.

Re:How not to sign a JSON object by merb on Monday July 29, 2019 @05:00PM (#20559394)
well 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.
Re:How not to sign a JSON object by SlowRobotAhead on Wednesday July 24, 2019 @04:39PM (#20519410)
Not 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.