Paserk: Platform Agnostic SERialized Keys
github.com
github.com
* JWT can be secure if you are careful
* there is wide support for JWT. (See for example this IETF draft https://datatracker.ietf.org/doc/html/draft-ietf-oauth-access-token-jwt-13 as well as the numerous libraries)
* it does a simple job "well enough".
Maybe paseto can eventually displace JWT, but I have a hard time seeing how that happens.https://www.howmanydayssinceajwtalgnonevuln.com/
https://www.zofrex.com/blog/2020/10/20/alg-none-jwt-nhs-cont...
https://twitter.com/SchmiegSophie/status/1413248896227155968
https://twitter.com/tqbf/status/1414087907938377735
etc.
> * there is wide support for JWT. (See for example this IETF draft https://datatracker.ietf.org/doc/html/draft-ietf-oauth-acces... as well as the numerous libraries)
Yes, and my intention is to make sure there is wide support for PASETO in the near future too.
> Maybe paseto can eventually displace JWT, but I have a hard time seeing how that happens.
It won't ever 100% displace JWT in the same way that we won't ever 100% displace PHP 4 from the Internet, or the legions of badly written tutorials full of SQL Injection vulnerabilities that new programmers learn from.
The goal isn't to displace JWT, though. The goal is to provide a secure-by-default, easy-to-use, hard-to-misuse alternative.
After all, just because it's possible to implement a set of building blocks "securely" doesn't mean the kit is secure. I wrote more about this here: https://paragonie.com/blog/2019/10/against-agility-in-crypto...
But even if you don't care about all of that, the upcoming PASETO versions (v3/v4) offer cryptographic properties that JWT does not, such as exclusive ownership. https://github.com/paragonie/paseto/blob/master/docs/Rationa...
------
Also, in case it wasn't obvious: PASERK is still a work-in-progress; things might change. Wait until you see a `1.0` tag before trying to implement it.
There is a reference implementation in PHP, but that's also experimental and no stable release has occurred there yet.
That would be great, thanks for your hard work.
> The goal isn't to displace JWT, though. The goal is to provide a secure-by-default, easy-to-use, hard-to-misuse alternative.
That makes sense, appreciate the insight.
Everybody makes mistakes. Insecure protocols make it easy for mistakes to turn into vulnerabilities. Secure protocols make it difficult for mistakes to turn into vulnerabilities.
There's a spectrum of course, but 'lack of care' can cause an issue with any software system, imo.
JWT includes cryptographic agility for the client to change algorithms and and defines a “none” algorithm that disables the cryptography altogether. The mistake is right there waiting to be made – and pretty much every single implementer made that mistake. And they keep making that mistake, over and over again [0].
Paseto doesn’t include cryptographic agility and doesn’t define a “none” algorithm. It’s quite literally impossible to make that mistake.
So on the one hand, we have a protocol that we can see empirically has a design that does lead to mistakes that do lead to vulnerabilities… versus a protocol where the mistake simply can’t happen. The former “can be secure if you are careful” in this respect – which we can see very clearly means “insecure”; and the other is secure because you can’t not be careful in this respect because the protocol doesn’t allow for it.
"none" is only viable in very narrow circumstances (basically where you have other ways of verifying trust, like mTLS or an isolated network AND you know that signing has a material impact on your system performance). I agree that it shouldn't be used widely.
Thanks for the example. It feels a bit like the old dynamic vs static typing debate, where more flexibility can be helpful in some circumstances (monkeypatching that old ruby gem) but can come back and bit you too if you (and everyone who updates the code) are not careful.
Anyway, hope Paseto (and other solutions) continue to push the ball forward.
And if you are using JWTs, never accept or generate one with alg=none. :)