Hosting sicuro dei dati utente nelle moderne applicazioni web

David Dworken
David Dworken

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 e Cross-Origin-Embedder-Policy: require-corp per attivare l'isolamento multiorigine.

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 che foo.exampleusercontent.com e bar.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 eventi message 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 utilizza postMessage 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.