Partizionamento della cache per maggiore sicurezza e privacy

In generale, la memorizzazione nella cache può migliorare le prestazioni mediante l'archiviazione dei dati in modo da gestire più velocemente le richieste future relative agli stessi dati. Ad esempio, una risorsa della rete memorizzata nella cache può evitare un round trip al server. Un risultato computazionale memorizzato nella cache può omettere il tempo necessario per eseguire lo stesso calcolo.

In Chrome, il meccanismo di cache viene utilizzato in vari modi e la cache HTTP ne è un esempio.

Come funziona attualmente la cache HTTP di Chrome

A partire dalla versione 85, Chrome memorizza nella cache le risorse recuperate dalla rete, utilizzando i rispettivi URL delle risorse come chiave cache. (Una chiave cache viene utilizzata per identificare una risorsa memorizzata nella cache).

L'esempio seguente illustra come una singola immagine viene memorizzata nella cache e trattata in tre diversi contesti:

Chiave cache: https://x.example/doge.png
Chiave cache: { https://x.example/doge.png }

Un utente visita una pagina (https://a.example) che richiede un'immagine (https://x.example/doge.png). L'immagine viene richiesta dalla rete e memorizzata nella cache utilizzando https://x.example/doge.png come chiave.

Chiave cache: https://x.example/doge.png
Chiave cache: { https://x.example/doge.png }

Lo stesso utente visita un'altra pagina (https://b.example) che richiede la stessa immagine (https://x.example/doge.png). Il browser controlla la cache HTTP per verificare se questa risorsa è già stata memorizzata nella cache, utilizzando l'URL dell'immagine come chiave. Il browser trova una corrispondenza nella propria cache, quindi utilizza la versione memorizzata nella cache della risorsa.

Chiave cache: https://x.example/doge.png
Chiave cache: { https://x.example/doge.png }

Non importa se l'immagine viene caricata dall'interno di un iframe. Se l'utente visita un altro sito web (https://c.example) con un iframe (https://d.example) e l'iframe richiede la stessa immagine (https://x.example/doge.png), il browser può comunque caricare l'immagine dalla cache perché la chiave cache è la stessa in tutte le pagine.

Questo meccanismo ha funzionato bene dal punto di vista delle prestazioni da molto tempo. Tuttavia, il tempo impiegato da un sito web per rispondere alle richieste HTTP può rivelare che il browser ha avuto accesso alla stessa risorsa in passato, il che apre il browser ad attacchi alla sicurezza e alla privacy, come i seguenti:

  • Rileva se un utente ha visitato un sito specifico. Un utente malintenzionato può rilevare la cronologia di navigazione di un utente controllando se la cache contiene una risorsa che potrebbe essere specifica per un determinato sito o coorte di siti.
  • Attacco di ricerca tra siti: un utente malintenzionato può rilevare se nei risultati di ricerca dell'utente è presente una stringa arbitraria controllando se nella cache del browser è presente un 'immagine "nessun risultato di ricerca" utilizzata da un determinato sito web.
  • Monitoraggio tra siti: la cache può essere utilizzata per archiviare identificatori simili a cookie come meccanismo di monitoraggio tra siti.

Per ridurre questi rischi, a partire da Chrome 86 Chrome partirà la cache HTTP.

In che modo il partizionamento della cache influirà sulla cache HTTP di Chrome?

Con il partizionamento della cache, le risorse memorizzate nella cache verranno codificate utilizzando una nuova "chiave di isolamento della rete" oltre all'URL della risorsa. La chiave di isolamento della rete è composta dal sito di primo livello e dal sito del frame corrente.

Esamina di nuovo l'esempio precedente per vedere come funziona il partizionamento della cache in diversi contesti:

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://a.example, https://a.example, https://x.example/doge.png }

Un utente visita una pagina (https://a.example) che richiede un'immagine (https://x.example/doge.png). In questo caso, l'immagine viene richiesta dalla rete e memorizzata nella cache utilizzando una tupla composta da https://a.example (il sito di primo livello), https://a.example (il sito del frame corrente) e https://x.example/doge.png (l'URL della risorsa) come chiave. Tieni presente che quando la richiesta di risorsa proviene dal frame di primo livello, il sito di primo livello e il sito del frame corrente nella chiave di isolamento di rete sono uguali.

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://b.example, https://b.example, https://x.example/doge.png }

Lo stesso utente visita un'altra pagina (https://b.example) che richiede la stessa immagine (https://x.example/doge.png). Anche se la stessa immagine è stata caricata nell'esempio precedente, poiché la chiave non corrisponde, non sarà un successo della cache.

L'immagine viene richiesta dalla rete e memorizzata nella cache utilizzando una tupla composta da https://b.example, https://b.example e https://x.example/doge.png come chiave.

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://a.example, https://a.example, https://x.example/doge.png }

Ora l'utente torna a https://a.example ma questa volta l'immagine (https://x.example/doge.png) è incorporata in un iframe. In questo caso, la chiave è una tupla contenente https://a.example, https://a.example e https://x.example/doge.png e si verifica un successo della cache. Tieni presente che quando il sito di primo livello e l'iframe sono lo stesso sito, è possibile utilizzare la risorsa memorizzata nella cache con il frame di primo livello.

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://a.example, https://c.example, https://x.example/doge.png }

L'utente è tornato alle ore https://a.example, ma questa volta l'immagine è ospitata in un iframe dal giorno https://c.example.

In questo caso, l'immagine viene scaricata dalla rete perché nella cache non esiste alcuna risorsa corrispondente alla chiave composta da https://a.example, https://c.example e https://x.example/doge.png.

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://a.example, https://c.example, https://x.example/doge.png }

Che cosa succede se il dominio contiene un sottodominio o un numero di porta? L'utente visita https://subdomain.a.example, che incorpora un iframe (https://c.example:8080), che richiede l'immagine.

Poiché la chiave è stata creata in base a "scheme://eTLD+1", i sottodomini e i numeri di porta vengono ignorati. Di conseguenza, si verifica un successo della cache.

Chiave cache { https://a.example, https://a.example, https://x.example/doge.png}
Chiave cache: { https://a.example, https://c.example, https://x.example/doge.png }

Cosa succede se l'iframe viene nidificato più volte? L'utente visita https://a.example, che incorpora un iframe (https://b.example), che incorpora un altro iframe (https://c.example), che alla fine richiede l'immagine.

Poiché la chiave viene presa dal top-frame (https://a.example) e dal frame immediato che carica la risorsa (https://c.example), si verifica un successo della cache.

Domande frequenti

È già attiva sul mio Chrome? Come faccio a controllare?

La funzionalità verrà implementata fino alla fine del 2020. Per verificare se la tua istanza di Chrome lo supporta già:

  1. Apri chrome://net-export/ e premi Avvia registrazione su disco.
  2. Specifica dove salvare il file di log sul computer.
  3. Naviga sul web con Chrome per un minuto.
  4. Torna a chrome://net-export/ e premi Interrompi registrazione.
  5. Vai a https://netlog-viewer.appspot.com/#import.
  6. Premi Scegli file e passa il file di log salvato.

Verrà visualizzato l'output del file di log.

Nella stessa pagina, individua SplitCacheByNetworkIsolationKey. Se è seguito da Experiment_[****], il partizionamento della cache HTTP è abilitato su Chrome. Se è seguito da Control_[****] o Default_[****], non è abilitato.

Come faccio a testare il partizionamento della cache HTTP su Chrome?

Per testare il partizionamento della cache HTTP su Chrome, devi avviare Chrome con un flag della riga di comando: --enable-features=SplitCacheByNetworkIsolationKey. Segui le istruzioni riportate nell'articolo Eseguire Chromium con flag per scoprire come avviare Chrome con un flag della riga di comando sulla tua piattaforma.

In qualità di sviluppatore web, c'è qualcosa che devo fare in risposta a questo cambiamento?

Non si tratta di una modifica che provoca un errore, ma può imporre considerazioni sulle prestazioni di alcuni servizi web.

Ad esempio, quelli che gestiscono grandi volumi di risorse altamente memorizzabili nella cache su molti siti (come caratteri e script popolari) potrebbero registrare un aumento del traffico. Inoltre, coloro che utilizzano questi servizi possono fare maggiore affidamento su questi servizi.

È stata presentata una proposta per abilitare le librerie condivise in modo incentrato sulla tutela della privacy chiamata librerie condivise sul web (video di presentazione), ma è ancora in fase di valutazione.

Qual è l'impatto di questo cambiamento comportamentale?

Il tasso di fallimento della cache complessivo aumenta di circa il 3,6%, le modifiche al valore FCP (First Contentful Paint) sono modeste (~0,3%) e la frazione complessiva di byte caricati dalla rete aumenta di circa il 4%. Per ulteriori informazioni sull'impatto sulle prestazioni, consulta la documentazione sul partizionamento della cache HTTP.

È standardizzato? Gli altri browser si comportano diversamente?

Le "partizioni cache HTTP" sono standardizzate nelle specifiche di recupero, anche se i browser si comportano in modo diverso:

Come viene trattato il recupero dai worker?

I worker dedicati utilizzano la stessa chiave del frame attuale. I Service worker e i worker condivisi sono più complicati poiché possono essere condivisi tra più siti di primo livello. La soluzione è attualmente in discussione.

Risorse