Molte applicazioni web devono mostrare contenuti controllati dall'utente. Può trattarsi sia della pubblicazione di immagini caricate dagli utenti (ad esempio, foto del profilo) sia del rendering del codice HTML controllato dagli utenti (ad esempio, un tutorial di 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 isolare i 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
. Dal momento che questi due domini sono cross-site, qualsiasi contenuto dannoso su exampleusercontent.com
non può influire su example.com
.
Questo approccio può essere utilizzato per pubblicare in modo sicuro tutti i tipi di contenuti non attendibili, inclusi immagini, download e HTML. Potrebbe non sembrare necessario utilizzare questa opzione per le immagini o i download, ma ciò consente di evitare il rischio di sniffing dei contenuti, soprattutto nei browser precedenti.
I domini sandbox sono ampiamente utilizzati nel settore e funzionano bene da molto tempo. Tuttavia, i due svantaggi principali sono due:
- Le applicazioni spesso 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 dell'applicazione principale, è molto difficile farlo in sicurezza. Per supportare l'autenticazione, i siti devono basarsi sugli URL delle funzionalità oppure devono 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 sono isolati dagli altri contenuti degli utenti. Ciò crea il rischio che contenuti utente dannosi attacchino altri dati nel dominio sandbox (ad esempio tramite la lettura di dati della stessa origine).
Vale anche la pena notare che i domini sandbox aiutano a ridurre i rischi di phishing poiché le risorse sono chiaramente segmentate in un dominio isolato.
Soluzioni moderne per la pubblicazione dei contenuti degli utenti
Nel corso del tempo il web si è evoluto e ora esistono modi più semplici e sicuri per pubblicare contenuti non attendibili. Esistono molti approcci diversi, quindi illustreremo due soluzioni che sono attualmente molto utilizzate in Google.
Approccio 1: pubblicare contenuti degli utenti inattivi
Se un sito deve pubblicare solo contenuti di utenti inattivi (ovvero contenuti non HTML o JavaScript come, ad esempio, immagini e download), ora è possibile farlo in sicurezza senza un dominio sandbox isolato. Ci sono due passaggi fondamentali:
- Imposta sempre l'intestazione
Content-Type
su un tipo MIME noto che sia supportato da tutti i browser e non contenga contenuti attivi (in caso di dubbio,application/octet-stream
è una scelta sicura). - Inoltre, imposta sempre le intestazioni di risposta seguenti 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 |
Limita la sandbox dei 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 sottorisorse) |
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 risorsa secondaria 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 limitazione default-src
. Nel complesso, la configurazione descritta sopra fornisce un elevato grado di certezza che le risposte fornite in questo modo non possano portare a vulnerabilità di injection o isolamento.
Difesa in profondità
Sebbene la soluzione descritta sopra rappresenti una difesa generalmente sufficiente contro le minacce XSS, esistono una serie di misure di rafforzamento aggiuntive che è possibile applicare per fornire ulteriori livelli di sicurezza:
- Imposta un'intestazione
X-Content-Security-Policy: sandbox
per la compatibilità con IE11. - Imposta un'intestazione
Content-Security-Policy: frame-ancestors 'none'
per bloccare l'incorporamento dell'endpoint. - Contenuti degli utenti sandbox in un sottodominio isolato:
- Pubblicazione dei contenuti degli utenti in un sottodominio isolato (ad es. 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 dei contenuti degli utenti in un sottodominio isolato (ad es. Google utilizza domini come
Approccio 2: pubblicazione di contenuti degli utenti attivi
Anche la pubblicazione in sicurezza dei contenuti attivi (ad esempio immagini HTML o SVG) può essere eseguita senza i punti deboli dell'approccio classico dei domini sandbox.
L'opzione più semplice consiste nello sfruttare l'intestazione Content-Security-Policy: sandbox
per indicare al browser di isolare la risposta. Sebbene non tutti i browser web implementino attualmente l'isolamento dei processi per i documenti sandbox, è probabile che i continui perfezionamenti ai modelli di processo browser migliorino la separazione dei contenuti sandbox dalle applicazioni di incorporamento. Se gli attacchi SpectreJS e di compromissioni di renderingr non rientrano nel 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 modernizzando il concetto di domini sandbox. L'idea alla base è:
- Crea un nuovo dominio sandbox che venga aggiunto all'elenco dei suffissi pubblici. Ad esempio, aggiungendo
exampleusercontent.com
al PSL, puoi assicurarti chefoo.exampleusercontent.com
ebar.exampleusercontent.com
siano cross-site e quindi completamente isolati l'uno dall'altro. - 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 visualizza tutti i contenuti che riceve. - Per usare questa funzionalità, il prodotto crea un iframe o un popup in
$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 del dominio sandbox, questo garantisce che tutti i contenuti siano completamente isolati su un sito unico. Inoltre, se l'applicazione principale si occupa del recupero dei dati da visualizzare, non è più necessario utilizzare URL di funzionalità.
Conclusione
Insieme, queste due soluzioni consentono di eseguire la migrazione 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 per utilizzare queste soluzioni e abbiamo in programma altre migrazioni per il prossimo anno.