Isolamento dei siti per sviluppatori web

In Chrome 67 su computer è attiva per impostazione predefinita una nuova funzionalità denominata Isolamento dei siti. Questo spiega cos'è l'isolamento dei siti, perché è necessario e perché gli sviluppatori web dovrebbero tienilo a mente.

Che cos'è l'isolamento dei siti?

Internet consente, tra le altre cose, di guardare video di gatti e di gestire i portafogli di criptovalute. ma non vorresti che fluffycats.example abbia accesso alle tue preziose criptovalute. Per fortuna i siti web in genere non possono accedere ai rispettivi dati all'interno del browser grazie alla Policy. Tuttavia, i siti web dannosi potrebbero tentare di aggirare questa politica per attaccare altri siti web e a volte, vengono rilevati bug di sicurezza nel codice del browser che applica il criterio della stessa origine. La Il team di Chrome punta a risolvere questi bug il più rapidamente possibile.

L'isolamento dei siti è una funzionalità di sicurezza di Chrome che offre una linea di difesa aggiuntiva per è meno probabile che abbiano successo. Garantisce che le pagine di diversi siti web vengano sempre inserite in processi diversi, ognuno in esecuzione in una sandbox che limita ciò che il processo è consentito. Inoltre, impedisce al processo di ricevere determinati tipi di dati sensibili da altri siti. Come di conseguenza, con l'isolamento dei siti è molto più difficile per un sito web dannoso utilizzare attacchi side-channel come Spectre per rubare dati da altri siti. Quando finisce il team di Chrome applicazioni aggiuntive, l'isolamento dei siti sarà utile anche quando la pagina di un malintenzionato può danneggiare delle regole nel proprio processo.

L'isolamento dei siti rende più difficile per i siti web non attendibili accedere o rubare informazioni dai tuoi account su altri siti web. Offre un'ulteriore protezione contro vari tipi di di bug di sicurezza, come i recenti attacchi al canale laterale Meltdown e Spectre.

Per maggiori dettagli sull'isolamento dei siti, vedi il nostro articolo sul blog sulla sicurezza di Google.

Blocco della lettura tra origini

Anche se tutte le pagine tra siti vengono inserite in processi separati, le pagine possono comunque richiedere legittimamente alcune risorse secondarie tra siti, come immagini e JavaScript. Una pagina web dannosa potrebbe utilizzare un Elemento <img> per caricare un file JSON con dati sensibili, come il saldo del tuo conto bancario:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Senza l'isolamento dei siti, i contenuti del file JSON tornerebbero alla memoria del renderer processo, a quel punto il renderer nota che non si tratta di un formato di immagine valido e non esegue il rendering un'immagine. Tuttavia, l’aggressore potrebbe poi sfruttare una vulnerabilità come Spectre per leggerla potenzialmente un frammento di memoria.

Anziché usare <img>, l'utente malintenzionato potrebbe anche usare <script> per eseguire il commit dei dati sensibili in memoria:

<script src="https://your-bank.example/balance.json"></script>

Il blocco della lettura interorigine, o CORB, è una nuova funzionalità di sicurezza che impedisce il contenuto balance.json di impedire l'inserimento nella memoria del processo del renderer in base al tipo MIME.

Vediamo come funziona CORB. Un sito web può richiedere due tipi di risorse a un server:

  1. risorse di dati come documenti HTML, XML o JSON
  2. risorse multimediali come immagini, JavaScript, CSS o caratteri

Un sito web è in grado di ricevere risorse di dati provenienti dalla propria origine o da altre origini con intestazioni CORS permissive, come Access-Control-Allow-Origin: *. Invece, le risorse multimediali possono essere incluse da qualsiasi anche senza intestazioni CORS permissive.

CORB impedisce al processo del renderer di ricevere una risorsa di dati multiorigine (ad esempio HTML, XML o JSON) se:

  • la risorsa ha un'intestazione X-Content-Type-Options: nosniff
  • CORS non consente esplicitamente l'accesso alla risorsa

Se per la risorsa di dati multiorigine non è impostata l'intestazione X-Content-Type-Options: nosniff, CORB tenta di annusare il corpo della risposta per determinare se è HTML, XML o JSON. Questo è necessaria perché alcuni server web non sono configurati correttamente e pubblicano immagini come text/html, ad esempio.

Le risorse di dati bloccate dal criterio CORB vengono presentate al processo come vuote, anche se la richiesta viene ancora eseguita in background. Di conseguenza, una pagina web dannosa ha difficoltà estraendo i dati di più siti nel suo processo per sottrarli.

Per una sicurezza ottimale e per trarre vantaggio da CORB, consigliamo quanto segue:

  • Contrassegna le risposte con l'intestazione Content-Type corretta. Ad esempio, le risorse HTML devono essere gestito come text/html, risorse JSON con un tipo MIME JSON e risorse XML con un tipo MIME XML).
  • Disattiva lo sniffing utilizzando l'intestazione X-Content-Type-Options: nosniff. Senza questa intestazione, Chrome esegue una rapida analisi dei contenuti per verificare che il tipo sia corretto, ma poiché questo permette di consentire le risposte per evitare di bloccare elementi quali i file JavaScript, è meglio fare in modo affermativo.

Per ulteriori dettagli, consulta Articolo CORB per gli sviluppatori web o la nostra spiegazione approfondita di CORB.

Perché gli sviluppatori web dovrebbero interessarsi all'isolamento dei siti?

In gran parte, l'isolamento dei siti è una funzionalità del browser in background che non è esposti agli sviluppatori web. Ad esempio, non esiste una nuova API esposta al web da imparare. In generale, il web le pagine non devono essere in grado di capire la differenza quando vengono eseguite con o senza isolamento dei siti.

Tuttavia, esistono alcune eccezioni a questa regola. L'attivazione dell'isolamento dei siti comporta alcune da eventuali effetti collaterali che potrebbero influire sul tuo sito web. Manteniamo un elenco dei problemi noti di isolamento dei siti, e approfondiamo le più importanti di seguito.

Il layout a pagina intera non è più sincrono

Con l'isolamento dei siti, non è più garantito che il layout a pagina intera sia sincrono, poiché i frame una pagina può ora essere distribuita in più processi. Ciò potrebbe influire sulle pagine se queste ultime ritengono che la modifica al layout si propaga immediatamente a tutti i frame della pagina.

Ad esempio, consideriamo un sito web chiamato fluffykittens.example che comunica con una widget social ospitato su social-widget.example:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

All'inizio, la larghezza di <iframe> del widget social è di 123 pixel. Ma poi la pagina FluffyKittens cambia la larghezza a 456 pixel (layout di attivazione) e invia un messaggio al widget social, che ha il seguente codice:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Ogni volta che il widget social riceve un messaggio tramite l'API postMessage, registra la larghezza il relativo elemento <html> principale.

Quale valore della larghezza viene registrato? Prima che Chrome attivasse l'isolamento dei siti, la risposta era 456. Accesso document.documentElement.clientWidth forza il layout, che prima di Chrome era sincrono attivato l'isolamento dei siti. Tuttavia, con l'isolamento dei siti abilitato, il widget social multiorigine il relayout ora avviene in modo asincrono in un processo separato. Di conseguenza, la risposta può anche essere 123, ovvero il vecchio valore width.

Se una pagina modifica le dimensioni di un <iframe> multiorigine e poi le invia un postMessage, con L'isolamento dei siti del frame ricevente potrebbe non conoscere ancora le sue nuove dimensioni quando riceve il messaggio. Altro in genere, ciò potrebbe interrompere le pagine se presuppongono che una modifica al layout si propaga immediatamente frame sulla pagina.

In questo particolare esempio, una soluzione più efficace imposterebbe width nel frame principale e e rilevare questo cambiamento in <iframe> mediante l'ascolto di un evento resize.

I gestori degli unload potrebbero scadere con maggiore frequenza

Quando un frame si sposta o si chiude, il vecchio documento e gli eventuali documenti del frame secondario incorporati al suo interno. eseguono tutti il proprio gestore unload. Se la nuova navigazione avviene nello stesso processo del renderer (ad esempio, una navigazione della stessa origine), i gestori unload del vecchio documento e i relativi frame secondari possono essere eseguiti arbitrariamente lungo prima di consentire il commit della nuova navigazione.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

In questa situazione, i gestori unload in tutti i frame sono molto affidabili.

Tuttavia, anche senza l'isolamento dei siti, alcune navigazioni del frame principale avvengono in più processi, il che influisce il comportamento del gestore dell'unload. Ad esempio, se passi da old.example a new.example digitando l'URL nella barra degli indirizzi, la navigazione new.example avviene in un nuovo processo. L'unload i gestori per old.example e i relativi frame secondari vengono eseguiti nel processo old.example in background, dopo la visualizzazione della pagina new.example e i precedenti gestori di unload vengono chiusi se devono terminare entro un determinato timeout. Poiché i gestori di unload potrebbero non terminare prima del timeout, il comportamento di unload è meno affidabile.

Con l'isolamento dei siti, tutte le navigazioni tra siti diventano cross-process, in modo che i documenti siti diversi non condividono tra loro i processi. Di conseguenza, la situazione descritta sopra si applica il numero di casi e i gestori di unload in <iframe> hanno spesso il comportamento di background e timeout descritti sopra.

Un'altra differenza derivante dall'isolamento dei siti è il nuovo ordine parallelo dei gestori di unload: senza l'isolamento dei siti, i gestori degli unload vengono eseguiti in ordine rigoroso dall'alto verso il basso tra i frame. Ma con Site I gestori di isolamento e unload vengono eseguiti in parallelo tra diversi processi.

Queste sono le conseguenze fondamentali dell'attivazione dell'isolamento dei siti. Il team di Chrome sta lavorando a migliorando l'affidabilità dei gestori dell'unload per i casi d'uso comuni, ove possibile. Inoltre, a conoscenza dei bug in cui i gestori di unload del frame secondario non sono ancora in grado di utilizzare determinate funzionalità stiamo lavorando per risolverli.

Un caso importante dei gestori di unload è l'invio di ping di fine sessione. In genere questa operazione viene eseguita che segue:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Un approccio migliore e più solido alla luce di questo cambiamento consiste nell'utilizzare le navigator.sendBeacon anziché:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

Se hai bisogno di un maggiore controllo sulla richiesta, puoi utilizzare l'opzione keepalive dell'API Fetch:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Conclusione

L'isolamento dei siti rende più difficile per i siti web non attendibili accedere o rubare informazioni dal tuo su altri siti web isolando ciascun sito nel proprio processo. Per questo motivo, CORB prova per escludere risorse di dati sensibili dal processo del renderer. I nostri consigli precedenti assicurano sfrutta al meglio queste nuove funzionalità di sicurezza.

Grazie a Alex Moshchuk Charlie Reis Jason Miller Nasko Oskov Philip Walton Shubhie Panicker Thomas Steiner per leggere una bozza di questo articolo e fornire i loro feedback.