Skip to main content

Session security

Overview

The following page takes you through some common security considerations that the SuperTokens Session recipe handles.

Anti-csrf

CSRF attacks can happen if a logged in user visits a malicious website which makes an API call to your website's API to maliciously change that user's data. To protect against this attack, the cookie sameSite attribute works along with some anti-csrf measures. This attribute declares if your cookies should restrict to a first-party or same-site context. Configuring sameSite can prevent CSRF attacks.

For example, if sameSite is lax, the browser only sends cookies for requests that originate from the same top level domain as the API's domain. If a user visits a malicious site, requests from those sites do not have the session cookies.

Configure anti-csrf

caution
  • SuperTokens automatically defends against CSRF attacks.
  • Please only change this setting if you know what you are doing. If you are unsure, please feel free to ask questions.
  • This setting does not apply while using header-based authentication, since they get the same protection as antiCsrf set to VIA_CUSTOM_HEADER.

You can change the antiCsrf configuration option to take control of the kind of protection you get. You can use on of the following values:

  • "NONE" would disable any anti-csrf protection from our end. You can use this if you have an implementation of CSRF protection.
  • "VIA_CUSTOM_HEADER" uses this method to prevent CSRF protection. This sets automatically if sameSite is none or if your apiDomain and websiteDomain do not share the same top level domain name.
  • "VIA_TOKEN" uses an explicit anti-csrf token. Use this method if you want to allow any origin to query your APIs. This method may cause issues in browsers like Safari, especially if your site embeds as an iframe.
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
Session.init({
antiCsrf: "VIA_CUSTOM_HEADER", // Should be one of "NONE" or "VIA_CUSTOM_HEADER" or "VIA_TOKEN"
})
]
});

Per GDPR, users do not need to give consent for your application to use session cookies. This is because they fall under essential cookies and not tracking cookies:

Important

"While it is not required to obtain consent for these cookies, explain to the user what they do and why they are necessary."

Same site cookies

To ensure session cookies have protection from CSRF attacks, the sameSite cookie attribute ensures this protection. The sameSite cookie attribute declares if your cookies should restrict to a first-party or same-site context. The sameSite attribute can have three possible values:

  • none
    • Cookies attach in all contexts, that is, cookies attach to both first-party and cross-origin requests.
    • On Safari however, if third-party cookies do not work (which is the default behavior), and the website and API domains do not share the same top-level domain, then cookies do not go. Please check the session management page to see how you can switch to using headers.
  • lax
    • Cookies are only sent in a first-party context and along with GET requests initiated by third party websites (that result in browser navigation - user clicking on a link).
  • strict
    • Cookies are only sent in a first-party context and not sent along with requests initiated by third party websites.

Configuration

caution
  • SuperTokens automatically sets the value of the sameSite cookie attribute based on your website and API domain configuration.
  • Please only change this setting if you are a web security expert. If you are unsure, please feel free to ask questions.
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
Session.init({
cookieSameSite: "strict", // Should be one of "strict" or "lax" or "none"
}),
],
});

Cookies and HTTPS

SuperTokens ensures that cookies have security by enabling the secure flag when generating session cookies. When set, the secure attribute limits the scope of the cookie to attach only to secure domains. This results in the cookie only attaching to requests transmitted over https. This, in turn, prevents cookie theft via man in the middle attacks.

You can explicitly set the security level of cookies using the next snippet:

important

If not explicitly set, SuperTokens automatically determines the value for the secure attribute based on your API domain having http or https.

import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
Session.init({
cookieSecure: true,
})
]
});

Access Token signing key rotation

Access Token signing key rotation implies that the secret key for signing the access tokens changes at a fixed time interval. This reduces the risk of key theft.

info
  • Existing logged in users are not logged out on key change.
  • This feature enables by default.

Change the key rotation interval

docker run \
-p 3567:3567 \
// highlight-start
-e ACCESS_TOKEN_DYNAMIC_SIGNING_KEY_UPDATE_INTERVAL=168 \
// highlight-end
-d registry.supertokens.io/supertokens/supertokens-<db name>
  • access_token_dynamic_signing_key_update_interval
    • Time in hours for how frequently the signing key changes.
    • It must have a number value with, the default value set to 168
info

For managed service, update this value by visiting the dashboard.

Use static keys

If you do not want to use dynamic keys for session creation, then you can tell SuperTokens to use the static key instead. This is useful in cases where you want to hard-code the public key for JWT verification in some process.

import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
supertokens: {
connectionURI: "...",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
Session.init({
useDynamicAccessTokenSigningKey: false,
})
]
});
caution

Updating this value causes a spike in the session refresh API, as and when users visit your application.

See also