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

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

Aggiornamenti

  • 21 giugno 2022: anche gli script worker richiedono attenzione quando è abilitato l'isolamento multiorigine. Sono state aggiunte alcune spiegazioni.
  • 5 agosto 2021: l'API JS Self-Profiling è stata menzionata come una delle API che richiedono l'isolamento multiorigine, ma in base a una recente modifica della direzione, viene rimossa.
  • 6 maggio 2021: in base ai feedback e ai problemi segnalati, abbiamo deciso di modificare la tempistica per l'utilizzo di SharedArrayBuffer nei siti non con isolamento multiorigine in modo che sia limitato in Chrome M92.
  • 16 aprile 2021: sono state aggiunte note relative alla nuova modalità COEP senza credenziali e alla COOP same-origin-allow-popups come condizione informale per l'isolamento multiorigine.
  • 5 marzo 2021: sono state rimosse le limitazioni per SharedArrayBuffer, performance.measureUserAgentSpecificMemory() e le funzionalità di debug, che ora sono 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 relativa ai criteri delle funzionalitàallow="cross-origin-isolated" e alla funzionalità di debug in DevTools.
  • 15 ottobre 2020: self.crossOriginIsolated è disponibile da Chrome 87. Ciò significa che document.domain è immutabile quando self.crossOriginIsolated restituisce true. performance.measureUserAgentSpecificMemory() sta terminando la prova dell'origine e è attiva per impostazione predefinita in Chrome 89. L'array buffer condiviso su Chrome per Android sarà disponibile da Chrome 88.

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

API Descrizione
SharedArrayBuffer Obbligatorio per i thread WebAssembly. Questa funzionalità è disponibile su Android Chrome 88. Al momento la versione desktop è 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 da Chrome 89.
performance.now(), performance.timeOrigin Attualmente disponibile in molti browser con una risoluzione limitata a almeno 100 microsecondi. Con l'isolamento cross-origin, la risoluzione può essere pari o superiore a 5 microsecondi.
Funzionalità che saranno disponibili nello stato con isolamento multiorigine.

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

Per attivare lo stato con isolamento multiorigine, devi inviare le seguenti intestazioni HTTP sul documento principale:

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

Queste intestazioni ordinano al browser di bloccare il caricamento di risorse o iframe che non sono stati attivati per il caricamento da documenti cross-origin e impediscono alle finestre cross-origin di interagire direttamente con il documento. Ciò significa anche che le risorse caricate in più origini richiedono l'attivazione.

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

Questo articolo spiega come utilizzare queste nuove intestazioni. In un articolo di follow-up fornirò ulteriori informazioni e contesto.

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

Integra 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 quelle aperte dal documento avranno un gruppo di contesti 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 entrambe le finestre viene 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 controllare se l'apri finestra e la finestra aperta appartengono a gruppi di contesti di navigazione distinti da DevTools.

2. Assicurati che per le risorse sia abilitato CORP o CORS

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

Ecco cosa devi fare a seconda della natura della risorsa:

  • Se la risorsa dovrebbe essere caricata solo dalla stessa origine, imposta l'intestazione Cross-Origin-Resource-Policy: same-origin.
  • Se si prevede che la risorsa venga caricata solo dallo stesso sito, ma con origini diverse, 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 cross-origin su cui non hai alcun 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 gestiti dalla stessa origine, quindi non hai bisogno di un'intestazione CORP o CORS.
  • Per un documento o un worker pubblicato con COEP: require-corp, i risorse secondarie cross-origin caricate senza CORS devono impostare l'intestazione Cross-Origin-Resource-Policy: cross-origin per attivare l'inserimento. Ad esempio, si applica a <script>, importScripts, <link>, <video>, <iframe> e così via.

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

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

Applicalo in modo ricorsivo a tutti i documenti, inclusi il documento di primo livello, gli iframe e gli script worker. Per informazioni sull'intestazione HTTP Solo report, consulta Osservare i problemi relativi all'utilizzo dell'API Reporting.

4. Attivare il protocollo COEP

Una volta verificato che tutto funzioni e che tutte le risorse possono essere caricate correttamente, passa l'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.

Determina se l'isolamento è riuscito con self.crossOriginIsolated

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

Risolvere i problemi di debug utilizzando Chrome DevTools

Per le risorse visualizzate sullo schermo, come le immagini, è abbastanza facile rilevare i problemi relativi ai contenuti offensivi 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 al COEP potrebbero non essere rilevati. Per questi, utilizza il riquadro Rete di DevTools. Se si verifica un problema con il COEP, nella colonna Stato dovresti vedere (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep).

Problemi relativi al 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 degli iframe e delle finestre popup tramite il riquadro Applicazione. Vai alla sezione "Frame" a sinistra e espandi "superiore" per visualizzare la suddivisione della struttura della risorsa.

Puoi controllare lo stato dell'iframe, ad esempio la disponibilità di SharedArrayBuffer e così via.

Strumento di controllo iframe di Chrome DevTools

Puoi anche controllare lo stato delle finestre popup, ad esempio se sono isolate multiorigine.

Controllo delle finestre popup di Chrome DevTools

Osservare i problemi utilizzando l'API di reporting

L'API Reporting è un altro meccanismo tramite il quale puoi rilevare vari problemi. Puoi configurare l'API Reporting in modo da indicare al browser degli utenti di inviare un report ogni volta che il blocco di caricamento di una risorsa o l'isolamento di una finestra popup da parte di COEP si verificano. Chrome supporta l'API di reporting dalla versione 69 per diversi 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.

Esempio di report COEP

Un esempio di payload del report su CoEP quando la risorsa cross-origin è 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 ha il seguente aspetto:

[{
  "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 gruppi di contesti di navigazione diversi tentano di accedere l'uno all'altro (solo in modalità "solo report"), anche COOP invia un report. Ad esempio, un report quando si cerca di usare 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 uno speciale stato isolato multiorigine per una pagina web. Potrai esaminare self.crossOriginIsolated per determinare se una pagina web è in uno stato di isolamento cross-origin.

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

Risorse