Sécurité

Veilige cookies: de technische gids

Beveilig uw cookies tegen diefstal en manipulatie. HttpOnly, Secure, SameSite en meer — technische best practices.

28 mars 20264 min de lectureWarDek Team

Waarom cookie-beveiliging belangrijk is

Cookies zijn het primaire mechanisme voor sessiebeheer op het web. Een sessiecookie die in verkeerde handen valt, geeft een aanvaller directe toegang tot het account van het slachtoffer — zonder wachtwoord, zonder MFA. Cookie-beveiliging is daarom een fundamenteel onderdeel van elke webapplicatie.

De vier essentiële cookie-attributen

1. HttpOnly

Set-Cookie: session=abc123; HttpOnly

Wat het doet: voorkomt dat JavaScript de cookie kan lezen via document.cookie.

Bescherming tegen: XSS-gebaseerde sessiediefstal. Zelfs als een aanvaller JavaScript kan injecteren, kan het sessiecookie niet worden geëxfiltreerd.

Wanneer gebruiken: altijd voor sessiecookies en authenticatietokens. Laat dit attribuut alleen weg als JavaScript de cookie daadwerkelijk moet lezen (bijv. een voorkeurscookie voor taal of thema).

2. Secure

Set-Cookie: session=abc123; Secure

Wat het doet: de cookie wordt alleen verzonden over HTTPS-verbindingen.

Bescherming tegen: man-in-the-middle aanvallen op onbeveiligde verbindingen. Zonder dit attribuut kan een aanvaller op hetzelfde netwerk (bijv. openbaar WiFi) het cookie onderscheppen.

Wanneer gebruiken: altijd in productie. In ontwikkeling (localhost) kan het worden weggelaten, maar zorg dat uw code het automatisch instelt op basis van de omgeving.

3. SameSite

Set-Cookie: session=abc123; SameSite=Strict

Wat het doet: bepaalt of de cookie wordt meegezonden bij cross-site requests.

WaardeGedrag
StrictCookie wordt nooit meegezonden bij cross-site requests
LaxCookie wordt meegezonden bij top-level navigatie (links) maar niet bij POST/iframe/AJAX
NoneCookie wordt altijd meegezonden (vereist Secure attribuut)

Bescherming tegen: Cross-Site Request Forgery (CSRF). Met Strict of Lax kan een kwaadaardige website geen acties uitvoeren namens de ingelogde gebruiker.

Aanbeveling: Strict voor sessiecookies. Lax als u inkomende links vanaf andere sites moet ondersteunen met behoud van sessie. None alleen als u cross-site embedding nodig heeft (bijv. betaalwidgets in iframes).

4. Path en Domain

Set-Cookie: session=abc123; Path=/; Domain=example.nl
AttribuutAanbeveling
PathZo specifiek mogelijk. / voor sessiecookies, /api voor API-tokens
DomainLaat leeg (standaard: exact het huidige domein) tenzij u subdomeinen moet ondersteunen

Volledige veilige cookie-configuratie

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=86400

Implementatievoorbeelden

Express.js (Node.js):

app.use(session({
  cookie: {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 24 * 60 * 60 * 1000, // 24 uur
    path: '/',
  },
  // ... overige sessieconfiguratie
}));

Next.js (API route):

import { cookies } from 'next/headers';

cookies().set('session', token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'strict',
  maxAge: 86400,
  path: '/',
});

Django (Python):

# settings.py
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'Strict'
SESSION_COOKIE_AGE = 86400
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True

Cookie-prefixen

Moderne browsers ondersteunen cookie-prefixen die extra beperkingen afdwingen:

PrefixVereisten
__Secure-Cookie moet Secure attribuut hebben en via HTTPS zijn gezet
__Host-Cookie moet Secure hebben, geen Domain, en Path=/
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/

__Host- is de strengste optie en voorkomt dat het cookie per ongeluk beschikbaar wordt op subdomeinen.

Sessiebeveiliging

Naast cookie-attributen zijn er aanvullende maatregelen voor sessiebeheer:

Sessiefixatie voorkomen

Genereer na succesvolle authenticatie altijd een nieuw sessie-ID:

// Na succesvolle login
req.session.regenerate((err) => {
  req.session.userId = user.id;
  // Gebruik het nieuwe sessie-ID
});

Sessie-timeout

Stel twee types timeout in:

TypeAanbevelingVoorbeeld
Inactiviteitstimeout15-30 minuten voor gevoelige applicatiesBankingapp: 15 min
Absolute timeout8-24 uur maximum sessielevensduurSaaS-app: 24 uur

Token-rotatie

Vernieuw sessietokens periodiek zonder de gebruiker uit te loggen:

// Elke 15 minuten een nieuw token
if (session.lastRotation < Date.now() - 15 * 60 * 1000) {
  session.regenerate();
  session.lastRotation = Date.now();
}

Third-party cookies: het einde

Browsers beperken steeds meer de functionaliteit van third-party cookies:

BrowserStatus third-party cookies
SafariGeblokkeerd sinds 2020 (ITP)
FirefoxGeblokkeerd (Enhanced Tracking Protection)
ChromeGeleidelijke beperking via Privacy Sandbox

Impact: als u afhankelijk bent van third-party cookies voor tracking, analytics of authenticatie, bereid u dan voor op alternatieven:

  • First-party tracking
  • Server-side analytics
  • OAuth/OIDC voor cross-domain authenticatie

Veelgemaakte fouten

FoutRisico
Sessiecookie zonder HttpOnlyXSS leidt tot sessiediefstal
Secure ontbreekt in productieCookie zichtbaar op HTTP
SameSite niet ingesteldCSRF-kwetsbaarheid
Te lange sessie-levensduurVergroot exploitatievenster
Geen sessie-regeneratie na loginSessiefixatie-aanval mogelijk
Gevoelige data in cookie-waardeCookie-inhoud is leesbaar en manipuleerbaar
JWT in localStorageToegankelijk via XSS (gebruik HttpOnly cookie)

Cookie-audit checklist

  • Alle sessiecookies hebben HttpOnly
  • Alle cookies in productie hebben Secure
  • SameSite is ingesteld op Strict of Lax
  • Cookie-levensduur is beperkt (geen permanente sessies)
  • Sessie-ID wordt geregenereerd na login
  • Geen gevoelige data in cookie-waarden opgeslagen
  • Cookie-prefixen gebruikt waar mogelijk
  • Third-party cookie afhankelijkheden in kaart gebracht

Scan uw website gratis met WarDek — OWASP, NIS2, AVG, AI Act compliance in één scan.

#cookies#beveiliging#sessies#webapplicaties

Scannez votre site gratuitement

WarDek détecte les vulnérabilités mentionnées dans cet article en quelques secondes.