I cookie sono il meccanismo fondamentale per gestire sessioni, preferenze e autenticazione sul web. Ma un cookie mal configurato è un regalo per gli attaccanti: furto di sessione, CSRF, tracking non autorizzato. Ecco come configurarli correttamente.
I flag di sicurezza essenziali
Secure
Set-Cookie: session=abc123; Secure
Il cookie viene trasmesso solo via HTTPS. Senza questo flag, il cookie può essere intercettato su connessioni HTTP non cifrate (attacco man-in-the-middle).
Regola: tutti i cookie devono avere il flag Secure in produzione. Nessuna eccezione.
HttpOnly
Set-Cookie: session=abc123; HttpOnly
Il cookie non è accessibile via JavaScript (document.cookie). Questo impedisce il furto del cookie tramite attacchi XSS.
Regola: tutti i cookie di sessione e autenticazione devono essere HttpOnly. Solo i cookie che devono essere letti da JavaScript (es. preferenze UI) possono non averlo.
SameSite
Set-Cookie: session=abc123; SameSite=Strict
Controlla quando il cookie viene inviato nelle richieste cross-site:
| Valore | Comportamento | Uso consigliato |
|--------|--------------|-----------------|
| Strict | Mai inviato in richieste cross-site | Cookie di sessione, autenticazione |
| Lax | Inviato solo in navigazione top-level (link, GET) | Default ragionevole |
| None | Sempre inviato (richiede Secure) | Solo per servizi cross-site (SSO, embed) |
SameSite=Strict è la protezione CSRF più efficace:
- L'utente clicca un link malevolo che fa una richiesta POST al vostro sito
- Con
SameSite=Strict, il cookie di sessione NON viene inviato - La richiesta arriva senza autenticazione → bloccata
Path e Domain
Set-Cookie: session=abc123; Path=/app; Domain=.example.it
| Attributo | Funzione | Consiglio |
|-----------|----------|-----------|
| Path | Limita il cookie a un percorso | Usate / o il percorso minimo necessario |
| Domain | Estende il cookie ai sottodomini | Omettete per limitare al dominio esatto |
Max-Age e Expires
Set-Cookie: session=abc123; Max-Age=3600
| Tipo | Durata | Uso | |------|--------|-----| | Cookie di sessione | Nessun Max-Age/Expires (eliminato alla chiusura del browser) | Sessioni sensibili | | Cookie persistente | Max-Age definito | "Ricordami", preferenze |
Regola: durata proporzionata alla sensibilità. Un cookie di sessione bancaria non dovrebbe durare 30 giorni.
Configurazione completa per tipo di cookie
Cookie di sessione (autenticazione)
Set-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Strict; Path=/; Max-Age=1800
Secure: solo HTTPSHttpOnly: non accessibile da JavaScriptSameSite=Strict: protezione CSRF completaMax-Age=1800: 30 minuti di validità
Cookie "Ricordami"
Set-Cookie: remember_token=xyz789; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=2592000
SameSite=Lax: permette la navigazione da link esterni (UX)Max-Age=2592000: 30 giorni- Associato a un token nel database (revocabile)
Cookie CSRF
Set-Cookie: csrf_token=def456; Secure; SameSite=Strict; Path=/
- Non
HttpOnly: deve essere leggibile da JavaScript per essere incluso negli header SameSite=Strict: doppia protezione CSRF
Cookie di preferenze
Set-Cookie: theme=dark; Secure; SameSite=Lax; Path=/; Max-Age=31536000
- Non
HttpOnly: deve essere leggibile dal frontend Max-Age=31536000: 1 anno- Nessun dato sensibile
Implementazione nei framework
Express.js
app.use(session({
cookie: {
secure: true, // Solo HTTPS
httpOnly: true, // Non accessibile da JS
sameSite: 'strict', // Protezione CSRF
maxAge: 30 * 60 * 1000, // 30 minuti
path: '/',
},
// ... altre opzioni
}))
Next.js (API routes)
export async function POST(req: Request) {
const response = NextResponse.json({ success: true })
response.cookies.set('session', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 60 * 30, // 30 minuti in secondi
path: '/',
})
return response
}
Attacchi basati sui cookie
1. Furto di sessione via XSS
Attacco: uno script XSS legge document.cookie e lo invia all'attaccante.
Difesa: HttpOnly su tutti i cookie di sessione.
2. Session fixation
Attacco: l'attaccante forza un ID di sessione noto alla vittima, poi usa lo stesso ID.
Difesa: rigenerare l'ID di sessione dopo il login.
// Dopo autenticazione riuscita
req.session.regenerate((err) => {
// Nuova sessione con nuovo ID
})
3. CSRF (Cross-Site Request Forgery)
Attacco: un sito malevolo induce il browser a inviare una richiesta autenticata.
Difese combinate:
SameSite=StrictoLax- Token CSRF nel form + verifica lato server
- Verifica header
Origin/Referer
4. Cookie tossing
Attacco: un sottodominio compromesso imposta un cookie per il dominio principale.
Difesa: usare il prefisso __Host- per i cookie sensibili:
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/
I cookie con prefisso __Host- devono essere Secure, avere Path=/ e non avere un attributo Domain.
Audit dei cookie
Verifica manuale
- Aprite il DevTools del browser (F12)
- Andate su Application → Cookies
- Per ogni cookie, verificate i flag di sicurezza
Verifica automatizzata
Usate un scanner di sicurezza per verificare automaticamente:
- Flag mancanti sui cookie di sessione
- Cookie con durata eccessiva
- Cookie senza
Securein produzione - Cookie di sessione senza
HttpOnly
Checklist sicurezza cookie
- [ ] Tutti i cookie con flag
Securein produzione - [ ] Cookie di sessione con
HttpOnly - [ ]
SameSite=Strictsui cookie di autenticazione - [ ] Durata (Max-Age) proporzionata alla sensibilità
- [ ] Rigenerazione dell'ID sessione dopo il login
- [ ] Prefisso
__Host-sui cookie più sensibili - [ ] Nessun dato sensibile nel valore del cookie
- [ ] Token CSRF per le operazioni di modifica
- [ ] Audit periodico dei cookie impostati
Conclusione
La configurazione sicura dei cookie è una delle misure con il miglior rapporto costo-efficacia. Tre flag (Secure, HttpOnly, SameSite=Strict) bloccano le tre categorie di attacchi più comuni sui cookie. Non c'è ragione per non implementarli oggi.
Scansiona il tuo sito web gratis con WarDek — OWASP, NIS2, GDPR, AI Act in un'unica scansione.