Banyak aplikasi web perlu menampilkan konten yang dikontrol pengguna. Hal ini bisa sesederhana menayangkan gambar yang diupload pengguna (misalnya, foto profil), atau serumit merender HTML yang dikontrol pengguna (misalnya, tutorial pengembangan web). Hal ini selalu sulit dilakukan secara aman, jadi kami telah bekerja untuk menemukan solusi yang mudah namun aman yang dapat diterapkan ke sebagian besar jenis aplikasi web.
Solusi klasik untuk mengisolasi konten yang tidak tepercaya
Solusi klasik untuk menayangkan konten yang dikontrol pengguna dengan aman adalah menggunakan domain sandbox. Ide dasarnya adalah jika domain utama aplikasi Anda adalah example.com
, Anda dapat menayangkan semua konten yang tidak tepercaya di exampleusercontent.com
. Karena kedua domain ini bersifat lintas situs, konten berbahaya apa pun di exampleusercontent.com
tidak dapat memengaruhi example.com
.
Pendekatan ini dapat digunakan untuk menyajikan semua jenis konten tidak tepercaya dengan aman, termasuk gambar, download, dan HTML. Meskipun penggunaan metode ini untuk gambar atau download mungkin tidak diperlukan, hal tersebut akan membantu menghindari risiko penyadapan konten, terutama di browser lama.
Domain sandbox digunakan secara luas di seluruh industri dan telah bekerja dengan baik untuk waktu yang lama. Namun, mereka memiliki dua kelemahan utama:
- Aplikasi sering kali perlu membatasi akses konten untuk satu pengguna, yang memerlukan penerapan autentikasi dan otorisasi. Karena domain sandbox sengaja tidak membagikan cookie dengan domain aplikasi utama, hal ini sangat sulit dilakukan secara aman. Untuk mendukung autentikasi, situs harus mengandalkan URL kemampuan, atau harus menetapkan cookie autentikasi terpisah untuk domain sandbox. Metode kedua ini sangat bermasalah di web modern, di mana banyak browser membatasi cookie lintas situs secara default.
- Meskipun konten pengguna diisolasi dari situs utama, konten tersebut tidak terisolasi dari konten pengguna lainnya. Hal ini menimbulkan risiko konten pengguna berbahaya yang menyerang data lain di domain sandbox (misalnya, melalui pembacaan data origin yang sama).
Perlu juga dicatat bahwa domain {i>sandbox <i}membantu mengurangi risiko {i>phishing<i} karena sumber daya telah disegmentasikan dengan jelas ke dalam domain yang terisolasi.
Solusi modern untuk menyajikan konten pengguna
Seiring waktu, web telah berkembang, dan kini ada cara yang lebih mudah dan aman untuk menayangkan konten yang tidak tepercaya. Ada banyak pendekatan yang berbeda di sini, jadi kami akan menguraikan dua solusi yang saat ini digunakan secara luas di Google.
Pendekatan 1: Menyajikan konten pengguna yang tidak aktif
Jika situs hanya perlu menayangkan konten pengguna yang tidak aktif (yaitu konten yang bukan HTML atau JavaScript, misalnya gambar dan download), tindakan ini sekarang dapat dilakukan dengan aman tanpa domain sandbox yang terisolasi. Ada dua langkah utama:
- Selalu tetapkan header
Content-Type
ke jenis MIME yang dikenal luas dan didukung oleh semua browser dan dijamin tidak berisi konten aktif (jika ragu,application/octet-stream
adalah pilihan yang aman). - Selain itu, selalu tetapkan header respons di bawah untuk memastikan browser sepenuhnya mengisolasi respons.
Header Respons | Tujuan |
---|---|
X-Content-Type-Options: nosniff |
Mencegah penyadapan konten |
Content-Disposition: attachment; filename="download" |
Memicu download, bukan rendering |
Content-Security-Policy: sandbox |
Sandbox konten seolah-olah disajikan di domain terpisah |
Content-Security-Policy: default-src ‘none' |
Menonaktifkan eksekusi JavaScript (dan penyertaan subresource apa pun) |
Cross-Origin-Resource-Policy: same-site |
Mencegah halaman disertakan lintas situs |
Kombinasi header ini memastikan bahwa respons hanya dapat dimuat sebagai subresource oleh aplikasi Anda, atau didownload sebagai file oleh pengguna. Selain itu, header memberikan perlindungan berlapis terhadap bug browser melalui header sandbox CSP dan pembatasan default-src
. Secara keseluruhan, penyiapan yang diuraikan di atas memberikan tingkat keyakinan yang tinggi bahwa respons yang diberikan dengan cara ini tidak dapat menyebabkan kerentanan injeksi atau isolasi.
Defense in depth
Meskipun solusi di atas mewakili pertahanan yang umumnya cukup memadai terhadap XSS, ada sejumlah langkah pengerasan tambahan yang dapat Anda terapkan untuk memberikan lapisan keamanan tambahan:
- Tetapkan header
X-Content-Security-Policy: sandbox
untuk kompatibilitas dengan IE11. - Tetapkan header
Content-Security-Policy: frame-ancestors 'none'
untuk memblokir endpoint agar tidak disematkan. - Lakukan sandbox konten pengguna di subdomain yang terisolasi dengan:
- Menayangkan konten pengguna di subdomain yang terisolasi (misalnya, Google menggunakan domain seperti
product.usercontent.google.com
). - Tetapkan
Cross-Origin-Opener-Policy: same-origin
danCross-Origin-Embedder-Policy: require-corp
untuk mengaktifkan isolasi lintas asal.
- Menayangkan konten pengguna di subdomain yang terisolasi (misalnya, Google menggunakan domain seperti
Pendekatan 2: Menyajikan konten pengguna aktif
Penyajian konten aktif dengan aman (misalnya, gambar HTML atau SVG) juga dapat dilakukan tanpa kelemahan pendekatan domain {i>sandbox<i} klasik.
Opsi paling sederhana adalah memanfaatkan header Content-Security-Policy: sandbox
untuk memberi tahu browser agar mengisolasi respons. Meskipun tidak semua browser web saat ini menerapkan isolasi proses untuk dokumen sandbox, peningkatan berkelanjutan pada model proses browser kemungkinan akan meningkatkan pemisahan konten dalam sandbox dari penyematan aplikasi. Jika serangan SpectreJS dan penyusupan perender berada di luar model ancaman Anda, penggunaan sandbox CSP kemungkinan merupakan solusi yang cukup.
Di Google, kami telah mengembangkan solusi yang dapat sepenuhnya mengisolasi konten aktif yang tidak tepercaya dengan memodernisasi konsep domain sandbox. Ide intinya adalah untuk:
- Buat domain sandbox baru yang ditambahkan ke daftar akhiran publik. Misalnya, dengan menambahkan
exampleusercontent.com
ke PSL, Anda dapat memastikan bahwafoo.exampleusercontent.com
danbar.exampleusercontent.com
bersifat lintas situs sehingga sepenuhnya terisolasi satu sama lain. - URL yang cocok dengan
*.exampleusercontent.com/shim
semuanya dirutekan ke file shim statis. File shim ini berisi cuplikan HTML dan JavaScript singkat yang memproses pengendali peristiwamessage
dan merender konten apa pun yang diterimanya. - Untuk menggunakan ini, produk akan membuat iframe atau pop-up ke
$RANDOM_VALUE.exampleusercontent.com/shim
dan menggunakanpostMessage
untuk mengirim konten tidak tepercaya ke shim untuk rendering. - Konten yang dirender akan diubah menjadi Blob dan dirender di dalam frame dengan sandbox.
Dibandingkan dengan pendekatan domain {i>sandbox<i} klasik, hal ini memastikan bahwa semua konten sepenuhnya terisolasi di sebuah situs yang unik. Dan, karena memiliki aplikasi utama yang berurusan dengan pengambilan data yang akan dirender, tidak perlu lagi menggunakan URL kemampuan.
Kesimpulan
Bersama-sama, kedua solusi ini memungkinkan migrasi dari domain sandbox klasik seperti googleusercontent.com
ke solusi yang lebih aman yang kompatibel dengan pemblokiran cookie pihak ketiga. Di Google, kami telah memigrasikan banyak produk untuk menggunakan solusi ini dan memiliki rencana migrasi lainnya untuk tahun depan.