Cookie di sessione sicuri: i flag che l'IA può omettere nei progetti web
Generare un login con l'IA è facile, ma i flag HttpOnly, Secure e SameSite possono mancare. Come verificarli in DevTools e chiederli correttamente.
Quando chiedi a un’intelligenza artificiale di scriverti un sistema di login per la tua nuova app web, il risultato di solito funziona al primo colpo: l’utente inserisce la password, il server valida i dati, restituisce un cookie di sessione e l’utente risulta loggato.
C’è però una fallacia tipica del vibe coding (creare software delegando la logica all’IA): il modello può scrivere il minimo necessario per far funzionare l’app e omettere le configurazioni di sicurezza se non le chiedi in modo esplicito. Nei boilerplate che ho rivisto, i cookie di sessione escono così “nudi”, senza le protezioni di base.
Un cookie senza i flag giusti può diventare un bersaglio comodo per lo XSS (Cross-Site Scripting): se uno script malevolo gira nella tua pagina, può leggere il cookie (se non è HttpOnly) e rubare la sessione, scavalcando la password.
In questo articolo ti mostro come controllare i cookie in DevTools (partendo da Windows), cosa fanno HttpOnly, Secure e SameSite, e come farli scrivere correttamente all’IA in Express, Flask e Next.js.
ℹ️ Nota / Prerequisito operativo
Ti serve un browser moderno (Chrome, Edge, Firefox o Safari) e un’app web locale o remota su cui fare login e ispezionare i cookie. Non serve un tool esterno.
Se stai ancora mappando le falle tipiche del codice generato dall’IA, l’audit di sicurezza gratuito e le 7 falle comuni restano letture opzionali: qui mi concentro solo sullo storage della sessione nel browser.
Come verificare i cookie in DevTools
Prima di toccare il codice, ispeziona cosa sta davvero emettendo la tua app. Basta il browser.
Windows — Chrome o Edge (percorso principale)
- Apri l’app nel browser e fai il login (es.
http://localhost:3000o il tuo dominio di staging). - Premi F12 (oppure clic destro sulla pagina → Ispeziona).
- Apri la scheda Application (Applicazione). Se non la vedi, clicca
»nella barra delle schede. - Nella colonna di sinistra, sotto Storage, espandi Cookies e seleziona il dominio dell’app (es.
http://localhost:3000). - Nella tabella a destra cerca le colonne HttpOnly, Secure e SameSite sul cookie di sessione (spesso
session,session_id,sid,connect.sid, ecc.). - Cosa cercare: HttpOnly spuntato / true; Secure true in HTTPS di produzione; SameSite almeno
Lax(oStrictse lo hai scelto di proposito). Celle vuote oNonesenza motivo = da correggere.
macOS — Chrome o Edge
Stessi passi di Windows (F12 o clic destro → Ispeziona → Application → Cookies). Su Mac, se F12 non apre DevTools in Chrome, usa ⌘⌥I o il menu Visualizza → Opzioni per sviluppatori → Strumenti per sviluppatori.
macOS — Safari
- Attiva il menu Sviluppo: Safari → Impostazioni → Avanzate → Mostra menu Sviluppo nella barra dei menu.
- Clic destro sulla pagina → Ispeziona elemento (oppure menu Sviluppo → Mostra Web Inspector).
- Scheda Archiviazione → Cookie → dominio dell’app.
- Controlla le colonne relative a HttpOnly, Secure e SameSite (le etichette possono variare leggermente rispetto a Chrome).
Linux — Chrome / Chromium / Firefox
- Chrome/Chromium: F12 → Application → Cookies (come su Windows).
- Firefox (anche su Windows/macOS): F12 → scheda Archiviazione (Storage) → Cookie → dominio. Controlla HttpOnly, Secure e SameSite sulla riga del cookie di sessione.
💡 Consiglio pratico
Per il test usa localhost o uno staging. Non fotografare / condividere screenshot con token reali di produzione: il valore del cookie è la sessione.
I tre flag che i cookie di sessione dovrebbero avere
Ogni cookie può portare “istruzioni” al browser. Se non le imposti, restano i default, spesso più permissivi del necessario.
| Flag cookie | Cosa mitiga | Perché serve in pratica |
|---|---|---|
| HttpOnly Isolamento da JavaScript | Furto cookie via XSS | Il cookie non è leggibile da document.cookie. Uno script XSS non può estrarre il token di sessione e inviarselo altrove. Non elimina l’XSS in sé. |
| Secure Solo su HTTPS | Sniffing su rete | Il browser invia il cookie solo su connessioni HTTPS. Riduce il rischio di intercettazione su Wi‑Fi pubbliche. Non è una difesa anti-XSS. |
| SameSite Contesto della richiesta | CSRF (non XSS) | Decide se il cookie parte anche da richieste cross-site. Utile contro CSRF. Non ferma uno script che gira già sulla tua pagina (XSS). |
HttpOnly: il blocco sul furto della sessione via script
Se ne scegli uno solo per i cookie di sessione, è questo. HttpOnly dice al browser: questo cookie parla col server; JavaScript della pagina non lo legge e non lo modifica.
Senza HttpOnly, chi inietta codice (es. campo commenti non filtrato) può usare document.cookie, estrarre il token e mandarselo su un server proprio.
⚠️ Attenzione — SPA e JWT
Se l’IA ha messo il JWT inlocalStorageo in un cookie leggibile da JS per poi copiarlo in un headerAuthorization,HttpOnly“rompe” quel flusso. Non è un buon motivo per togliere il flag: la raccomandazione tipica (anche in linea con le linee guida OWASP sull’auth basata su cookie) è far gestire la sessione al browser con cookieHttpOnly, senza che il frontend manipoli il token. Tenere i JWT accessibili a JS aumenta la superficie XSS.
Secure: solo su connessioni cifrate
Con Secure, su HTTP in chiaro il browser non allega il cookie. In produzione, su HTTPS, è praticamente obbligatorio per le sessioni.
Su localhost i browser moderni spesso accettano cookie Secure anche su HTTP: comodo in sviluppo, ma non farti ingannare — in produzione senza HTTPS il flag Secure è indispensabile (e senza HTTPS hai già altri problemi).
SameSite: non è un antivirus
Valori tipici:
Lax— il cookie parte sulle navigazioni top-level (es. click su un link verso il tuo sito). Buon default per molte app.Strict— solo se la richiesta nasce dal tuo stesso sito. Più stretto; a volte l’utente deve rifare login arrivando da un link esterno.None— consente l’invio cross-site; richiede ancheSecure. Usalo solo se ti serve davvero (es. scenari embed/cross-origin specifici), non “perché l’IA l’ha messo”.
Punto chiave: SameSite non mitiga l’XSS. Se lo script malevolo gira sulla tua origine, la richiesta è same-site e i cookie partono. SameSite aiuta soprattutto contro il CSRF (Cross-Site Request Forgery).
Come impostare i flag nei progetti generati dall’IA
Non chiedere solo «scrivi la login». Nel prompt specifica: «Imposta il cookie di sessione con HttpOnly, Secure (in produzione) e SameSite=Lax». Poi verifica in DevTools dopo il login.
Express (Node.js)
I flag stanno nelle options di res.cookie():
// Esempio in Express.js
app.post('/login', (req, res) => {
// ... autenticazione e generazione del session_id ...
const sessionId = 'token-generato-dal-backend';
res.cookie('session_id', sessionId, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000, // 24 ore
});
res.send('Login effettuato');
});
💡 Consiglio pratico — locale vs produzione
Consecure: truesu HTTP “vero” (es. IP in LAN senza HTTPS) il cookie spesso non viene salvato. LegaresecureaNODE_ENV === 'production'(o a una variabile tipoCOOKIE_SECURE=true) è un compromesso comune. Dopo il deploy HTTPS, ricontrolla in DevTools che Secure sia true.
Flask (Python)
# Esempio in Flask
from flask import Flask, make_response
import os
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login():
# ... validazione utente ...
session_id = 'token-generato-dal-backend'
resp = make_response('Login effettuato')
# In produzione forza True (HTTPS). In locale puoi lasciare False.
is_secure = os.environ.get('COOKIE_SECURE', '').lower() in ('1', 'true', 'yes')
resp.set_cookie(
'session_id',
session_id,
httponly=True,
secure=is_secure,
samesite='Lax',
max_age=86400,
)
return resp
Se usi anche le sessioni firmate di Flask (session[...]), configura in modo coerente SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE e SESSION_COOKIE_SAMESITE nell’oggetto app.config, così non dipendi solo da un set_cookie manuale.
Next.js (App Router)
Con cookies() in Server Actions o Route Handlers (Next.js 15+: cookies() è async — va fatto await):
// Esempio in Next.js (app/actions.js)
'use server';
import { cookies } from 'next/headers';
export async function loginAction(formData) {
// ... logica di validazione ...
const sessionId = 'token-generato-dal-backend';
const cookieStore = await cookies();
cookieStore.set('session_id', sessionId, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24, // 24 ore in secondi
path: '/',
});
}
Dopo il login, torna in DevTools e verifica le tre colonne sul cookie appena impostato.
Domande Frequenti (FAQ)
Quali flag deve avere un cookie di sessione sicuro?
Come minimo: HttpOnly (niente lettura da JavaScript), Secure (solo su HTTPS) e SameSite sensato (Lax o Strict nella maggior parte dei login; None solo se serve davvero cross-site e sempre con Secure). Controlla anche Path e una scadenza coerente.
Come verifico i flag del cookie in Chrome o Edge?
Apri DevTools → Application (o Archiviazione) → Cookies → seleziona il tuo dominio. Nella tabella cerca le colonne HttpOnly, Secure e SameSite sul cookie di sessione dopo il login. Su Firefox il percorso analogo è Archiviazione → Cookie.
Perché l’IA può omettere HttpOnly, Secure e SameSite nei tutorial di login?
Nei dataset abbondano snippet “che funzionano in locale” su http://localhost senza HTTPS. L’assistente può ripetere il percorso minimo che fa partire la sessione, non la checklist di produzione. Tocca a te aggiungere i flag e verificarli in DevTools dopo ogni modifica.
HttpOnly basta contro gli attacchi XSS?
No. HttpOnly impedisce a uno script malevolo di leggere il cookie e esfiltrarlo facilmente, ma lo script può comunque agire come l’utente loggato (chiamate API, modifiche). Serve anche sanitizzare gli output HTML e, dove puoi, una CSP utile.
SameSite=None è sicuro per ogni sito?
Solo se ti serve davvero cookie cross-site (es. widget su altri domini) e solo insieme a Secure su HTTPS. Per un login classico sullo stesso sito, Lax o Strict riducono meglio il rischio CSRF “da click esterno”.
Limiti: cosa i flag non possono fermare
Cookie ben configurati riducono la superficie di attacco, non rendono il sito invulnerabile.
Nei miei test su progetti vibe-coded, il rischio tipico è la sensazione di «ora è tutto a posto». Con HttpOnly, uno XSS non ruba facilmente il cookie — ma lo script può comunque agire come l’utente loggato: chiamare le API, cambiare dati, leggere ciò che è a schermo. I flag isolano la sessione come segreto nel browser; per ridurre davvero l’XSS servono escaping/sanitizzazione degli output e input controllati (e, a livello di header, anche una CSP sensata — vedi la guida su CSP/HSTS/X-Frame-Options come lettura opzionale).
SameSite non è un antivirus; Secure non sostituisce HTTPS ben configurato; HttpOnly non sostituisce la pulizia dell’HTML. Usali insieme, poi verifica in DevTools dopo ogni modifica della login.