- Untuk mencegah serangan XSS, salah satu kerentanan utama di web, Firefox menjadi yang pertama mendukung Sanitizer API yang telah distandardisasi
- Dengan menggunakan metode setHTML() alih-alih innerHTML yang lama, HTML yang tidak tepercaya akan disanitasi secara otomatis sebelum dimasukkan ke DOM, sehingga skrip berbahaya dapat dihapus
- Pengembang dapat mengontrol elemen dan atribut yang diizinkan melalui pengaturan kustom jika konfigurasi bawaan terasa terlalu ketat atau kurang memadai
- Fitur Firefox ini, bila digabungkan dengan Trusted Types, meningkatkan tingkat keamanan web secara keseluruhan dan memungkinkan pengembang mencegah XSS tanpa perlu tim keamanan khusus
Kerentanan XSS dan respons Firefox
- Cross-site scripting (XSS) terjadi ketika penyerang menyisipkan HTML atau JavaScript arbitrer melalui konten yang dimasukkan pengguna
- Penyerang dapat memanfaatkannya untuk memantau interaksi pengguna atau mencuri data
- XSS telah diklasifikasikan sebagai salah satu dari 3 kerentanan web teratas (CWE-79) selama hampir 10 tahun
- Sejak 2009, Firefox telah memperkuat pertahanan terhadap XSS dengan memimpin standardisasi Content-Security-Policy (CSP)
- CSP membatasi resource yang boleh dimuat dan dijalankan oleh situs web
- Namun, karena memerlukan perubahan struktur situs yang ada dan peninjauan keamanan berkelanjutan, adopsi luasnya memiliki keterbatasan
Peran Sanitizer API dan setHTML()
- Sanitizer API menyediakan cara yang distandardisasi untuk mengubah HTML berbahaya menjadi bentuk yang aman
- Dalam contoh kode, elemen
<img src="x" onclick="alert('XSS')"> dihapus dan hanya <h1>Hello my name is</h1> yang tersisa
- Metode setHTML() secara otomatis menjalankan proses sanitasi saat HTML disisipkan, sehingga menjamin perilaku yang aman secara default
- Cukup dengan mengganti assignment
innerHTML yang lama menjadi setHTML(), pertahanan XSS yang kuat bisa diperoleh
- Jika konfigurasi bawaan terlalu ketat atau terlalu longgar, pengembang dapat mendefinisikan elemen dan atribut HTML yang diizinkan melalui pengaturan kustom
- Untuk eksperimen, dapat digunakan alat Sanitizer API playground
Integrasi dengan Trusted Types
- Trusted Types API menyediakan lapisan keamanan tambahan dengan mengendalikan parsing dan penyisipan HTML secara terpusat
- Kebijakan Trusted Types dapat dengan mudah diterapkan saat menggunakan
setHTML()
- Kebijakan yang ketat hanya mengizinkan
setHTML() dan memblokir metode penyisipan berisiko lainnya, sehingga membantu mencegah regresi XSS di masa depan
Dampak peningkatan keamanan di Firefox 148
- Firefox 148 mendukung Sanitizer API dan Trusted Types, sehingga secara signifikan meningkatkan tingkat keamanan dasar
- Pengembang dapat mencegah XSS hanya dengan perubahan kode sederhana, tanpa kebijakan keamanan yang kompleks atau tim keamanan terpisah
- Adopsi standar ini diharapkan akan mendorong penyebaran lingkungan web yang aman di semua browser
Ringkasan
- Firefox 148 mendukung pengembang web agar mudah memblokir serangan XSS melalui metode setHTML() dan Sanitizer API
- Fitur ini melengkapi keterbatasan CSP dan menjadi momentum untuk menjadikan cara penyisipan HTML yang aman secara default sebagai standar web
- Dengan integrasi Trusted Types, pemeliharaan keamanan jangka panjang dan pencegahan regresi XSS menjadi mungkin
- Hasilnya, Firefox memimpin transisi menuju lingkungan web dengan keamanan sebagai nilai bawaan
2 komentar
Oh, memang hal seperti ini jelas memang diperlukan. Akan sangat bagus kalau didukung di semua browser.
Opini Hacker News
Fitur seperti ini selalu terasa agak mengkhawatirkan
Karena ada campuran metode yang aman untuk menerima input pengguna sembarang dan metode yang tidak aman, tetapi dari namanya saja sulit dibedakan
Idealnya, sejak awal fungsi yang berbahaya harus terlihat jelas dari namanya
Selain itu, konsep “sanitize” HTML itu sendiri ambigu, dan sulit menilai apakah benar-benar aman
Elemen atau atribut yang bisa mengeksekusi skrip dihapus, dan logika ini berjalan di dalam engine browser sehingga ditangani lebih akurat dibanding sanitizer berbasis string
Lihat detailnya di dokumentasi MDN setHTML
elementNode.textContentaman untuk input yang tidak tepercaya, sedangkanelementNode.innerHTMLtidakYang pertama melakukan escape pada semua karakter, yang kedua tidak melakukan escape apa pun
Ada juga pendapat bahwa “HTML sanitization” pada dasarnya adalah masalah yang tidak mungkin diselesaikan secara tuntas
Lihat pembahasan terkait di komentar ini
API seperti ini seharusnya tidak lolos pada tahap proposal
innerHTMLdansetHTML, seharusnyainnerHTMLdihapus sepenuhnya dan jika perilaku lama dibutuhkan gunakansetHTMLUnsafeinnerHTMLlewat pengaturan globalNamun kalau begitu, situs mungkin tidak akan berjalan di browser lama
Content-Security-Policy: require-trusted-types-for 'script', maka string biasa bisa dicegah untuk diteruskan ke metode tanpa sanitizerJika seperti pada contoh, tag seperti
<h1>atau<br>bisa disisipkan ke nama pengguna, maka meskipun eksekusi skrip diblokir tetap saja memungkinkan injeksi markup sewenang-wenangDengan tag
<style>pun CSS bisa diubah, sehingga misalnya desain halaman profil PayPal bisa dimodifikasiSulit membayangkan siapa yang benar-benar menginginkan ini
HTML yang dihasilkan dari Markdown bisa dibatasi lagi dengan sanitizer agar hanya tag tertentu yang diizinkan, menambah satu lapisan pertahanan
innerHTMLmelainkaninnerTextatautextContentsetHTMLadalah pengganti untukinnerHTMLsetHTML()terlalu ketat atau terlalu longgar, pengembang bisa menyediakan konfigurasi kustom untuk menentukan sendiri elemen dan atribut HTML yang diizinkanLihat diskusi terkait di thread ini
Pada akhirnya backend tetap harus men-sanitize nama pengguna dengan cara standar, dan saat output harus diterapkan HTML escape
Menurut RFC 2119, ini adalah persyaratan tingkat “SHOULD”
Senang melihat fitur ini hadir, tetapi tampaknya perlu waktu sampai dukungan browser benar-benar cukup luas
Status dukungan bisa dicek di Can I use
Sementara itu bisa digantikan dengan polyfill
Judulnya agak sensasional
Sebenarnya bukankah sanitization juga bisa diimplementasikan dengan fungsi yang memeriksa input sebelum diberikan ke
innerHTMLHanya saja upaya seperti itu pada akhirnya terasa seperti menciptakan ulang roda
Selain itu, di Firefox lama, hacks.mozilla.org bahkan tidak terbuka sama sekali, dan di Pale Moon atau SeaMonkey MDN terlihat rusak
Rasanya seperti “kartel browser” sedang mencoba merusak web
Itu juga mengabaikan masalah parser differential
Jika Sanitizer API dipakai dengan salah, ini bisa menjadi footgun
Terutama harus hati-hati saat memakai mode “remove”
Menurut saya lebih baik cukup gunakan
setTextdan sama sekali tidak mengizinkan pengguna menambahkan HTMLsetHTML, XSS tidak akan terjadiMelihat kenyataan bahwa
innerHTMLsering dipakai, sulit untuk sepenuhnya menyingkirkannyaMengesankan bahwa semua aspek akses jaringan sudah dikendalikan dengan baik, sehingga kini rantai keamanan berpindah dari kepercayaan pada kode ke kepercayaan pada konfigurasi host
Nilai bawaannya juga disetel aman
Yang benar-benar saya inginkan adalah elemen
<sandbox>yang bisa menjalankan kode berbahaya dengan amanBukan memperbaiki kode berbahaya, melainkan memungkinkannya berjalan di lingkungan yang terisolasi
iframe punya keterbatasan karena tidak bisa mengalir bersama DOM, dan di era AI serta konten dinamis yang terus bertambah, dibutuhkan enkapsulasi yang dapat dikomposisikan
Saya sangat suka nama
setHTMLUnsafeFitur keamanan akan gagal jika strukturnya menuntut pengembang untuk opt-in
Sebaliknya, membuat “jalur berbahaya terasa berbahaya” jauh lebih efektif
Nama
set_html()jauh lebih intuitif dibandinginner_htmlAPI JavaScript benar-benar berantakan dan suatu hari perlu dirapikan
Diskusi kali ini memang berpusat pada keamanan, tetapi ketika merilis API baru, desainnya sendiri juga harus rapi
DOM API sejak dulu, dan bahkan sekarang, memberi kesan seperti “dibuat oleh orang-orang yang belum pernah mendesain API”
Developer tahun 90-an:
Developer tahun 2020-an:
Kita tidak belajar apa pun dari tahun 90-an