Your question
I've been looking through the documentation to see if there were specifics around what the three next-auth cookies were used for and what details were stored in each. I didn't find answers to everything I was curious about.
I know (or have made the assumptions) that:
session-token cookiecsrf-token is a relatively standard implementation of this functionality, preventing attacks/supporting scenarios as detailed here https://stackoverflow.com/q/20504846/1763258I'm still wondering/would like to confirm:
session-token cookie?csrf-token cookie?callback-url cookie used, and what is stored in it?What are you trying to do
I'd like to be able to provide as much comprehensive detail as possible to security teams/auditors.
Documentation feedback
Documentation refers to searching through online documentation, code comments and issue history. The example project refers to next-auth-example.
This is a fantastic set of questions and deserves to be written up somewhere more permanently, but here is a quick reply from memory:
I know (or have made the assumptions) that:
- The cookies are signed with the secret I provide
- Any tokens in the cookies are hashed using the secret I provide
I'll answer these together.
In v3 there are currently only 3 cookies (less than in v2):
The value in callbackUrl is always checked before it is used so there is limited value in signing it, but it's not a terrible idea, now that in v3 it can only be set via POST (using request with CSRF Token).
The JWT is signed by the random Session ID token is not. There might be some benefit in also signing it as it would avoid an extra database call to look up a token that is fake (reducing a DDoS vector).
- The JWT is stored in the
session-tokencookie
Yes.
Note: Version 3 uses a better JWS implementation and signing only by default
jwt: { encryption: true }). If keys are not configured, it uses a different AES asymmetric key, also ultimately derived from the secret.
- The
csrf-tokenis a relatively standard implementation of this functionality, preventing attacks/supporting scenarios as detailed here https://stackoverflow.com/q/20504846/1763258
Yes - specifically the 'Request Body Approach' detailed there.
Note: Not all routes were protected in v2, but this has been extended in v3 to cover sign in as well (often with OAuth this a GET request as it's often just in the form of a link, but is now an HTTP POST with CSRF Token required for all flows). The built-in sign in pages and the client signIn() method hide this complexity.
I'm still wondering/would like to confirm:
- Are my assumptions above are correct?
- Although they are signed, the cookies are not encrypted, and anything not hashed can be read?
- Is there anything not hashed stored in the cookies?
session-token cookie?Session Token cookie is either a random Session ID (if using database sessions) or a JWT (if using JWT sessions)
The JWT in v3 includes JWT claims for name, email and avatar; but the contents is customisable.
- What else (besides token), if anything, is stored on the
csrf-tokencookie?
Only the token and a signature for the token (hashed with the secret).
- How is the
callback-urlcookie used, and what is stored in it?
The callback URL set before the user started their sign in journey so that they are returned to the same page after signing in.
The value is checked to see if it is allowed before it is stored AND AGAIN before it is used. By default any same site URL is valid, but a custom redirect() callback can be specified.
It is used because not all providers support keeping track of a state parameter passed to them; and there are security issues that can arise with those that do support this.
- Will any of the above assumptions or answers change between current v2 implementation and upcoming v3 implementation?
tl;dr
Happy to answer any followup questions.
If a team are evaluating this, I would suggest against the v3 beta or - if they don't want to do that - hold off for a week or two until it's released (I don't think it will be long now).
This is amazing, thanks for the detailed response!
I'll take your advice & look into the v3 beta and hold off on any formal internal review until after that is released.
I'm curious about setting the domain in the cookie. It sounds the domain in the cookie is generated from the environmental variable. I'm looking to generate a cookie that can be shared between this site and a subdomain (like .mydomain.com) but I'm having trouble setting this. I've tried generating my own cookies and it has been troublesome as the page mentions (https://next-auth.js.org/configuration/options#usesecurecookies). If it is an environmental variable I can't use .domain.com since that will break everything else.
What is the best approach to expanding this? My goal is to get a cookie which can be passed to api.domain.com as well. Is it to use custom cookies? Just using the code from the cookie page doesn't seem to work (they aren't setting). Thanks.
Hi there! It looks like this issue hasn't had any activity for a while. It will be closed if no further activity occurs. If you think your issue is still relevant, feel free to comment on it to keep ot open. Thanks!
Hi there! It looks like this issue hasn't had any activity for a while. To keep things tidy, I am going to close this issue for now. If you think your issue is still relevant, just leave a comment and I will reopen it. (Read more at #912) Thanks!
Most helpful comment
This is a fantastic set of questions and deserves to be written up somewhere more permanently, but here is a quick reply from memory:
I'll answer these together.
In v3 there are currently only 3 cookies (less than in v2):
The value in
callbackUrlis always checked before it is used so there is limited value in signing it, but it's not a terrible idea, now that in v3 it can only be set via POST (using request with CSRF Token).The JWT is signed by the random Session ID token is not. There might be some benefit in also signing it as it would avoid an extra database call to look up a token that is fake (reducing a DDoS vector).
Yes.
Note: Version 3 uses a better JWS implementation and signing only by default
jwt: { encryption: true }). If keys are not configured, it uses a different AES asymmetric key, also ultimately derived from the secret.Yes - specifically the 'Request Body Approach' detailed there.
Note: Not all routes were protected in v2, but this has been extended in v3 to cover sign in as well (often with OAuth this a GET request as it's often just in the form of a link, but is now an HTTP POST with CSRF Token required for all flows). The built-in sign in pages and the client
signIn()method hide this complexity.> * What else (besides token), if anything, is stored in the
session-tokencookie?Session Token cookie is either a random Session ID (if using database sessions) or a JWT (if using JWT sessions)
The JWT in v3 includes JWT claims for name, email and avatar; but the contents is customisable.
Only the token and a signature for the token (hashed with the secret).
The callback URL set before the user started their sign in journey so that they are returned to the same page after signing in.
The value is checked to see if it is allowed before it is stored AND AGAIN before it is used. By default any same site URL is valid, but a custom
redirect()callback can be specified.It is used because not all providers support keeping track of a state parameter passed to them; and there are security issues that can arise with those that do support this.
tl;dr
Happy to answer any followup questions.
If a team are evaluating this, I would suggest against the v3 beta or - if they don't want to do that - hold off for a week or two until it's released (I don't think it will be long now).