Hacker News new | ask | show | jobs
by unscaled 27 days ago
> It's not "JWT is broken". The cryptography is fine. The tymondesigns/jwt-auth package is fine. The concept of using JWT as your app's session is what's broken.

If only that was true. JWT came with a lot of questionable cryptographic choices. It went hard on fine-grained cryptographic agility like it was 1995 all over again. It started with the wrong suite of outdated ciphers like RSA and no good security requirements and implementation guides, and even the notorious "none" algorithm. The end result is a string of CVEs that affected a wide swath of JWT libraries.

JWT has many other ill-conceived features such as embedded JWK, token-declared URLs and the complex mess that is JWE (which you'll need if you want encryption). This complexity, useless features (the "none" algorithm), together with picking algorithms that are hard to implement correctly[1] and not setting any kind of security requirements made vulnerable libraries spread like wildfire, and introduced at least 5 different classes of vulnerabilities[2].

The craziest thing, is that easiest vulnerability to abuse (the "none" algorithm), is a required by the JWT RFC, you read it too literally:

  Of the signature and MAC algorithms specified in JSON Web Algorithms
  JWA], only HMAC SHA-256 ("HS256") and "none" MUST be implemented by
  conforming JWT implementations.
Now, the RFC writers obviously meant that conforming JWT libraries, should support "none" if explicitly requested, but did not mean that the libraries have to accept the "none" aglorithm by default. In fact, it's clearly stated:

  An Unsecured JWS uses the "alg" value "none" and is formatted
  identically to other JWSs [...]

  Implementations that support Unsecured JWSs MUST NOT accept such
  objects as valid unless the application specifies that it is
  acceptable for a specific object to not be integrity protected.
  Implementations MUST NOT accept Unsecured JWSs by default.  In order
  to mitigate downgrade attacks, applications MUST NOT signal
  acceptance of Unsecured JWSs at a global level, and SHOULD signal
  acceptance on a per-object basis
Or in another section:

  Unsecured JWSs (JWSs that use the "alg" value "none") provide no
  integrity protection.  Thus, they must only be used in contexts in
  which the payload is secured by means other than a digital signature
  or MAC value, or they need not be secured.
Unfortunately, the JWA spec is huge and complex because it needs to definy many useful, secure and totally not bonkers algorithms like PBES2-HS256+A128KW and RSAES-PKCS1-v1_5, and the very important(?) reasons for storing the coefficients for RSA. So I guess the end result is that almost nobody ever read the JWA RFC, and somehow half of the first crop of JWT libraries let anyone strip the signature, change "alg" to "none" in the header and freely manipulate the token. Good times.

So yes, stateless tokens are a bad tradeoff for many (if not most) web applications. But even if they weren't, there many formats that would do much better than JWT[3]. If you end up going with JWT, it's really better to thoroughly review your library, and stick to safer algorithms that doesn't result in a 5kb token (I'm looking at you RSA). Ed25519 is now supported by a decent amount of libraries.

[1] https://neilmadden.blog/2022/04/19/psychic-signatures-in-jav...

[2] https://pentesterlab.com/blog/jwt-vulnerabilities-attacks-gu...

[3] https://fly.io/blog/api-tokens-a-tedious-survey/

1 comments

Thank you very much, YOU ARE SOMEONE YOU ACTUALLY UNDERSTAND WHAT IM RANTING HERE.

You dont need JWT, just use something else and you will be fine, this is the gist of it.