Cara Marketer Indonesia Pasang Trusted Types API di Next.js untuk Cegah DOM XSS 2026
TL;DR: Trusted Types API memaksa semua sink DOM berbahaya seperti innerHTML hanya menerima objek tipe terpercaya, menutup celah DOM XSS yang luput dari Content Security Policy biasa. Di Next.js 15, aktifkan via header CSP
require-trusted-types-for 'script'di middleware, daftarkan policy sanitasi, dan rilis bertahap di report-only mode dulu.
Dalam audit keamanan beberapa proyek SaaS yang Vito Atmo tangani sepanjang 2025 hingga 2026, satu pola muncul berulang. CSP sudah aktif, semua script eksternal sudah whitelist, tapi DOM-based XSS tetap lolos lewat React component yang pakai dangerouslySetInnerHTML dengan data dari API tidak tepercaya. Auditor Acunetix dan Burp Suite menemukan 4 sampai 12 finding di tiap aplikasi.
Trusted Types API adalah jawaban resmi browser untuk masalah ini. API ini memaksa semua sink berbahaya menolak string mentah, dan hanya menerima objek yang sudah lewat policy sanitasi terdaftar. Hasilnya: walaupun developer lupa sanitasi, browser yang menolak.
Apa yang Hilang dari CSP Biasa
Content Security Policy standar bagus untuk memblokir script eksternal yang tidak whitelist, tapi tidak menyentuh sink DOM internal. Saat React mengeksekusi dangerouslySetInnerHTML={{__html: payload}} dengan payload dari user-generated content, CSP biasa tidak bisa mencegah.
Praktik standar di industri keamanan menunjukkan DOM XSS mengisi 35 sampai 50 persen total finding XSS di SPA modern. Angka ini bervariasi tergantung kompleksitas aplikasi.
Framework Penerapan di Next.js
| Tahap | Aksi | Durasi |
|---|---|---|
| 1 | Aktifkan Content-Security-Policy-Report-Only dengan require-trusted-types-for 'script' | Hari 1 |
| 2 | Daftarkan policy sanitasi di app/layout.tsx lewat script tag | Hari 1-3 |
| 3 | Kumpulkan report violation via Reporting API selama 14 hari | Hari 4-17 |
| 4 | Perbaiki tiap sink yang melanggar, bungkus pakai policy | Hari 18-21 |
| 5 | Pindah ke enforcing mode (Content-Security-Policy, bukan report-only) | Hari 22 |
Aturan: jangan langsung enforcing. Aplikasi akan crash di production karena library pihak ketiga (Google Tag Manager, Hotjar, chat widget) sering pakai sink terlarang.
Studi Kasus: LMS Atmo
Saat Vito Atmo memasang Trusted Types di LMS Atmo pada Q1 2026, prosesnya berjalan tiga minggu. Hari pertama aktif report-only mode, hari ke-14 jumlah violation report turun dari 847 menjadi 6 setelah patch tiap sink. Library yang paling sering melanggar adalah Quill rich text editor (8 sink) dan widget komentar Disqus (3 sink). Solusinya: bungkus output Quill dengan DOMPurify lewat policy bernama quill-policy, dan untuk Disqus pakai default policy yang memanggil sanitasi internal.
Setelah enforcing aktif penuh di hari ke-22, audit ulang Acunetix menunjukkan finding DOM XSS turun dari 11 ke 0. Tidak ada keluhan pengguna karena policy sanitasi sudah handle semua case sebelum dipasang strict.
Studi kasus serupa di Vetmo menunjukkan pola yang sama, walaupun di sana sink dari payment iframe perlu dipasangkan dengan Storage Access API untuk akses cookie first-party.
Implementasi Praktis di Next.js 15
Di file middleware.ts, tambahkan header CSP:
response.headers.set(
'Content-Security-Policy-Report-Only',
"require-trusted-types-for 'script'; trusted-types default react-renderer; report-uri /api/csp-report"
);
Lalu daftarkan policy di app/layout.tsx sebelum komponen render:
<Script id="trusted-types-policy" strategy="beforeInteractive">
{`if (window.trustedTypes && trustedTypes.createPolicy) {
trustedTypes.createPolicy('default', {
createHTML: (s) => DOMPurify.sanitize(s)
});
}`}
</Script>
Untuk Next.js, library next/script strategy beforeInteractive memastikan policy aktif sebelum React mount. Detail lengkap di web.dev Trusted Types guide.
Pertanyaan Umum
Apakah Trusted Types bikin bundle JS lebih besar?
Tidak signifikan. DOMPurify yang biasa dipasang berbarengan menambah sekitar 18 KB gzipped. Untuk benefit keamanan, ini investasi kecil.
Bagaimana kalau library third-party tidak compatible?
Pakai default policy yang menerima string mentah tapi melalui sanitasi DOMPurify. Aktifkan reportOnly dulu, identifikasi library yang violation paling banyak, lalu negosiasi dengan vendor atau cari pengganti.
Apakah Safari dan Firefox sudah mendukung?
Per April 2026, Chrome dan Edge mendukung penuh enforcing, Firefox dan Safari masih partial (no enforcing). Aplikasi tetap aman karena fallback CSP biasa tetap aktif untuk browser non-Chromium.
Apakah kompatibel dengan React Server Components?
Ya. RSC merender HTML di server, hasil hydrasi di client tetap kena Trusted Types karena React DOM menggunakan policy react-renderer yang sudah builtin sejak React 19.
Penutup
Trusted Types bukan pengganti review kode dan sanitasi manual. Tapi sebagai jaring pengaman terakhir, ini menutup kelas serangan paling mahal untuk di-debug. Pasang di staging dulu, monitor violation report, lalu enforce di production setelah 14 hari bersih.
Artikel Terkait
Website Bisnis
Cara Marketer Indonesia Pasang Passkeys di Next.js untuk Login Tanpa Password dan Naikkan Repeat Login 4x di 2026
Panduan implementasi passkeys di Next.js App Router pakai library SimpleWebAuthn. Turunkan friksi login, naikkan repeat purchase, hapus tiket "lupa password".
Website Bisnis
Cara Marketer Indonesia Pasang Performance Max Feed-Only untuk Toko E-Commerce 2026
Performance Max mode Feed-Only memberi kontrol shopping-style tanpa risiko placement display. Panduan setup lengkap untuk e-commerce Indonesia 2026.
Website Bisnis
Cara Marketer Indonesia Pasang CSS Scroll Snap di Next.js untuk Storytelling Landing Page Tanpa JavaScript Berat 2026
CSS scroll snap di Next.js memberi pengalaman storytelling kelas Apple tanpa beban JavaScript carousel. Panduan implementasi dengan Tailwind, kombinasi scroll-driven animation, dan dampaknya ke Core Web Vitals.
Butuh website yang benar-benar bekerja?
Hubungi Vito untuk konsultasi gratis 15 menit.
WhatsApp Sekarang