From 7ec54911d617f113dae5a735a9b2007ddc7405e7 Mon Sep 17 00:00:00 2001 From: Matthew Elwell Date: Tue, 27 Feb 2024 09:10:25 +0000 Subject: [PATCH] feat: add option to disable secure cookies and configure `samesite` (#3441) --- api/app/settings/common.py | 2 ++ api/app/views.py | 2 ++ docs/docs/deployment/hosting/locally-frontend.md | 5 +++++ frontend/api/index.js | 2 ++ frontend/env/project_dev.js | 1 + frontend/env/project_e2e.js | 1 + frontend/env/project_local.js | 1 + frontend/env/project_prod.js | 1 + frontend/env/project_selfhosted.js | 1 + frontend/env/project_staging.js | 1 + frontend/web/project/api.js | 4 ++-- 11 files changed, 19 insertions(+), 2 deletions(-) diff --git a/api/app/settings/common.py b/api/app/settings/common.py index 13a69bf067f4..ca976297ef68 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -878,6 +878,8 @@ SENTRY_API_KEY = env("SENTRY_API_KEY", default=None) AMPLITUDE_API_KEY = env("AMPLITUDE_API_KEY", default=None) ENABLE_FLAGSMITH_REALTIME = env.bool("ENABLE_FLAGSMITH_REALTIME", default=False) +USE_SECURE_COOKIES = env.bool("USE_SECURE_COOKIES", default=True) +COOKIE_SAME_SITE = env.str("COOKIE_SAME_SITE", default="none") # Set this to enable create organisation for only superusers RESTRICT_ORG_CREATE_TO_SUPERUSERS = env.bool("RESTRICT_ORG_CREATE_TO_SUPERUSERS", False) diff --git a/api/app/views.py b/api/app/views.py index 8e1198ed16b0..197ef359898a 100644 --- a/api/app/views.py +++ b/api/app/views.py @@ -53,6 +53,8 @@ def project_overrides(request): "preventEmailPassword": "PREVENT_EMAIL_PASSWORD", "preventSignup": "PREVENT_SIGNUP", "sentry": "SENTRY_API_KEY", + "useSecureCookies": "USE_SECURE_COOKIES", + "cookieSameSite": "COOKIE_SAME_SITE", } override_data = { diff --git a/docs/docs/deployment/hosting/locally-frontend.md b/docs/docs/deployment/hosting/locally-frontend.md index b633192daed1..2a4dda29b8a9 100644 --- a/docs/docs/deployment/hosting/locally-frontend.md +++ b/docs/docs/deployment/hosting/locally-frontend.md @@ -95,6 +95,11 @@ Current variables used between 'frontend/environment.js' and 'frontend/common/pr - `STATIC_ASSET_CDN_URL`: Used for replacing local static paths with a cdn, .e.g https://cdn.flagsmith.com. Defaults to `/`, i.e. no CDN. - `BASE_URL`: Used for specifying a base url path that's ignored during routing if serving from a subdirectory. +- `USE_SECURE_COOKIES`: Enable / disable the use of secure cookies. If deploying the FE in a private network without a + domain / SSL cert, disable secure cookies to ensure that session token is persisted. Default: true. +- `COOKIE_SAME_SITE`: Define the value of the samesite attribute for the session token cookie set by the frontend. + Further reading on this value is available [here](https://web.dev/articles/samesite-cookies-explained). Default: + 'none'. ## E2E testing diff --git a/frontend/api/index.js b/frontend/api/index.js index a41264238e85..c05af4b9eb4d 100755 --- a/frontend/api/index.js +++ b/frontend/api/index.js @@ -113,6 +113,8 @@ app.get('/config/project-overrides', (req, res) => { value: envToBool('DISABLE_INVITE_LINKS', false), }, { name: 'albacross', value: process.env.ALBACROSS_CLIENT_ID }, + {name: 'useSecureCookies', value: envToBool('USE_SECURE_COOKIES', true)}, + {name: 'cookieSameSite', value: process.env.USE_SECURE_COOKIES} ] let output = values.map(getVariable).join('') let dynatrace = '' diff --git a/frontend/env/project_dev.js b/frontend/env/project_dev.js index 7d1067567819..23f61a13ecb8 100644 --- a/frontend/env/project_dev.js +++ b/frontend/env/project_dev.js @@ -16,5 +16,6 @@ module.exports = global.Project = { flagsmithClientEdgeAPI: 'https://edge.bullet-train-staging.win/api/v1/', // This is used for Sentry tracking maintenance: false, + useSecureCookies: true, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/env/project_e2e.js b/frontend/env/project_e2e.js index 1a22f4a74272..5ba0ec03e362 100644 --- a/frontend/env/project_e2e.js +++ b/frontend/env/project_e2e.js @@ -18,5 +18,6 @@ module.exports = global.Project = { flagsmithClientEdgeAPI: 'https://edge.api.flagsmith.com/api/v1/', // This is used for Sentry tracking maintenance: false, + useSecureCookies: true, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/env/project_local.js b/frontend/env/project_local.js index 618b0cb0ff75..c3a86d7453ff 100644 --- a/frontend/env/project_local.js +++ b/frontend/env/project_local.js @@ -16,5 +16,6 @@ module.exports = global.Project = { flagsmithClientEdgeAPI: 'https://edge.api.flagsmith.com/api/v1/', // This is used for Sentry tracking maintenance: false, + useSecureCookies: false, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/env/project_prod.js b/frontend/env/project_prod.js index 5511303a4684..d6052afb3b23 100644 --- a/frontend/env/project_prod.js +++ b/frontend/env/project_prod.js @@ -22,5 +22,6 @@ module.exports = global.Project = { flagsmithClientEdgeAPI: 'https://edge.api.flagsmith.com/api/v1/', // This is used for Sentry tracking maintenance: false, + useSecureCookies: true, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/env/project_selfhosted.js b/frontend/env/project_selfhosted.js index 3eb6ffcd91fa..42e3f35f9388 100644 --- a/frontend/env/project_selfhosted.js +++ b/frontend/env/project_selfhosted.js @@ -8,5 +8,6 @@ module.exports = global.Project = { // This is used for Sentry tracking maintenance: false, + useSecureCookies: true, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/env/project_staging.js b/frontend/env/project_staging.js index 7d1067567819..23f61a13ecb8 100644 --- a/frontend/env/project_staging.js +++ b/frontend/env/project_staging.js @@ -16,5 +16,6 @@ module.exports = global.Project = { flagsmithClientEdgeAPI: 'https://edge.bullet-train-staging.win/api/v1/', // This is used for Sentry tracking maintenance: false, + useSecureCookies: true, ...(globalThis.projectOverrides || {}), } diff --git a/frontend/web/project/api.js b/frontend/web/project/api.js index 813cba854433..59257900ce01 100644 --- a/frontend/web/project/api.js +++ b/frontend/web/project/api.js @@ -237,8 +237,8 @@ global.API = { require('js-cookie').set(key, v, { expires: 30, path: '/', - sameSite: 'none', - secure: true, + sameSite: Project.cookieSameSite || 'none', + secure: Project.useSecureCookies, }) } }