Site icon Ryadel

Come leggere, scrivere, modificare ed eliminare Cookie in ASP.NET C#

Classe ASP.NET C# per il controllo e il calcolo formale del Codice Fiscale

Avere a che fare con i Cookie è una esigenza tipica di qualsiasi programmatore web. In questo articolo, dopo una breve introduzione volta a spiegare il funzionamento dei Cookie in una tipica web application, presenteremo alcune classi helper che consentono di implementare in modo piuttosto semplice le principali attività necessarie per gestire i Cookie all'interno di un qualsiasi progetto ASP.NET Web Forms, MVC Core: ci riferiamo alle funzionalità di lettura, scrittura, modifica, eliminazione, gestione dei cookie contenenti coppie di chiavi-valori (key-value pairs), ma anche alla gestione di caratteristiche come la data di scadenza, le restrizioni di dominio, la modalità HttpOnly, il flag Secure, e così via. Nell'ultimo paragrafo ci occuperemo di come configurare le medesime impostazioni e caratteristiche a livello globale, ovvero relativamente a tutti i cookie creati dalla nostra applicazione web, utilizzando l'apposito file web.config.

Per chi non sapesse cosa siano i cookie - cosa piuttosto difficile, se vi siete imbattuti in questo articolo - rimandiamo a questa pagina informativa e alla voce Wikipedia dedicata.

Introduzione

I Cookie svolgono una serie di funzioni importantissime nella maggior parte delle applicazioni web. L'utilizzo più frequente è senz'altro quello legato all'autenticazione automatica (o semi-automatica) degli utenti: i cookie di autenticazione vengono creati dal server sul computer dell'utente al momento del login e contengono i dati necessari per determinare, nel corso delle visite successive, la presenza delle informazioni necessarie a effettuare nuovamente l'accesso. Questi dati, a seconda dei casi, possono contenere informazioni più o meno delicate, come un hash di username e password, un token di autenticazione e così via. Per questo motivo è estremamente importante proteggerli da accessi non autorizzati seguendo una serie di tecniche di sicurezza standard, quali ad esempio:

  • data encryption, ovvero la cifratura dei dati personali e dei valori potenzialmente oggetto di attacco (username, password)
  • hashing di qualsivoglia password o chiave di sicurezza che non sia fondamentale trasmettere in chiaro.
  • limitazione alla lettura/scrittura del cookie da parte di un determinato dominio.
  • impostare la data di scadenza (expiration date), così da impedire che il cookie resti attivo a tempo indefinito sul browser.
  • limitazione all'accesso da parte del browser attraverso la proprietà HttpOnly che, se abilitata, rende il cookie invisibile a JavaScript e altri linguaggi client-side presenti nella pagina.
  • limitazione alla trasmissione alle sole connessioni HTTPS su canale sicuro SSL/TLS attraverso il flag Secure che, se abilitato, rende il cookie impossibile da leggere a eventuali eavesdropper che si frappongano alla comunicazione tra client e server e quindi garantisce contro gli attacchi di tipo man in the middle.
IMPORTANTE: Gli snippet di codice che troverete in questo articolo sono stati recentemente aggiornati per gestire in modo corretto le novità introdotte nel 2019-2020 da Google Chrome e dal .NET Framework (4.7.2+) relativamente alla gestione dei cookie e degli attributi SameSite e Secure: per un approfondimento su questi aggiornamenti consigliamo di leggere questo articolo.

Creare un Cookie

Il seguente metodo statico, scritto in linguaggio C#, si occupa della creazione di un cookie:

Come si può vedere analizzando i parametri del metodo, è possibile specificare il nome, il dominio, la scadenza e la proprietà HttpOnly, mentre il flag Secure è bene impostarlo a livello di file web.config (come avremo modo di vedere in uno dei paragrafi successivi) così da renderlo abilitato (o disabilitato) per tutti i cookie generati dal sito.

Creare un Cookie con set di chiavi-valori

Ciascun cookie rappresenta, per definizione, una singola coppia chiave-valore: la chiave è il nome del cookie, mentre il valore è una normale stringa di testo. Questo significa che, in condizioni normali, per passare molteplici informazioni - come ad esempio username, password e data di login - avrò bisogno di molteplici cookie. Se questo modo di procedere può sembrare inefficiente, è possibile sfruttare uno dei tanti standard di serializzazione esistenti per fare in modo che un singolo cookie contenga più coppie chiave-valore, ovvero un set di chiavi-valori.

Questa possibilità è implementata nel seguente metodo statico, scritto in linguaggio C#, che può essere utilizzato per creare un singolo cookie contenente un set di chiavi-valori attraverso un Dictionary di stringhe:

 

Come si può vedere, il dictionary viene serializzzato all'interno della proprietà Values della classe HttpCookie messa a disposizione da ASP.NET.

Con questa tecnica è possibile memorizzare all'interno del cookie veri e propri oggetti, a patto di serializzare le loro proprietà in stringhe. Al tempo stesso, è bene non esagerare con questo approccio, poiché il processo di serializzazione e deserializzazione del cookie è sicuramente molto meno efficiente rispetto all'utilizzo degli stessi previsto dalle numerose specifiche che si sono succedute per definire il loro funzionamento (dalla US5774670 del 1998 alla RFC6265 attualmente in vigore).

Leggere un Cookie

Il seguente metodo statico, anch'esso in C#, consente di recuperare una stringa corrispondente al valore di un singolo Cookie oppure, opzionalmente, a una singola chiave presente all'interno di un singolo Cookie.

Ovviamente, la lettura della chiave ha senso solo se quest'ultima è stata "scritta" con il metodo precedente, ovvero rispettando lo standard di serializzazione predefinito di ASP.NET. La lettura del singolo cookie è invece pienamente compatibile a prescindere dalla piattaforma utilizzata.

Eliminare un Cookie

Il seguente metodo statico in C# consente di eliminare un cookie, oppure, opzionalmente, una singola chiave da un cookie esistente.

Controllo dell'esistenza di un Cookie

L'ultimo metodo che presentiamo si occupa di determinare se un cookie esiste o meno, senza modificarlo in alcun modo.

Configurazione dell'Applicazione Web

Ora che abbiamo visto come è possibile gestire i cookie a livello di codice è il momento di dare un'occhiata al file web.config per capire come possiamo impostare globalmente alcune caratteristiche relative a tutti i Cookie che saranno creati, modificati o altrimenti gestiti dalla nostra applicazione.

Secure Flag (requireSSL)

Se abbiamo configurato il nostro sito per accettare unicamente richieste web provenienti da canali protetti (HTTPS con certificato SSL/TLS) vale senz'altro la pena di impostare il flag Secure come attivo: prima di farlo, però, è opportuno spendere un paio di minuti per comprenderne il funzionamento.

Il flag Secure, se presente, indica al browser di autorizzare la creazione (e nelle versioni più recenti dei browser, anche la lettura) di cookie da parte del nostro sito solo utilizzando una connessione protetta. Il fatto che i browser meno recenti consentano la lettura dei cookie Secure anche attraverso connessioni non protette è indubbiamente un problema, che può essere però fortemente mitigato a livello server consentendo solo connessioni protette e rifiutando (o reindirizzando tramite apposite regole di rewrite/redirect da HTTP a HTTPS) quelle provenienti da canali non sicuri; al tempo stesso, è opportuno sottolineare come il senso dell'utilizzo del flag Secure sia soprattutto quello di difendere i nostri "preziosi" cookie di autenticazione da attacchi di tipo tampering, ovvero quelli che potrebbe effettuare un ipotetico man-in-the-middle (MITM) impadronendosi o alterando i nostri dati di sessione.

Per impostare il flag Secure globalmente, inserire i seguenti parametri di configurazione nel file web.config:

IMPORTANTE: l'attributo requireSSL impostato a true impedirà la creazione di qualsivoglia cookie (compresi quelli di sessione) in tutti i casi in cui l'applicazione venga eseguita in modalità diversa da HTTPS, come ad esempio durante il debug con Visual Studio: questo potrebbe portare a errori di autenticazione, ValidateTokens Exception (come spiegato in questo articolo) o altre problematiche bloccanti. Per evitare problemi di questo tipo consigliamo di abilitare tale attributo attraverso una transformation rule sul file web.Release.config, in modo a abilitare questa impostazione soltanto a seguito della pubblicazione dell'applicazione in un ambiente di produzione.

Nel caso in cui l'applicazione web utilizzi la Forms Authentication, ovvero l'autenticazione utente tramite form, è necessario attivare il flag Secure anche nella configurazione delle suddette form onde evitare che i cookie di autenticazione ereditino le impostazioni (per default non sicure) delle suddette. Per gestire anche questo caso, inserire i seguenti parametri di configurazione nel file web.config:

IMPORTANTE: A prescindere dalle modalità di trasmissione e dalla presenza del flag Secure, è importante tenere presenre come il cookie sia un meccanismo di scambio e archiviazione dati intrinsecamente insicuro, in quanto il suo contenuto - anche se ricevuto attraverso canale un TLS ultrasicuro - finisce sempre e comunque per essere letto in memoria e memorizzato nella cache dei client come una normalissima stringa di testo non crittografata.

HttpOnly Flag

Come già spiegato in precedenza, la presenza del flag HttpOnly - per default non attivo - indica al browser di non rendere disponibili i Cookie a tutti gli script client-side, come ad esempio gli script realizzati in JavaScript. Per forzare l'attivazione di questo flag a livello globale, ovvero per tutti i cookie creati dalla nostra applicazione web, è necessario utilizzare l'attributo httpOnly="true" all'interno del file web.config nello stesso elemento già definito in precedenza:

Restrizioni di dominio

Anche le restrizioni di dominio, delle quali abbiamo già parlato in precedenza, possono essere impostate a livello globale impostando il file web.config nel seguente modo:

Conclusioni

Per il momento è opportuno fermarci qui: ci auguriamo che questa guida ai Cookies in ASP.NET possa essere utile a tutti gli sviluppatori e amministratori di sistema chiamati a cimentarsi con queste problematiche. Alla prossima, e... felice sviluppo!

 

Exit mobile version