Live data from Hacker News

Managing a Secure JSON Web Token Implementation

cursorblog.com

11–20 of 21 posts

Re: Managing a Secure JSON Web Token Implementation

#11

Now, what is the (currently accepted) best way to store that refresh token in a ReactJS frontend? I send the JWT via Cookies as “httpOnly; Secure”, would the refresh token go the same route? If so, wouldn’t compromising of the JWT also mean the same for the refresh token? And therefore give the person unlimited access until key-rotation? Or, like with Oauth2, is the idea that JWT gets transmitted back to the server w…

JWT and Refresh tokens dont address session issues; so the answer to your question is to introduce strong session management tools.

(Id argue that JWT is the wrong tool to use in a react front end - store that in the orchestration and implement some strong session management betweem FE and orch through an access gateway)

Re: Managing a Secure JSON Web Token Implementation

#12
post #8

If you are going to use JWT besides its failings, you should use it safely. But not all advice in this piece is equally strong. 1. RS256 vs ES256 - you shouldn't use either. RS256 not just an old standard on the way out. With safe keys sizes tokens are often going to be too large and signing too slow for you. ES256 on the other hand, suffers from many theoretical flaws and at least one practical flaw that (complete b…

Nonce reuse is easily preventable with deterministic nonces or sufficient randomness. PS3 used a fixed nonce which is a whole different problem.

I agree that JWT has all sorts of flexibility that make it hard to use well but NIST curves work just fine.

If you think they are backdoored then sure, Ed25519 is a better option but real world constraints may require you to use a NIST curve for now.

Re: Managing a Secure JSON Web Token Implementation

#13

Now, what is the (currently accepted) best way to store that refresh token in a ReactJS frontend? I send the JWT via Cookies as “httpOnly; Secure”, would the refresh token go the same route? If so, wouldn’t compromising of the JWT also mean the same for the refresh token? And therefore give the person unlimited access until key-rotation? Or, like with Oauth2, is the idea that JWT gets transmitted back to the server w…

>...best way to store that refresh token in a ReactJS frontend

You never store refresh tokens in a frontend. You can store access tokens (short-lived) in the frontend but you should never store refresh-tokens.

Re: Managing a Secure JSON Web Token Implementation

#14

Anyone have any experience implementing PASETO[0]? I have read the papers and seen the talks -- it seems fairly compelling. [0] https://paseto.io/

I haven't implemented but like what it's going for. Modern crypto is all about making it easy to do the right thing without thinking about it and PASETO does that well with its versioning scheme and relying on established crypto from libsodium.

Re: Managing a Secure JSON Web Token Implementation

#15

Anyone have any experience implementing PASETO[0]? I have read the papers and seen the talks -- it seems fairly compelling. [0] https://paseto.io/

I haven't implemented PASETO but I was thinking about adding support for another language. If I were to implement it, I would just use libsodium for most of the cryptographic primitives whenever possible since the reference PASETO implementation uses it as well as most of the other language implementations too (Except for the Go version).

PASETO does seem like a cryptographic secure alternative that addresses the pitfalls of the JOSE standard and has most of the mitigations mentioned in this blog-post (No cryptographic-algorithm agility) and it supports the same functionalities of JWT/JWE and JWS. So I am convinced on getting that standardized, but it also needs XChaCha20-Poly1305 AEAD to be standardized too [0].

Fernet was also around as being a secure alternative, but it has been mostly replaced by Branca [1] and PASETO.v2.

[0] - https://github.com/bikeshedders/xchacha-rfc

[1] - https://branca.io

Re: Managing a Secure JSON Web Token Implementation

#16

Now, what is the (currently accepted) best way to store that refresh token in a ReactJS frontend? I send the JWT via Cookies as “httpOnly; Secure”, would the refresh token go the same route? If so, wouldn’t compromising of the JWT also mean the same for the refresh token? And therefore give the person unlimited access until key-rotation? Or, like with Oauth2, is the idea that JWT gets transmitted back to the server w…

You should not store any token in the frontend. Instead, have a server doing that and use a classic secure cookie session. The session is bound to the token / refresh token and can then do the token management. Alternatively, don't use access token / refresh token but an ID token. The refresh of the token will be done via the ID token and the user's session (cookie) to the OAuth provider.

Agree this stuck out to me - I think a lot of confusion stems from how to handle refresh tokens - the oauth spec I feel is responsible by the confusion of how it calls apps “clients” and how flimsy it is about implementation (should/shall/must). If you are keeping refresh token locally on the user agent, you really urgently need to provide the user session management tools to revoke those things, and you need to be doing more advanced threat/abuse detection of their usage.

Re: Managing a Secure JSON Web Token Implementation

#17
post #16

Earlier quoted context omitted.

You should not store any token in the frontend. Instead, have a server doing that and use a classic secure cookie session. The session is bound to the token / refresh token and can then do the token management. Alternatively, don't use access token / refresh token but an ID token. The refresh of the token will be done via the ID token and the user's session (cookie) to the OAuth provider.

Agree this stuck out to me - I think a lot of confusion stems from how to handle refresh tokens - the oauth spec I feel is responsible by the confusion of how it calls apps “clients” and how flimsy it is about implementation (should/shall/must). If you are keeping refresh token locally on the user agent, you really urgently need to provide the user session management tools to revoke those things, and you need to be d…

Most people should probably follow the pathways laid out by IdentityServer4 and oidc-client, even if not not using .NET Core (you could absolutely deploy it standalone). Lots of sane defaults, even for refresh tokens and revocations and other difficult specs to understand. It’s well maintained and well thought out.

Re: Managing a Secure JSON Web Token Implementation

#18
post #8

If you are going to use JWT besides its failings, you should use it safely. But not all advice in this piece is equally strong. 1. RS256 vs ES256 - you shouldn't use either. RS256 not just an old standard on the way out. With safe keys sizes tokens are often going to be too large and signing too slow for you. ES256 on the other hand, suffers from many theoretical flaws and at least one practical flaw that (complete b…

Security is always relative.

There usually is a "don't use JWTs" alternative, but it's almost always shared secrets. Passwords, cookies, or some variation on that concept.

In that light, even poor jwt hygiene is better than none as long as you avoid a few key mistakes.

But on the other hand, security is, at it's core, the assessment of what guarantees a given technology can actually provide versus what you _depend_ on it to provide. So better tech can be worse security if you overestimate its capabilities.

Re: Managing a Secure JSON Web Token Implementation

#19

Now, what is the (currently accepted) best way to store that refresh token in a ReactJS frontend? I send the JWT via Cookies as “httpOnly; Secure”, would the refresh token go the same route? If so, wouldn’t compromising of the JWT also mean the same for the refresh token? And therefore give the person unlimited access until key-rotation? Or, like with Oauth2, is the idea that JWT gets transmitted back to the server w…

I use Auth0 for my React frontend. The Auth0 folks themselves say you shouldn't use refresh tokens for single page apps, you can't trust the client-side.

Instead of using refresh tokens, they have a "silent authentication" mechanism[1]. The idea is: sometime before the user's initial token expires, your app goes through the silent-auth process in an invisible iframe. Assuming the user's authentication credentials are still valid, the invisible iframe will eventually use the browsers postMessage() functionality to deliver a new token to the main app's frame, your app then quietly starts using this new token that has a new cryptoperiod.

The silent-auth mechanism doesn't use any different inputs than a normal Auth0 SSO login. Your app is constantly re-authenticating until the user is not allowed to login any more. This allows you to set short expiration times with no interruption of the user at all.

[1] - https://auth0.com/docs/api-auth/tutorials/silent-authenticat...

Re: Managing a Secure JSON Web Token Implementation

#20
post #8

If you are going to use JWT besides its failings, you should use it safely. But not all advice in this piece is equally strong. 1. RS256 vs ES256 - you shouldn't use either. RS256 not just an old standard on the way out. With safe keys sizes tokens are often going to be too large and signing too slow for you. ES256 on the other hand, suffers from many theoretical flaws and at least one practical flaw that (complete b…

Nonce reuse is easily preventable with deterministic nonces or sufficient randomness. PS3 used a fixed nonce which is a whole different problem. I agree that JWT has all sorts of flexibility that make it hard to use well but NIST curves work just fine. If you think they are backdoored then sure, Ed25519 is a better option but real world constraints may require you to use a NIST curve for now.

I don't think the NIST curves are backdoored, but they obviously have some serious theoretical and practical issues. [1]

As far as I know, neither of these issues is relevant to their usage with ECDSA (although invalid curve attacks should be a good enough reason to avoid using these curves with ECDH completely), but experience with SHA-1 and RC4 has thought us that algorithms with theoretical problems are likely to be practically broken sooner or later.

But NIST curves are not even the main issue with the ES* algorithms in JWT. The real issue is ECDSA:

1. Verification is slow. P-256 is about 2-4 times slower than Ed25519 [2]. This kind of speed hit may often be unacceptable. 2. Nonce reuse is an issue. The PS3 implementation was extremely bad, but random number generators can often be broken. This is not a theoretical issue - it used to happen verify often with docker containers until recently. There are alternative schemes that allow using ECDSA with a deterministic synthetic nonce [3], but this is not supported by any JWT implementation I know of. Ed25519, on the other hand, uses a synthetic nonce.

[1] https://safecurves.cr.yp.to/ [2] https://bench.cr.yp.to/results-sign.html [3] https://tools.ietf.org/html/rfc6979

Post reply on HN