Molte applicazioni web devono mostrare contenuti controllati dagli utenti. Può trattarsi di operazioni semplici come la pubblicazione di immagini caricate dagli utenti (ad esempio, foto del profilo) o complesse come la visualizzazione di codice HTML controllato dall'utente (ad esempio, un tutorial sullo sviluppo web). È sempre stato difficile farlo in sicurezza, quindi ci siamo impegnati per trovare soluzioni semplici ma sicure che possano essere applicate alla maggior parte dei tipi di applicazioni web.
Soluzioni classiche per l'isolamento dei contenuti non attendibili
La soluzione classica per pubblicare in modo sicuro contenuti controllati dagli utenti consiste nell'utilizzare i cosiddetti domini sandbox. L'idea di base è che se il dominio principale della tua applicazione è example.com
, potresti pubblicare tutti i contenuti non attendibili su exampleusercontent.com
. Poiché questi due domini sono cross-site, qualsiasi contenuto dannoso su exampleusercontent.com
non può influire su example.com
.
Questo approccio può essere usato per pubblicare in sicurezza tutti i tipi di contenuti non attendibili, tra cui immagini, download e HTML. Potrebbe non sembrare necessario utilizzare questa funzionalità per le immagini o i download, ma ciò consente di evitare i rischi dello sniffing dei contenuti, soprattutto nei browser precedenti.
I domini sandbox sono ampiamente utilizzati in tutto il settore e hanno funzionato bene da molto tempo. Tuttavia, presentano due principali svantaggi:
- Spesso le applicazioni devono limitare l'accesso ai contenuti a un singolo utente, il che richiede l'implementazione dell'autenticazione e dell'autorizzazione. Poiché i domini sandbox non condividono intenzionalmente i cookie con il dominio principale dell'applicazione, questa operazione è molto difficile da eseguire in sicurezza. Per supportare l'autenticazione, i siti devono fare affidamento su URL di funzionalità oppure impostare cookie di autenticazione separati per il dominio sandbox. Questo secondo metodo è particolarmente problematico nel web moderno, dove molti browser limitano i cookie in più siti per impostazione predefinita.
- Sebbene i contenuti degli utenti siano isolati dal sito principale, non vengono isolati da altri contenuti dell'utente. Ciò comporta il rischio che contenuti utente dannosi attaccano altri dati sul dominio sandbox (ad esempio, tramite la lettura di dati della stessa origine).
Vale anche la pena notare che i domini sandbox aiutano a mitigare i rischi di phishing poiché le risorse sono chiaramente segmentate su un dominio isolato.
Soluzioni moderne per la pubblicazione di contenuti per gli utenti
Nel corso del tempo il web si è evoluto e ora esistono modi più semplici e sicuri per pubblicare contenuti non attendibili. Ci sono molti approcci diversi in questo caso, quindi definiremo due soluzioni che sono attualmente ampiamente utilizzate in Google.
Approccio 1: pubblicazione di contenuti di utenti inattivi
Se un sito deve pubblicare solo contenuti di utenti inattivi (ovvero contenuti non HTML o JavaScript, ad esempio immagini e download), ora puoi farlo senza un dominio sandbox isolato. Ci sono due passaggi chiave:
- Imposta sempre l'intestazione
Content-Type
su un tipo MIME noto che è supportato da tutti i browser e che non contiene contenuti attivi (in caso di dubbi,application/octet-stream
è una scelta sicura). - Inoltre, imposta sempre le seguenti intestazioni della risposta per garantire che il browser isoli completamente la risposta.
Intestazione della risposta | Purpose |
---|---|
X-Content-Type-Options: nosniff |
Impedisce lo sniffing dei contenuti |
Content-Disposition: attachment; filename="download" |
Attiva un download anziché il rendering |
Content-Security-Policy: sandbox |
Archivia i contenuti come se fossero pubblicati su un dominio separato |
Content-Security-Policy: default-src ‘none' |
Disabilita l'esecuzione di JavaScript (e l'inclusione di eventuali risorse secondarie) |
Cross-Origin-Resource-Policy: same-site |
Impedisce l'inclusione della pagina tra siti |
Questa combinazione di intestazioni garantisce che la risposta possa essere caricata solo come sottorisorsa dall'applicazione o scaricata come file dall'utente. Inoltre, le intestazioni forniscono più livelli di protezione contro i bug del browser tramite l'intestazione sandbox CSP e la restrizione default-src
. Nel complesso, la configurazione descritta sopra fornisce un alto grado di certezza che le risposte fornite in questo modo non possono portare a vulnerabilità di iniezione o isolamento.
Difesa in profondità
Sebbene la soluzione di cui sopra rappresenti in genere una difesa sufficiente contro l’XSS, ci sono una serie di misure di protezione aggiuntive che puoi applicare per fornire ulteriori livelli di sicurezza:
- Imposta un'intestazione
X-Content-Security-Policy: sandbox
per garantire la compatibilità con IE11. - Imposta un'intestazione
Content-Security-Policy: frame-ancestors 'none'
per bloccare l'incorporamento dell'endpoint. - Sandbox dei contenuti degli utenti in un sottodominio isolato per:
- Pubblicazione di contenuti degli utenti in un sottodominio isolato (ad esempio, Google utilizza domini come
product.usercontent.google.com
). - Imposta
Cross-Origin-Opener-Policy: same-origin
eCross-Origin-Embedder-Policy: require-corp
per attivare l'isolamento multiorigine.
- Pubblicazione di contenuti degli utenti in un sottodominio isolato (ad esempio, Google utilizza domini come
Approccio 2: pubblicazione di contenuti di utenti attivi
La pubblicazione sicura dei contenuti attivi (ad esempio, immagini HTML o SVG) può avvenire anche senza i punti deboli dell'approccio classico ai domini sandbox.
L'opzione più semplice consiste nello utilizzare l'intestazione Content-Security-Policy: sandbox
per indicare al browser di isolare la risposta. Sebbene non tutti i browser web implementino l'isolamento dei processi per i documenti sandbox, è probabile che i continui perfezionamenti ai modelli di processo del browser migliorino la separazione dei contenuti sandbox dall'incorporamento delle applicazioni. Se gli attacchi SpectreJS e compromissioni del rendering sono al di fuori del tuo modello di minaccia, l'utilizzo della sandbox CSP è probabilmente una soluzione sufficiente.
Google ha sviluppato una soluzione in grado di isolare completamente i contenuti attivi non attendibili mediante la modernizzazione del concetto di domini sandbox. L'idea alla base è:
- Crea un nuovo dominio sandbox da aggiungere all'elenco dei suffissi pubblici. Ad esempio, aggiungendo
exampleusercontent.com
al PSL, puoi assicurarti chefoo.exampleusercontent.com
ebar.exampleusercontent.com
siano in più siti e quindi completamente isolati tra loro. - Gli URL che corrispondono a
*.exampleusercontent.com/shim
vengono tutti indirizzati a un file shim statico. Questo file shim contiene un breve snippet HTML e JavaScript che ascolta il gestore di eventimessage
e esegue il rendering di tutti i contenuti ricevuti. - Per usarlo, il prodotto crea un iframe o un popup per
$RANDOM_VALUE.exampleusercontent.com/shim
e utilizzapostMessage
per inviare i contenuti non attendibili allo shim per il rendering. - I contenuti visualizzati vengono trasformati in un BLOB e visualizzati all'interno di un iframe con sandbox.
Rispetto all'approccio classico ai domini sandbox, questo assicura che tutti i contenuti siano completamente isolati su un unico sito. Inoltre, avendo l'applicazione principale che deve recuperare i dati di cui eseguire il rendering, non è più necessario usare gli URL delle funzionalità.
Conclusione
Insieme, queste due soluzioni consentono di migrare dai domini sandbox classici come googleusercontent.com
a soluzioni più sicure compatibili con il blocco dei cookie di terze parti. Noi di Google abbiamo già eseguito la migrazione di molti prodotti a queste soluzioni e abbiamo in programma altre migrazioni per il prossimo anno.