Usare i cookie HTTP
Cos’è un Cookie
Un cookie (noto anche come web cookie o cookie del browser) è un piccolo pezzo di dati che un server invia al browser web di un utente. Il browser può memorizzare cookie, crearne di nuovi, modificare quelli esistenti e inviarli allo stesso server con richieste successive.
I cookie consentono alle applicazioni web di memorizzare quantità limitate di dati e ricordare informazioni sullo stato; di default, il protocollo HTTP è senza stato, ovvero Stateless.
In questo articolo esploreremo i principali utilizzi dei cookie, spiegheremo le best practice per il loro utilizzo e analizzeremo le implicazioni sulla privacy e sulla sicurezza.
A cosa servono i cookie
In genere, il server utilizzerà il contenuto dei cookie HTTP per determinare se richieste diverse provengono dallo stesso browser/utente e quindi invierà una risposta personalizzata o generica, a seconda dei casi. Di seguito viene descritto un sistema di accesso utente molto semplice:
- L’utente invia le credenziali di accesso al server, ad esempio tramite l’invio di un modulo.
- Se le credenziali sono corrette, il server aggiorna l’interfaccia utente per indicare che l’utente ha effettuato l’accesso e risponde con un cookie contenente un ID di sessione che registra il suo stato di accesso sul browser.
- In un secondo momento, l’utente passa a una pagina diversa sullo stesso sito. Il browser invia il cookie contenente l’ID di sessione insieme alla richiesta corrispondente per indicare che ritiene ancora che l’utente abbia effettuato l’accesso.
- Il server controlla l’ID di sessione e, se è ancora valido, invia all’utente una versione personalizzata della nuova pagina. Se non è valido, l’ID di sessione viene eliminato e all’utente viene mostrata una versione generica della pagina (o forse un messaggio di “accesso negato” e gli viene chiesto di effettuare nuovamente l’accesso).
I cookie vengono utilizzati principalmente per tre scopi:
- Gestione della sessione: stato di accesso dell’utente, contenuto del carrello, punteggi di gioco o qualsiasi altro dettaglio relativo alla sessione dell’utente che il server deve ricordare.
- Personalizzazione: preferenze dell’utente come lingua di visualizzazione e tema dell’interfaccia utente.
- Tracciamento: registrazione e analisi del comportamento dell’utente.
Archiviazione dei dati
Agli albori del Web, quando non esistevano altre opzioni, i cookie venivano utilizzati per scopi generali di archiviazione dei dati lato client. Ora sono consigliate le moderne API di archiviazione, ad esempio la Web Storage API (localStorage e sessionStorage) e IndexedDB.
Sono progettati tenendo a mente l’archiviazione, non inviano mai dati al server e non presentano altri svantaggi nell’uso dei cookie per l’archiviazione:
- I browser sono generalmente limitati a un numero massimo di cookie per dominio (varia a seconda del browser, generalmente nell’ordine delle centinaia) e a una dimensione massima per cookie (solitamente 4 KB). Le API di archiviazione possono archiviare quantità maggiori di dati.
- I cookie vengono inviati a ogni richiesta, quindi possono peggiorare le prestazioni (ad esempio su connessioni dati mobili lente), soprattutto se hai impostato molti cookie.
Nota: per visualizzare i cookie archiviati (e altri archivi utilizzati da una pagina Web) puoi utilizzare Storage Inspector in Firefox Developer Tools o il pannello Applicazione in Chrome Developer Tools.
Creare, rimuovere e aggiornare cookie
Dopo aver ricevuto una richiesta HTTP, un server può inviare una o più intestazioni Set-Cookie con la risposta, ognuna delle quali imposterà un cookie separato. Un semplice cookie viene impostato specificando una coppia nome-valore come questa:
HTTP Copia negli Appunti Set-Cookie: <nome-cookie>=<valore-cookie>
La seguente risposta HTTP indica al browser ricevente di memorizzare una coppia di cookie:
HTTP HTTP/2.0 200 OK Content-Type: text/html Set-Cookie: yummy_cookie=chocolate Set-Cookie: tasty_cookie=strawberry [contenuto della pagina]
Nota: scopri come utilizzare l’intestazione Set-Cookie in vari linguaggi/framework lato server: PHP, Node.JS, Python, Ruby on Rails.
Quando viene effettuata una nuova richiesta, il browser di solito invia i cookie precedentemente memorizzati per il dominio corrente al server all’interno di un’intestazione HTTP Cookie:
HTTP GET /sample_page.html HTTP/2.0 Host: www.example.org Cookie: yummy_cookie=chocolate; tasty_cookie=strawberry
Removal: definizione della durata di un cookie
È possibile specificare una data di scadenza o un periodo di tempo dopo il quale il cookie deve essere eliminato e non più inviato. A seconda degli attributi impostati nell’intestazione Set-Cookie quando vengono creati i cookie, possono essere cookie permanenti o di sessione:
-
- I cookie permanenti vengono eliminati dopo la data specificata nell’attributo Expires:
HTTP Set-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;
o dopo il periodo specificato nell’attributo Max-Age:
HTTP Set-Cookie: id=a3fWa; Max-Age=2592000
Nota: Expires è disponibile da più tempo di Max-Age, comunque Max-Age è meno soggetto a errori e ha la precedenza quando vengono impostati entrambi. La logica alla base di ciò è che quando si imposta una data e un’ora di Expires, sono relative al client su cui viene impostato il cookie. Se il server è impostato su un’ora diversa, ciò potrebbe causare errori.
- I cookie di sessione, ovvero i cookie senza un attributo Max-Age o Expires, vengono eliminati quando termina la sessione corrente. Il browser definisce quando termina la “sessione corrente” e alcuni browser utilizzano la sessione ripristino al riavvio. Ciò può causare la durata indefinita dei cookie di sessione.
Nota: se il tuo sito autentica gli utenti, dovrebbe rigenerare e inviare nuovamente i cookie di sessione, anche quelli già esistenti, ogni volta che un utente si autentica. Questo approccio aiuta a prevenire gli attacchi di fissazione della sessione, in cui una terza parte può riutilizzare la sessione di un utente.
- I cookie permanenti vengono eliminati dopo la data specificata nell’attributo Expires:
Esistono alcune tecniche progettate per ricreare i cookie dopo che sono stati eliminati. Questi sono noti come cookie “zombie”. Queste tecniche violano i principi di privacy e controllo dell’utente, possono violare le normative sulla privacy dei dati e potrebbero esporre un sito Web che li utilizza a responsabilità legali.
Aggiornamento dei valori dei cookie
Per aggiornare un cookie tramite HTTP, il server può inviare un’intestazione Set-Cookie con il nome del cookie esistente e un nuovo valore. Ad esempio:
HTTP Set-Cookie: id=new-value Ci sono diversi motivi per cui potresti voler fare ciò, ad esempio se un utente ha aggiornato le proprie preferenze e l'applicazione desidera riflettere le modifiche nei dati lato client (potresti anche farlo con un meccanismo di archiviazione lato client come Web Storage).
Aggiornamento dei cookie tramite JavaScript
Nel browser, puoi creare nuovi cookie tramite JavaScript utilizzando la proprietà Document.cookie o l’API asincrona Cookie Store. Nota che tutti gli esempi sottostanti utilizzano Document.cookie, in quanto è l’opzione più ampiamente supportata/consolidata.
JS document.cookie = "yummy_cookie=chocolate"; document.cookie = "tasty_cookie=strawberry";
Puoi anche accedere ai cookie esistenti e impostare nuovi valori per essi, a condizione che l’attributo HttpOnly non sia impostato su di essi (ad esempio nell’intestazione Set-Cookie che lo ha creato):
JS console.log(document.cookie); // registra "yummy_cookie=chocolate; tasty_cookie=strawberry" document.cookie = "yummy_cookie=blueberry"; console.log(document.cookie); // registra "tasty_cookie=strawberry; yummy_cookie=blueberry"
Nota che, per motivi di sicurezza, non puoi modificare i valori dei cookie inviando direttamente un’intestazione Cookie aggiornata quando avvii una richiesta, ad esempio tramite fetch() o XMLHttpRequest. Nota che ci sono anche delle buone ragioni per cui non dovresti consentire a JavaScript di modificare i cookie, ad esempio impostando HttpOnly durante la creazione.
Consulta la sezione Sicurezza qui sotto per maggiori dettagli.
Sicurezza
Quando memorizzi informazioni nei cookie, per impostazione predefinita tutti i valori dei cookie sono visibili e possono essere modificati dall’utente finale. Non vuoi davvero che i tuoi cookie vengano utilizzati in modo improprio, ad esempio accessibili/modificati da malintenzionati o inviati a domini in cui non dovrebbero essere inviati. Le potenziali conseguenze possono variare da fastidiose (app che non funzionano o mostrano comportamenti strani) a catastrofiche. Un criminale potrebbe ad esempio rubare un ID di sessione e usarlo per impostare un cookie che faccia sembrare che abbia effettuato l’accesso come qualcun altro, prendendo il controllo del suo conto bancario o di e-commerce nel processo.
Puoi proteggere i tuoi cookie in vari modi, che sono esaminati in questa sezione.
Blocca l’accesso ai tuoi cookie
Puoi assicurarti che i cookie vengano inviati in modo sicuro e che non siano accessibili da parti o script indesiderati in uno dei due modi: con l’attributo Secure e l’attributo HttpOnly:
HTTP Copia negli appunti Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
- Un cookie con l’attributo Secure viene inviato al server solo con una richiesta crittografata tramite il protocollo HTTPS. Non viene mai inviato con HTTP non protetto (tranne su localhost), il che significa che gli aggressori man-in-the-middle non possono accedervi facilmente. I siti non sicuri (con http: nell’URL) non possono impostare cookie con l’attributo Secure. Tuttavia, non dare per scontato che Secure impedisca qualsiasi accesso alle informazioni sensibili nei cookie. Ad esempio, qualcuno con accesso al disco rigido del client (o JavaScript se l’attributo HttpOnly non è impostato) può leggere e modificare le informazioni.
- Un cookie con l’attributo HttpOnly non può essere accessibile da JavaScript, ad esempio tramite Document.cookie; è possibile accedervi solo quando raggiunge il server. I cookie che persistono nelle sessioni utente, ad esempio, dovrebbero avere l’attributo HttpOnly impostato: sarebbe davvero poco sicuro renderli disponibili a JavaScript. Questa precauzione aiuta a mitigare gli attacchi cross-site scripting (XSS).
Nota: a seconda dell’applicazione, potresti voler utilizzare un identificatore opaco che il server cerca anziché archiviare informazioni sensibili direttamente nei cookie, oppure esaminare meccanismi di autenticazione/riservatezza alternativi come i token Web JSON.
Definisci dove vengono inviati i cookie
Gli attributi Domain e Path definiscono l’ambito di un cookie: a quali URL vengono inviati i cookie.
-
- L’attributo Domain specifica quale server può ricevere un cookie. Se specificato, i cookie sono disponibili sul server specificato e sui suoi sottodomini. Ad esempio, se imposti Domain=mozilla.org da mozilla.org, i cookie sono disponibili su quel dominio e su sottodomini come developer.mozilla.org.
HTTP Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Domain=mozilla.org
Se l’intestazione Set-Cookie non specifica un attributo Domain, i cookie sono disponibili sul server che lo imposta ma non sui suoi sottodomini. Pertanto, specificare Domain è meno restrittivo che ometterlo. Nota che un server può impostare l’attributo Domain solo sul proprio dominio o su un dominio padre, non su un sottodominio o un altro dominio. Quindi, ad esempio, un server con dominio foo.example.com potrebbe impostare l’attributo su example.com o foo.example.com, ma non su bar.foo.example.com o else.com (i cookie verrebbero comunque inviati a sottodomini come bar.foo.example.com). Per maggiori dettagli, vedere Domini non validi.
- L’attributo Path indica un percorso URL che deve esistere nell’URL richiesto per inviare l’intestazione Cookie. Ad esempio:
HTTP Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Path=/docs
Il carattere %x2F (“/”) è considerato un separatore di directory e anche le sottodirectory corrispondono. Ad esempio, se imposti Path=/docs, questi percorsi di richiesta corrispondono:
- /docs
- /docs/
- /docs/Web/
- /docs/Web/HTTP
Ma questi percorsi di richiesta non corrispondono:
- /
- /docsets
- /fr/docs
- L’attributo Domain specifica quale server può ricevere un cookie. Se specificato, i cookie sono disponibili sul server specificato e sui suoi sottodomini. Ad esempio, se imposti Domain=mozilla.org da mozilla.org, i cookie sono disponibili su quel dominio e su sottodomini come developer.mozilla.org.
Controllo dei cookie di terze parti con SameSite
L’attributo SameSite consente ai server di specificare se/quando i cookie vengono inviati con richieste cross-site, ovvero cookie di terze parti. Le richieste cross-site sono richieste in cui il sito (il dominio registrabile) e/o lo schema (http o https) non corrispondono al sito che l’utente sta visitando in quel momento.
Ciò include le richieste inviate quando si fa clic sui link su altri siti per navigare verso il tuo sito e qualsiasi richiesta inviata da contenuti di terze parti incorporati.
SameSite aiuta a prevenire la perdita di informazioni, preservando la privacy dell’utente e fornendo una certa protezione contro gli attacchi di falsificazione delle richieste cross-site. Accetta tre possibili valori: Strict, Lax e None:
-
- Strict fa sì che il browser invii il cookie solo in risposta alle richieste provenienti dal sito di origine del cookie. Dovrebbe essere utilizzato quando si hanno cookie relativi a funzionalità che saranno sempre dietro una navigazione iniziale, come l’autenticazione o la memorizzazione delle informazioni del carrello.
HTTP Set-Cookie: cart=110045_77895_53420; SameSite=Strict
Nota: i cookie utilizzati per informazioni sensibili dovrebbero avere anche una durata breve.
- Lax è simile, tranne per il fatto che il browser invia anche il cookie quando l’utente naviga sul sito di origine del cookie (anche se l’utente proviene da un sito diverso). Questo è utile per i cookie che influenzano la visualizzazione di un sito, ad esempio potresti avere informazioni sui prodotti dei partner insieme a un link di affiliazione sul tuo sito web. Quando quel link viene seguito per il sito web del partner, potrebbe voler impostare un cookie che indica che il link di affiliazione è stato seguito, che visualizza un banner di ricompensa e fornisce uno sconto se il prodotto viene acquistato.
HTTP Set-Cookie: affiliate=e4rt45dw; SameSite=Lax
- None specifica che i cookie vengono inviati sia sulle richieste di origine che su quelle tra siti. Ciò è utile se si desidera inviare cookie insieme alle richieste effettuate da contenuti di terze parti incorporati in altri siti, ad esempio, provider di tecnologia pubblicitaria o di analisi. Si noti che se SameSite=None è impostato, anche l’attributo Secure deve essere impostato: SameSite=None richiede un contesto sicuro.
HTTP Set-Cookie: widget_session=7yjgj57e4n3d; SameSite=None; Secure; HttpOnly
Se non è impostato alcun attributo SameSite, il cookie viene trattato come Lax per impostazione predefinita.
Prefissi dei cookie
A causa della progettazione del meccanismo dei cookie, un server non può confermare che un cookie sia stato impostato da un’origine sicura o persino dire dove è stato originariamente impostato un cookie.
Un’applicazione vulnerabile su un sottodominio può impostare un cookie con l’attributo Domain, che consente l’accesso a tale cookie su tutti gli altri sottodomini. Questo meccanismo può essere abusato in un attacco di fissazione della sessione. Vedere la fissazione della sessione per i metodi di mitigazione principali.
Tuttavia, come misura di difesa approfondita, puoi usare i prefissi dei cookie per affermare fatti specifici sul cookie. Sono disponibili due prefissi:
- __Host-: se un nome di cookie ha questo prefisso, viene accettato in un’intestazione Set-Cookie solo se è anche contrassegnato con l’attributo Secure, è stato inviato da un’origine sicura, non include un attributo Domain e ha l’attributo Path impostato su /. In altre parole, il cookie è bloccato dal dominio.
- __Secure-: se un nome di cookie ha questo prefisso, viene accettato in un’intestazione Set-Cookie solo se è contrassegnato con l’attributo Secure ed è stato inviato da un’origine sicura. Questo è più debole del prefisso __Host-.
Il browser rifiuterà i cookie con questi prefissi che non rispettano le loro restrizioni. Ciò garantisce che i cookie creati da sottodomini con prefissi siano limitati a un sottodominio o ignorati completamente. Poiché il server applicativo verifica solo un nome cookie specifico quando determina se l’utente è autenticato o se un token CSRF è corretto, questo agisce efficacemente come misura di difesa contro la fissazione della sessione.
Nota: sul server, l’applicazione Web deve verificare il nome completo del cookie, incluso il prefisso. Gli user agent non rimuovono il prefisso dal cookie prima di inviarlo nell’intestazione Cookie di una richiesta.
Per ulteriori informazioni sui prefissi dei cookie e sullo stato attuale del supporto del browser, vedere la sezione Prefissi dell’articolo di riferimento Set-Cookie.
Privacy e tracciamento
In precedenza abbiamo parlato di come l’attributo SameSite può essere utilizzato per controllare quando vengono inviati cookie di terze parti e che questo può aiutare a preservare la privacy dell’utente. La privacy è una considerazione molto importante quando si creano siti Web che, se eseguita correttamente, può creare fiducia con i tuoi utenti. Se eseguita male, può erodere completamente tale fiducia e causare tutti i tipi di altri problemi.
I cookie di terze parti possono essere impostati da contenuti di terze parti incorporati nei siti tramite <iframe>. Hanno molti usi legittimi, tra cui la condivisione di informazioni sul profilo utente, il conteggio delle impressioni degli annunci o la raccolta di analisi su diversi domini correlati.
Tuttavia, i cookie di terze parti possono anche essere utilizzati per creare esperienze utente inquietanti e invasive. Un server di terze parti può creare un profilo della cronologia di navigazione e delle abitudini di un utente in base ai cookie inviati dallo stesso browser quando accede a più siti. L’esempio classico è quando cerchi informazioni sui prodotti su un sito e poi vieni inseguito in giro per il web da pubblicità di prodotti simili ovunque tu vada.
I fornitori di browser sanno che agli utenti non piace questo comportamento e, di conseguenza, hanno tutti iniziato a bloccare i cookie di terze parti per impostazione predefinita o almeno hanno pianificato di andare in quella direzione. I cookie di terze parti (o semplicemente i cookie di tracciamento) possono anche essere bloccati da altre impostazioni o estensioni del browser.
Nota: il blocco dei cookie può causare il malfunzionamento di alcuni componenti di terze parti (come i widget dei social media). Poiché i browser impongono ulteriori restrizioni sui cookie di terze parti, gli sviluppatori dovrebbero iniziare a cercare modi per ridurre la loro dipendenza da essi.
Consulta il nostro articolo sui cookie di terze parti per informazioni dettagliate sui cookie di terze parti, sui problemi ad essi associati e sulle alternative disponibili. Consulta la nostra pagina di destinazione sulla privacy per maggiori informazioni sulla privacy in generale.
Normative relative ai cookie
Legislazione o le normative che regolano l’uso dei cookie includono:
- Il Regolamento generale sulla privacy dei dati (GDPR) nell’Unione Europea
- La direttiva ePrivacy nell’UE
- Il California Consumer Privacy Act
Queste normative hanno una portata globale. Si applicano a qualsiasi sito sul World Wide Web a cui accedono gli utenti di queste giurisdizioni (l’UE e la California, con l’avvertenza che la legge della California si applica solo alle entità con un fatturato lordo superiore a 25 milioni di USD, tra le altre cose).
Queste normative includono requisiti come:
- Notificare agli utenti che il tuo sito utilizza i cookie.
- Consentire agli utenti di scegliere di non ricevere alcuni o tutti i cookie.
- Consentire agli utenti di utilizzare la maggior parte del tuo servizio senza ricevere cookie.
Potrebbero esserci altre normative che regolano l’uso dei cookie nella tua località. L’onere è a tuo carico di conoscere e rispettare queste normative. Ci sono aziende che offrono un codice “cookie banner” che ti aiuta a rispettare queste normative.
Nota: le aziende dovrebbero divulgare i tipi di cookie che utilizzano sui loro siti per motivi di trasparenza e per rispettare le normative. Ad esempio, vedi l’informativa di Google sui tipi di cookie utilizzati e l’Informativa sulla privacy di Mozilla sui siti web, le comunicazioni e i cookie
- Strict fa sì che il browser invii il cookie solo in risposta alle richieste provenienti dal sito di origine del cookie. Dovrebbe essere utilizzato quando si hanno cookie relativi a funzionalità che saranno sempre dietro una navigazione iniziale, come l’autenticazione o la memorizzazione delle informazioni del carrello.