privacy

Attributi sicuri dei cookie

MetricSpot ispeziona gli header Set-Cookie cercando Secure, HttpOnly e SameSite. La mancanza di uno qualsiasi amplia la superficie d'attacco per furto cookie e CSRF.

Cosa verifica questo controllo

Legge ogni header di risposta Set-Cookie e controlla tre flag:

  • Secure — cookie inviato solo via HTTPS.
  • HttpOnly — cookie non leggibile da JavaScript (blocca il furto via XSS).
  • SameSite=Lax|Strict|None — comportamento sulle richieste cross-site (blocca CSRF).

Passa quando ogni cookie che porta stato di autenticazione o sessione ha tutti e tre.

Perché è importante

I cookie tengono le chiavi delle sessioni dei tuoi utenti. Un cookie senza questi flag è a una vulnerabilità XSS o a un Wi-Fi ostile di distanza dal furto account:

  • Senza Secure → il cookie viaggia in chiaro HTTP alla prima richiesta prima che HSTS si attivi. Sniffabile dal Wi-Fi di un bar.
  • Senza HttpOnly → qualunque script iniettato (XSS, dipendenza npm malevola, pubblicità ostile) può leggere il cookie via document.cookie ed esfiltrarlo.
  • Senza SameSite → cross-site request forgery (CSRF). Una pagina malevola può inviare form o scatenare richieste come tuo utente loggato.

I browser hanno stretto i default: Chrome ora spedisce SameSite=Lax di default, ma il codice legacy che imposta esplicitamente cookie senza flag continua a perdere.

Come sistemarlo

Imposta ogni cookie di sessione/auth con tutti e tre i flag.

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

Express / Node.js:

res.cookie("session", token, {
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  maxAge: 86400 * 1000,
  path: "/",
});

Next.js (App Router con cookies()):

import { cookies } from "next/headers";

cookies().set({
  name: "session",
  value: token,
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  path: "/",
  maxAge: 86400,
});

Bun.serve():

return new Response("ok", {
  headers: {
    "Set-Cookie": `session=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400`,
  },
});

Django:

# settings.py
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = "Lax"

Rails:

# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store,
  key: "_app_session",
  secure: Rails.env.production?,
  httponly: true,
  same_site: :lax

PHP / WordPress: in wp-config.php o prima di qualsiasi output:

ini_set('session.cookie_secure', '1');
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_samesite', 'Lax');

Quale valore di SameSite?

  • Strict — cookie mai inviato su richieste cross-site. Protezione massima, ma rompe il caso in cui un utente segue un link al tuo sito e arriva disconnesso. Buono per flussi ad alto rischio (admin, banking).
  • Lax (default) — cookie inviato sulle navigazioni top-level (clic su un link) ma non su POST cross-site, iframe o richieste di immagini. Il default giusto per la maggior parte dei siti.
  • None — cookie inviato su tutte le richieste cross-site. Richiede Secure. Usalo solo se ti serve davvero un contesto di terze parti (widget incorporati, identity provider).

I prefissi nel nome del cookie aggiungono un secondo livello di enforcement:

  • __Secure- — il browser rifiuta di impostare questo cookie a meno che non sia anche Secure.
  • __Host- — il browser rifiuta a meno che non ci sia Secure, Path=/ e nessun attributo Domain.
Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax

Abbina questa regola a HTTPS, abilitare HSTS e referrer policy per una baseline completa di sicurezza del trasporto.

Domande frequenti

HttpOnly rompe il mio codice client-side?

Solo se leggi il cookie da JavaScript. Per i cookie di sessione/auth non dovresti — il cookie deve essere opaco al client e usato solo dal server. Se stai salvando dati che il JS deve leggere, è un’altra categoria di cookie (preferenze, stato UI) e HttpOnly non si applica.

I cookie di consenso e analytics spesso hanno davvero bisogno di essere leggibili da JavaScript. Imposta Secure e SameSite=Lax su di loro, ma salta HttpOnly. Il controllo MetricSpot lo tollera — avvisa solo quando un cookie di sessione manca dei flag.

Questo influisce direttamente sulla compliance GDPR?

Non sul lato consenso/base giuridica, ma sul lato sicurezza. L’art. 32 del GDPR richiede “misure tecniche appropriate” — la mancanza di flag sui cookie è regolarmente citata nelle decisioni delle autorità di vigilanza come falla di sicurezza. Abbina a un banner di consenso cookie e a una privacy policy per il livello legale.

Fonti

Ultimo aggiornamento 2026-05-11