Rendere il sito web "isolato multiorigine" utilizzando COOP e COEP

Utilizza COOP e COEP per configurare un ambiente isolato cross-origin e attivare funzionalità avanzate come SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e timer ad alta risoluzione con una precisione migliore.

Aggiornamenti

  • 21 giugno 2022: anche gli script dei service worker richiedono attenzione quando è abilitato l'isolamento cross-origin. Aggiunte alcune spiegazioni.
  • 5 agosto 2021: l'API JS Self-Profiling è stata menzionata come una delle API che richiedono l'isolamento cross-origin, ma riflettendo il recente cambio di direzione, è stata rimossa.
  • 6 maggio 2021: in base ai feedback e ai problemi segnalati, abbiamo deciso di modificare la cronologia di utilizzo di SharedArrayBuffer nei siti non isolati multiorigine in modo che venga limitata in Chrome M92.
  • 16 aprile 2021: sono state aggiunte note su una nuova modalità COEP senza credenziali e su COOP same-origin-allow-popups come condizione meno restrittiva per l'isolamento cross-origin.
  • 5 marzo 2021: sono state rimosse le limitazioni per SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e le funzionalità di debug, ora completamente abilitate in Chrome 89. Sono state aggiunte funzionalità future, performance.now() e performance.timeOrigin, che avranno una maggiore precisione.
  • 19 febbraio 2021: è stata aggiunta una nota sulle norme relative alle funzionalità allow="cross-origin-isolated" e sulla funzionalità di debug in DevTools.
  • 15 ottobre 2020: self.crossOriginIsolated è disponibile a partire da Chrome 87. Di conseguenza, document.domain è immutabile quando self.crossOriginIsolated restituisce true. performance.measureUserAgentSpecificMemory() sta terminando la prova dell'origine ed è attivato per impostazione predefinita in Chrome 89. SharedArrayBuffer su Android Chrome sarà disponibile a partire da Chrome 88.

Alcune API web aumentano il rischio di attacchi side-channel come Spectre. Per mitigare questo rischio, i browser offrono un ambiente isolato basato sull'attivazione chiamato isolamento multiorigine. Con uno stato di isolamento cross-origin, la pagina web potrà utilizzare funzionalità privilegiate, tra cui:

API Descrizione
SharedArrayBuffer Obbligatorio per i thread WebAssembly. Questa opzione è disponibile a partire da Android Chrome 88. La versione desktop è attualmente attiva per impostazione predefinita con l'aiuto dell' isolamento dei siti, ma richiederà lo stato di isolamento multiorigine e sarà disattivata per impostazione predefinita in Chrome 92.
performance.measureUserAgentSpecificMemory() Disponibile a partire da Chrome 89.
performance.now(), performance.timeOrigin Attualmente disponibile in molti browser con una risoluzione limitata a 100 microsecondi o superiore. Con l'isolamento cross-origin, la risoluzione può essere di 5 microsecondi o superiore.
Funzionalità che saranno disponibili dietro lo stato di isolamento multiorigine.

Lo stato di isolamento multiorigine impedisce anche le modifiche di document.domain. La possibilità di modificare document.domain consente la comunicazione tra documenti dello stesso sito ed è stata considerata una scappatoia nei criteri della stessa origine.

Per attivare uno stato di isolamento multiorigine, devi inviare le seguenti intestazioni HTTP nel documento principale:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Queste intestazioni indicano al browser di bloccare il caricamento di risorse o iframe che non hanno acconsentito al caricamento da parte di documenti cross-origin e impediscono alle finestre cross-origin di interagire direttamente con il tuo documento. Ciò significa anche che il caricamento di queste risorse multiorigine richiede l'attivazione.

Puoi determinare se una pagina web è in uno stato di isolamento multiorigine esaminando self.crossOriginIsolated.

Questo articolo mostra come utilizzare queste nuove intestazioni. In un articolo di approfondimento fornirò maggiori informazioni di base e contesto.

Esegui il deployment di COOP e COEP per isolare il tuo sito web da origini diverse

Integrare COOP e COEP

1. Imposta l'intestazione Cross-Origin-Opener-Policy: same-origin nel documento di primo livello

Se attivi COOP: same-origin in un documento di primo livello, le finestre con la stessa origine e le finestre aperte dal documento avranno un gruppo di contesto di navigazione separato, a meno che non si trovino nella stessa origine con la stessa impostazione COOP. Pertanto, l'isolamento viene applicato alle finestre aperte e la comunicazione reciproca tra le due finestre è disattivata.

Un gruppo di contesti di navigazione è un insieme di finestre che possono fare riferimento l'una all'altra. Ad esempio, un documento di primo livello e i relativi documenti secondari incorporati tramite <iframe>. Se un sito web (https://a.example) apre una finestra popup (https://b.example), la finestra di apertura e la finestra popup condividono lo stesso contesto di navigazione, pertanto hanno accesso l'una all'altra tramite API DOM come window.opener.

Gruppo di contesti di navigazione

Puoi verificare se l'apertura della finestra e il relativo destinatario si trovano in gruppi di contesti di navigazione separati da DevTools.

2. Assicurati che le risorse abbiano CORP o CORS abilitato

Assicurati che tutte le risorse della pagina vengano caricate con le intestazioni HTTP CORP o CORS. Questo passaggio è necessario per il passaggio 4, l'attivazione di COEP.

Ecco cosa devi fare a seconda della natura della risorsa:

  • Se la risorsa deve essere caricata solo dalla stessa origine, imposta l'intestazione Cross-Origin-Resource-Policy: same-origin.
  • Se la risorsa deve essere caricata solo dallo stesso sito, ma con origine incrociata, imposta l'intestazione Cross-Origin-Resource-Policy: same-site.
  • Se la risorsa viene caricata da origini diverse sotto il tuo controllo, imposta l'intestazione Cross-Origin-Resource-Policy: cross-origin, se possibile.
  • Per le risorse multiorigine su cui non hai il controllo:
    • Utilizza l'attributo crossorigin nel tag HTML di caricamento se la risorsa viene pubblicata con CORS. Ad esempio <img src="***" crossorigin>.
    • Chiedi al proprietario della risorsa di supportare CORS o CORP.
  • Per gli iframe, segui gli stessi principi indicati sopra e imposta Cross-Origin-Resource-Policy: cross-origin (o same-site, same-origin a seconda del contesto).
  • Gli script caricati con un WebWorker devono essere pubblicati dalla stessa origine, pertanto non sono necessarie intestazioni CORP o CORS.
  • Per un documento o un worker pubblicato con COEP: require-corp, le risorse secondarie multiorigine caricate senza CORS devono impostare l'intestazione Cross-Origin-Resource-Policy: cross-origin per attivare l'incorporamento. Ad esempio, questo vale per <script>, importScripts, <link>, <video>, <iframe> e così via.

3. Utilizzare l'intestazione HTTP COEP Report-Only per valutare le risorse incorporate

Prima di attivare completamente COEP, puoi eseguire una prova generale utilizzando l'intestazione Cross-Origin-Embedder-Policy-Report-Only per verificare se il criterio funziona effettivamente. Riceverai i report senza bloccare i contenuti incorporati.

Applica questa impostazione in modo ricorsivo a tutti i documenti, inclusi il documento di primo livello, gli iframe e gli script worker. Per informazioni sull'intestazione HTTP Report-Only, consulta Osservare i problemi utilizzando l'API Reporting.

4. Abilita COEP

Una volta verificato che tutto funzioni e che tutte le risorse possano essere caricate correttamente, passa dall'intestazione Cross-Origin-Embedder-Policy-Report-Only all'intestazione Cross-Origin-Embedder-Policy con lo stesso valore per tutti i documenti, inclusi quelli incorporati tramite iframe e script worker.

Determinare se l'isolamento è riuscito con self.crossOriginIsolated

La proprietà self.crossOriginIsolated restituisce true quando la pagina web si trova in uno stato di isolamento cross-origin e tutte le risorse e le finestre sono isolate all'interno dello stesso gruppo di contesti di navigazione. Puoi utilizzare questa API per determinare se hai isolato correttamente il gruppo di contesti di navigazione e ottenuto l'accesso a funzionalità avanzate come performance.measureUserAgentSpecificMemory().

Eseguire il debug dei problemi utilizzando Chrome DevTools

Per le risorse visualizzate sullo schermo, come le immagini, è abbastanza facile rilevare i problemi relativi a COEP perché la richiesta verrà bloccata e la pagina indicherà un'immagine mancante. Tuttavia, per le risorse che non hanno necessariamente un impatto visivo, come script o stili, i problemi relativi a COEP potrebbero passare inosservati. Per questi, utilizza il riquadro Rete di DevTools. Se si verifica un problema con COEP, dovresti vedere (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) nella colonna Stato.

Problemi relativi a COEP nella colonna Stato del riquadro Rete.

Puoi quindi fare clic sulla voce per visualizzare ulteriori dettagli.

I dettagli del problema COEP vengono visualizzati nella scheda Intestazioni dopo aver fatto clic su una risorsa di rete nel riquadro Rete.

Puoi anche determinare lo stato di iframe e finestre popup tramite il pannello Applicazione. Vai alla sezione "Frame" a sinistra ed espandi "top" per visualizzare la suddivisione della struttura delle risorse.

Puoi controllare lo stato dell'iframe, ad esempio la disponibilità di SharedArrayBuffer, ecc.

Iframe Inspector di Chrome DevTools

Puoi anche controllare lo stato delle finestre popup, ad esempio se sono isolate tra origini diverse.

Ispettore della finestra popup di Chrome DevTools

Osservare i problemi utilizzando l'API Reporting

L'API Reporting è un altro meccanismo tramite il quale puoi rilevare vari problemi. Puoi configurare l'API Reporting in modo che il browser degli utenti invii un report ogni volta che COEP blocca il caricamento di una risorsa o COOP isola una finestra popup. Chrome supporta l'API Reporting dalla versione 69 per una serie di utilizzi, tra cui COEP e COOP.

Per scoprire come configurare l'API di reporting e impostare un server per ricevere i report, consulta Utilizzo dell'API di reporting.

Report COEP di esempio

Un esempio di payload di un report COEP quando la risorsa multiorigine è bloccata è il seguente:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.glitch.me/check.svg?",
    "blockedURL": "https://third-party-test.glitch.me/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

Report COOP di esempio

Un esempio di payload del report COOP quando viene aperta una finestra popup isolata è il seguente:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Quando diversi gruppi di contesti di navigazione tentano di accedere l'uno all'altro (solo in modalità "solo report"), COOP invia anche un report. Ad esempio, un report quando viene tentato postMessage() avrà il seguente aspetto:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Conclusione

Utilizza una combinazione di intestazioni HTTP COOP e COEP per attivare una pagina web in uno stato speciale di isolamento cross-origin. Potrai esaminare self.crossOriginIsolated per determinare se una pagina web si trova in uno stato di isolamento cross-origin.

Continueremo ad aggiornare questo post man mano che nuove funzionalità verranno rese disponibili per questo stato di isolamento cross-origin e verranno apportati ulteriori miglioramenti a DevTools in merito a COOP e COEP.

Risorse