Cookie-Sicherheit für Express.js konfigurieren

Schritt-für-Schritt-Anleitung: Secure, HttpOnly und SameSite in Express.js einrichten — mit express-session, globaler Cookie-Middleware und fertigen Code-Snippets zum Kopieren.

Express · Schritt für Schritt

Sichere Cookies in Express.js

Express.js setzt keine sicheren Cookie-Flags automatisch — weder express-session noch helmet.js übernehmen das für Sie. Jeder Cookie muss manuell mit Secure, HttpOnly und SameSite abgesichert werden. Mit der richtigen Session-Konfiguration und einer globalen Middleware lässt sich das aber einmalig lösen.

Sichere Cookies bringen 15 von 166 Punkten im Wolf-Agents Web Security Check. Diese Anleitung zeigt die Konfiguration in vier Schritten: von der express-session-Absicherung über eine globale Cookie-Middleware bis zur Verifizierung in Development und Production. Alle Beispiele berücksichtigen den typischen Reverse-Proxy-Betrieb hinter Nginx.

1 Schritt 1 von 4

express-session mit sicheren Cookie-Defaults

Das cookie-Objekt in der express-session-Konfiguration steuert alle Attribute des Session-Cookies. Entscheidend: secure sollte über process.env.NODE_ENV gesteuert werden, damit das Development nicht blockiert wird. Das Secure-Flag schlägt im Reverse-Proxy-Betrieb fehl, wenn trust proxy nicht gesetzt ist.

server.js / app.js express-session
// package.json: npm install express-session
const session = require('express-session');

app.use(session({
  name: 'session',
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production', // Nur HTTPS
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 1000 * 60 * 60 * 24 * 7, // 7 Tage in ms
  }
}));

// Hinter einem Reverse Proxy (Nginx, Traefik, AWS ALB)?
// Ohne trust proxy wird Secure nie gesetzt!
app.set('trust proxy', 1);
Warum setzt helmet.js keine Cookie-Flags?

helmet.js setzt HTTP-Response-Header wie CSP, HSTS oder X-Frame-Options — aber keine Set-Cookie-Attribute. Cookie-Sicherheit ist Aufgabe der Session-Konfiguration und Ihrer Middleware, nicht von Helmet. Beides ergänzt sich und sollte kombiniert werden.

Session-Secret aus Umgebungsvariable laden:
SESSION_SECRET=$(openssl rand -hex 32) node server.js
2 Schritt 2 von 4

Globale Cookie-Middleware für alle Cookies

express-session sichert nur das Session-Cookie. Alle anderen Cookies — Auth-Token, CSRF-Token, Präferenzen — müssen separat abgesichert werden. Eine globale Middleware, die res.cookie() überschreibt, löst das Problem einmalig für die gesamte Anwendung: Jeder Cookie-Aufruf erhält automatisch sichere Defaults.

middleware/secure-cookies.js Middleware
// npm install cookie-parser
const cookieParser = require('cookie-parser');
app.use(cookieParser());

// Globale Middleware: alle res.cookie()-Aufrufe absichern
app.use((req, res, next) => {
  const originalSetCookie = res.cookie.bind(res);

  res.cookie = (name, value, options = {}) => {
    return originalSetCookie(name, value, {
      ...options,
      secure: process.env.NODE_ENV === 'production',
      httpOnly: options.httpOnly !== false,
      sameSite: options.sameSite || 'strict',
    });
  };

  next();
});
Wert Cross-Site-Verhalten Empfehlung
Strict Cookie wird nie bei Cross-Site-Requests gesendet Session-Cookies, Auth-Token, Admin-Panels
Lax Cookie wird bei Top-Level-GET-Navigation gesendet Standard für die meisten Websites
None Cookie wird immer gesendet (benötigt Secure) Nur für Cross-Site-Embeds / OAuth-Flows
Bei E-Commerce mit Stripe oder PayPal: Setzen Sie SameSite=Lax für Session-Cookies, da Payment-Redirects die Session sonst verlieren. Nur hochsensitive Apps (Banking, Admin) sollten Strict nutzen.
3 Schritt 3 von 4

Cookie-Prefixes und SameSite-Strategie

Cookie-Prefixes sind ein Defense-in-Depth-Mechanismus: Der Browser erzwingt Attribute allein aufgrund des Cookie-Namens — unabhängig vom Server-Code. __Host- ist die strengste Option, da sie das Domain-Attribut komplett verbietet und Subdomain-Angriffe verhindert.

routes/auth.js Prefixes
// __Host- Prefix: strengster Schutz (kein domain-Attribut!)
res.cookie('__Host-session', sessionId, {
  secure: true,          // Pflicht für __Host-
  httpOnly: true,
  sameSite: 'strict',
  path: '/',              // Pflicht für __Host-
  // domain: NICHT setzen! (Pflicht für __Host-)
});

// __Secure- Prefix: erlaubt domain-Attribut
res.cookie('__Secure-token', token, {
  secure: true,
  httpOnly: true,
  sameSite: 'lax',
  domain: 'ihre-domain.de',
});

// SameSite-Strategie nach Cookie-Typ
// Session/Auth:   sameSite: 'strict'
// Standard:       sameSite: 'lax'
// Cross-Site/3rd: sameSite: 'none' + secure: true
Wenn Sie den Cookie-Namen ändern (z.B. session__Host-session), werden bestehende User-Sessions ungültig. Planen Sie die Umstellung mit einem Migrations-Window und informieren Sie Nutzer ggf. über eine erneute Anmeldung.
4 Schritt 4 von 4

Verifizierung im Development und Production

Testen Sie die Cookie-Flags sowohl im Development- als auch im Production-Modus. Das Secure-Flag ist im Development nicht aktiv — nutzen Sie NODE_ENV=production lokal, um das Production-Verhalten zu simulieren. Browser DevTools (Application → Cookies) zeigen alle Attribute visuell.

Terminal Verifizierung
# Development: HTTP-Flags prüfen (Secure nicht aktiv)
curl -sI http://localhost:3000/login | grep -i set-cookie

# Production: HTTPS-Flags prüfen
curl -sI https://ihre-domain.de/login | grep -i set-cookie

# Erwartete Ausgabe (Production):
# Set-Cookie: __Host-session=...; Path=/; HttpOnly; Secure; SameSite=Strict

# NODE_ENV lokal auf production setzen und testen:
NODE_ENV=production node server.js
Browser DevTools als Alternative

Öffnen Sie DevTools (F12) → Application → Cookies → Ihre Domain. Prüfen Sie die Spalten HttpOnly, Secure und SameSite für jeden Cookie. Session-Cookies müssen bei allen drei Spalten ein Häkchen zeigen.

Wie steht Ihre Domain bei Cookie-Sicherheit?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.

Häufig gestellte Fragen

Setzt helmet.js Cookie-Flags in Express automatisch?

Nein. helmet.js setzt viele HTTP-Security-Header (CSP, HSTS, X-Frame-Options), aber keine Cookie-Flags. Secure, HttpOnly und SameSite müssen Sie manuell in express-session oder in Ihrer Cookie-Middleware konfigurieren. Helmet und sichere Cookie-Konfiguration ergänzen sich — beides ist nötig.

Was ist der Unterschied zwischen express-session und manuell gesetzten Cookies?

express-session verwaltet Session-Daten serverseitig und setzt nur ein Session-ID-Cookie im Browser. Manuell gesetzte Cookies (res.cookie()) enthalten dagegen direkt Daten. Für beide gilt: Secure, HttpOnly und SameSite müssen explizit gesetzt werden. express-session hat dafür das cookie-Objekt in der Konfiguration, manuelle Cookies nutzen den Options-Parameter von res.cookie().

Was bedeutet trust proxy und wann brauche ich es?

Wenn Express hinter einem Reverse Proxy (Nginx, Traefik, AWS ALB) läuft, muss app.set('trust proxy', 1) gesetzt werden. Andernfalls erkennt Express keine HTTPS-Verbindung und das Secure-Flag wird nicht gesetzt — auch wenn der Client über HTTPS kommuniziert. Ohne trust proxy bleibt das Secure-Flag im Production-Betrieb wirkungslos.

Wie setze ich Cookie-Flags in Express.js?

In express-session setzen Sie die Flags im cookie-Objekt: { secure: true, httpOnly: true, sameSite: 'strict' }. Für einzelne Cookies nutzen Sie res.cookie('name', 'wert', { secure: true, httpOnly: true, sameSite: 'strict' }). Eine globale Middleware überschreibt res.cookie(), um die Flags automatisch für alle Cookies zu setzen.

Wie verhindere ich, dass das Secure-Flag im Development die Entwicklung blockiert?

Setzen Sie secure: process.env.NODE_ENV === 'production'. Damit ist das Secure-Flag nur im Production-Modus aktiv — im Development können Sie HTTP nutzen. Alternativ nutzen Sie mkcert für lokale HTTPS-Zertifikate, um Production-nah zu entwickeln.

Was ist der __Host- Prefix und wie nutze ich ihn in Express?

Der __Host- Prefix (z.B. __Host-session) ist der stärkste Cookie-Schutz: Der Browser erzwingt Secure, Path=/ und verhindert das Domain-Attribut. In Express setzen Sie den Prefix im Cookie-Namen: res.cookie('__Host-session', value, { secure: true, path: '/' }). Wichtig: Das domain-Attribut darf NICHT gesetzt sein.

Brauche ich cookie-parser, wenn ich express-session nutze?

Nicht zwingend. express-session verarbeitet das Session-Cookie selbst. cookie-parser ist nötig, wenn Sie andere Cookies aus req.cookies lesen wollen. Für die globale Cookie-Middleware (Überschreiben von res.cookie()) ist cookie-parser sinnvoll, aber technisch optional — die Middleware arbeitet auf Response-Ebene.