From 59791df2483f6a1e8f2c8309d6daf8dbdc58ee3c Mon Sep 17 00:00:00 2001 From: Ulas Date: Wed, 1 Apr 2026 18:34:31 +0200 Subject: [PATCH] fix: enforce Secure flag on session and CSRF cookies by default Cookies were sent without Secure flag outside of production (NODE_ENV check). New logic: secure=true by default; set SESSION_SECURE=false in .env to allow HTTP explicitly (local dev without reverse proxy). Affects session cookie, CSRF cookie in login handler, and CSRF middleware. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 3 +++ server/auth.js | 9 +++------ server/middleware/csrf.js | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebdfcb9..c1f226a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Security +- Session and CSRF cookies now have `secure: true` by default; HTTP is only allowed when `SESSION_SECURE=false` is explicitly set in `.env` — previously cookies were sent without `Secure` flag in non-production environments + ## [0.5.2] - 2026-04-01 ### Security diff --git a/server/auth.js b/server/auth.js index 64e5167..85a2434 100644 --- a/server/auth.js +++ b/server/auth.js @@ -103,10 +103,8 @@ const sessionMiddleware = session({ name: 'oikos.sid', cookie: { httpOnly: true, - // SESSION_SECURE=false in .env erlaubt HTTP-Zugriff (z.B. direktes localhost ohne Reverse Proxy) - // Ohne diese Variable: secure=true wenn NODE_ENV=production - secure: process.env.SESSION_SECURE === 'false' ? false - : process.env.NODE_ENV === 'production', + // secure=true by default; set SESSION_SECURE=false in .env to allow HTTP (local dev without reverse proxy) + secure: process.env.SESSION_SECURE !== 'false', sameSite: 'strict', maxAge: 1000 * 60 * 60 * 24 * 7, // 7 Tage in ms }, @@ -193,8 +191,7 @@ router.post('/login', loginLimiter, async (req, res) => { res.cookie('csrf-token', req.session.csrfToken, { httpOnly: false, sameSite: 'strict', - secure: process.env.SESSION_SECURE === 'false' ? false - : process.env.NODE_ENV === 'production', + secure: process.env.SESSION_SECURE !== 'false', maxAge: 1000 * 60 * 60 * 24 * 7, }); diff --git a/server/middleware/csrf.js b/server/middleware/csrf.js index fcb301a..0724d98 100644 --- a/server/middleware/csrf.js +++ b/server/middleware/csrf.js @@ -39,8 +39,7 @@ function csrfMiddleware(req, res, next) { res.cookie('csrf-token', req.session.csrfToken, { httpOnly: false, sameSite: 'strict', - secure: process.env.SESSION_SECURE === 'false' ? false - : process.env.NODE_ENV === 'production', + secure: process.env.SESSION_SECURE !== 'false', maxAge: 1000 * 60 * 60 * 24 * 7, // 7 Tage (gleich wie Session) });