Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

- JWT algorithm is not configurable: good!

- JWT Algorithm is RS512: uggh.

Huge access tokens, slow validation AND bad security at the same time, boy we must be lucky.

- Encrypted JWT when saving sensitive information in cookie? Good start...

- ... Using Asymmetric encryption? Oh no...

- RSA-OAEP: At least it's not PKCS#1.5 amirite?

- Same RSA key is used for encryption and signature(?) Not great.

- Stateful Access Tokens: well...

I'm not sure how I feel about using stateful access tokens here at all. Since there is already a KV dependency, there are some advantages to storing stateful access tokens in the KV, most importantly you can easily revoke the tokens directly by deleting them. Revoking stateless tokens, on the other hand, is quite hard and not something that most web applications would care to implement.

The most common trade-off (and indeed, half of the raison d'être for OAuth 2.0 refresh tokens) is to have a very short-lived (e.g. 5 minutes) stateless access token and a long-lived stateful refresh token (which OpenAUTH already does). Revocation would still come with some delay, but you won't be able to use an outdated token for a long time after the user logs out or changes password. This is an acceptable trade-off for many applications, but I'm not sure if it's right to offer it as the only solution in a software package that wants to be generic: many applications will have compliance requirements that could rule out accepting logged out session tokens for such a period.

- JWT in any form or manner

The elephant in the room. Since JWT allows you to choose your own algorithm and offers some some rather bad options, using JWT can be considered as "Rolling your own crypto Lite". You have a lot of choices here and if you are not an expert you're bound to make some wrong choices: such as the ones I've listed above. If OpenAUTH had used PASETO for its tokens, it wouldn't be running into these issues at least since no clearly insecure options are available.

If you do use JWT, for the love of all that is good, never stray away from this path:

1. For symmetric tokens, use the HS* family of algorithms. That's the only available option anyway.

2. When using HS256/384/512, you should use randomly generated secrets from /dev/urandom [1]. The secret size in bits should be the same size as the HS algorithm bits (i.e. 32 bytes for HS256, 48 bytes for HS384 and 64 bytes for HS512). In any case, you should NEVER use passwords as the HS256/384/512 algorithm secret.

3. Do not use asymmetric tokens unless the there are are multiple token verifying parties which are separate from the token issuer. If the token issuer is the same as the verifier, you should use a symmetric token. If you've got one issuer and one verifier, you should probably still use a symmetric token with a shared secret, since there is no issue of trust. Asymmetric cryptography is always an order of magnitude easier to screw up than symmetric cryptography.

4. If you do use asymmetric cryptography, always use Ed25519. If you are forced to use something else for compatibility, use ES256/384/512. It still has some issues (especially if your random number generator is unreliable), but it's still better than RSA. You really want to use Ed25519 though.

5. If you want to encrypt JWT, don't. JWE is too hard to use correctly, and the only reliably secure option that is usually implemented by libraries (A256GCMKW) is slow and it's not very popular so I'm not sure how much analysis the algorithm (AES Key Wrap) has seen.

6. The best and easiest option for encryption if you really must use JWT (and can't use PASETO): Just take your payload, encrypt it with NaCl/Libsodium (secretbox[2]), base64 encode the result and stuff it inside a JWT claim. This will be faster, easier and more secure than anything JWE can offer.

[1] https://www.latacora.com/blog/2018/04/03/cryptographic-right...

[2] https://libsodium.gitbook.io/doc/secret-key_cryptography/sec...



thanks for writing this up! i have been looking at switching to PASETO instead of jwt

one thing though - the reason we use asymmetric encryption is to allow other clients to validate tokens without calling a central server

eg if you use AWS API Gateway they specifically have jwt authorization support where you can point them to a jwks url and it will validate requests

i need to look into the algorithm again - another constraint was trying to work across everywhere JS runs and i need to check if a better algorithm can be used that still works everywhere


> thanks for writing this up! i have been looking at switching to PASETO instead of jwt

I'm glad to hear that! PASETO would solve all the cryptography issues I've described above.

> one thing though - the reason we use asymmetric encryption is to allow other clients to validate tokens without calling a central server

There seem to be two different usages of asymmetric JWT in OpenAUTH:

1. Asymmetric RSA signatures for access tokens. These tokens can be validated by any third party server which supports JWT. The tokens are SIGNED, but not ENCRYPTED. If you did encrypt them, then third party servers will not be able to verify the token without having the private key — which is obviously insecure.

This type of token would usually be asymmetric if you want to support multiple audiences ("resource servers" in OAuth 2.0 terms) with the same token. If you have just one audience, I would still make this token symmetric, unless key distribution is a problem. AWS JWT authorizer sucks[1], but you could write your own lambda authorizer. Google Cloud (Apigee)[2] and Azure API Management[3] natively support HS256/384/512, so this is mostly an AWS problem.

2. Asymmetric signature AND encryption for cookies. I guess these cookies are used for saving SSO state and PKCE verifier, but I didn't dive deeply into that. This cookie seems to be only read and written by the OpenAUTH server, so there is no reason for using asymmetric encryption, let alone using it with the same RSA keypair for both encryption and signature[4].

Since the cookie is only read by OpenAUTH, you can just use PASETO v4.local for this cookie.

---

[1] I wouldn't trust the security of a product which ONLY allows RSA, when they could have enabled safer protocols with a single line of code.

[2] https://cloud.google.com/apigee/docs/api-platform/security/o...

[3] https://learn.microsoft.com/en-us/azure/api-management/valid...

[4] https://crypto.stackexchange.com/questions/12090/using-the-s...


There is already a closed ticket about JWT usage. Unfortunately the ticket author did not point at any specific weaknesses besides revocation to which the app author answered:

"JWTs aren't innately problematic - they come with the tradeoff of not being able to be revoked. The ideal setup is setting a short expiry time on the access_token (eg 5min) and setting a long expiry on the refresh token (which is not a JWT and can be revoked)."

The fact that this tradeoff is acceptable to some apps is correct. But I disagree that JWT tokens aren't innately problematic. Stateless tokens aren't innately problematic. Even stateless access tokens aren't innately problematic if you're willing to live with the tradeoffs (revocation delay or a centralized/propagated revocation list). But JWT is innately problematic, in the most literal sense possibly: the very nature of the JWT specification is to permit the largest amount of cryptographic flexibility including supporting (and even recommending) insecure cryptographic algorithms, that may cause security problems if chosen. In other words: it is innately (= in its very nature) problematic (= has the potential of causing problems). JWT is the poster child of being "innately problematic".

I think the app author confuses "innately problematic" with "impossible to implement securely". JWT is not impossible to implement securely. After all, even SAML with the nefarious XMLdsig is possible to implement securely and we do, in fact, have secure implementations of SAML. The real problem is that JWT is hard to implement securely if you do not have the right expertise. And OpenAUTH is giving us (yet another) clear example where the JWT implementation is less than ideal.

I will be the first to admit that I am not expert enough to know how to hack this kind of cryptography, but I am also not good enough to prove that it is safe to use.


> we do, in fact, have secure implementations of SAML.

Do we?

I thought we only had implementations where with no currently known security problems.


> no currently known security problems

To be fair, that is the layman's definition of "secure"


Yes, that was my usage of "secure" here. I obviously didn't mean that we should blindly trust SAML implementations. SAML should be avoided if possible, due to inherently complicated implementation. The same goes true for JWT. Both standards have better alternatives which are viable for the majority of necessary use cases.


> If you do use asymmetric cryptography, always use Ed25519

What about secp256k1 / ES256K?


btw what's wrong with 512-bit keys?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: