Partizionamento della cache per maggiore sicurezza e privacy

In generale, la memorizzazione nella cache può migliorare le prestazioni archiviando i dati in modo che le richieste future per gli stessi dati vengano eseguite più velocemente. Ad esempio, una risorsa memorizzata nella cache della rete può evitare un viaggio di andata e ritorno al server. Un risultato di calcolo memorizzato nella cache può ommettere il tempo necessario per eseguire lo stesso calcolo.

In Chrome, il meccanismo della cache viene utilizzato in vari modi e la cache HTTP è 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 come chiave della cache. Una chiave della 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 ha già questa risorsa in cache, utilizzando l'URL dell'immagine come chiave. Il browser trova una corrispondenza nella 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 da 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 della cache è la stessa in tutte le pagine.

Questo meccanismo funziona bene dal punto di vista del rendimento da molto tempo. Tuttavia, il tempo necessario a un sito web per rispondere alle richieste HTTP può rivelare che il browser ha avuto accesso alla stessa risorsa in passato, il che lo espone ad attacchi alla sicurezza e alla privacy, come i seguenti:

  • Rileva se un utente ha visitato un sito specifico: un 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 per una coorte di siti.
  • Attacco alla ricerca tra siti: un malintenzionato può rilevare se una stringa arbitraria è presente nei risultati di ricerca dell'utente controllando se un 'immagine "Nessun risultato di ricerca" utilizzata da un determinato sito web è presente nella cache del browser.
  • Monitoraggio tra siti: la cache può essere utilizzata per memorizzare identificatori simili ai cookie come meccanismo di monitoraggio tra siti.

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

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

Con il partizionamento della cache, le risorse memorizzate nella cache verranno assegnate a 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:

Cache Key { 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 risorse proviene dal frame di primo livello, il sito di primo livello e il sito del frame corrente nella chiave di isolamento della rete sono gli stessi.

Cache Key { 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 una pagina diversa (https://b.example) che richiede la stessa immagine (https://x.example/doge.png). Sebbene la stessa immagine sia stata caricata nell'esempio precedente, poiché la chiave non corrisponde, non si verificherà un hit 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.

Cache Key { 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 hit 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.

Cache Key { 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 torna su https://a.example, ma questa volta l'immagine è ospitata in un frame di https://c.example.

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

Cache Key { 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 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 viene creata in base a "schema://eTLD+1", i sottodomini e i numeri di porta vengono ignorati. Di conseguenza, si verifica un successo della cache.

Cache Key { 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 è nidificato più volte? L'utente visitahttps://a.example, che incorpora un iframe (https://b.example), che incorpora un altro iframe (https://c.example), che infine richiede l'immagine.

Poiché la chiave viene presa dal frame principale (https://a.example) e dal frame immediato che carica la risorsa (https://c.example), si verifica un colpo alla cache.

Domande frequenti

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

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

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

Vedrai l'output del file di log.

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

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 --enable-features=SplitCacheByNetworkIsolationKey. Segui le istruzioni riportate in Eseguire Chromium con i flag per scoprire come avviare Chrome con un flag a riga di comando sulla tua piattaforma.

In qualità di sviluppatore web, devo intraprendere qualche azione in risposta a questa modifica?

Non si tratta di una modifica che comporta interruzioni, ma potrebbe imporre considerazioni sul rendimento per alcuni servizi web.

Ad esempio, i siti che pubblicano grandi volumi di risorse altamente cacheabili su molti siti (come i caratteri e gli script più utilizzati) potrebbero registrare un aumento del traffico. Inoltre, chi utilizza questi servizi potrebbe farne un uso più frequente.

Esiste una proposta per attivare le librerie condivise nel rispetto della privacy, chiamata Librerie condivise web (video di presentazione), ma è ancora in fase di valutazione.

Qual è l'impatto di questa modifica del comportamento?

Il tasso di mancate corrispondenze della cache aumenta di circa il 3,6%, le modifiche al FCP (First Contentful Paint) sono modeste (~0,3%) e la frazione complessiva di byte caricati dalla rete aumenta di circa il 4%. Per scoprire di più sull'impatto sul rendimento, consulta la spiegazione del partizionamento della cache HTTP.

È standardizzato? Gli altri browser si comportano in modo diverso?

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

  • Chrome: utilizza lo schema di primo livello://eTLD+1 e lo schema del frame://eTLD+1
  • Safari: utilizza TLD+1 di primo livello
  • Firefox: prevista l'implementazione con schema di primo livello://eTLD+1 e si sta valutando la possibilità di includere una seconda chiave come in Chrome

Come viene gestito il recupero dai lavoratori?

I worker dedicati utilizzano la stessa chiave del frame corrente. I worker di servizio e i worker condivisi sono più complicati in quanto possono essere condivisi tra più siti di primo livello. Al momento è in discussione la soluzione per questo problema.

Risorse