Content Security Policy dan CMP Anda: Membuat CSP dan Persetujuan Bekerja Bersama
Dua Lapisan Keamanan yang Harus Sepakat
Content Security Policy (CSP) memberi tahu browser dari sumber mana saja sebuah halaman boleh memuat skrip, gaya, gambar, frame, dan permintaan jaringan. Platform manajemen persetujuan melakukan pekerjaan sebaliknya: ia memutuskan skrip mana yang boleh berjalan berdasarkan pilihan pengguna. Bila keduanya dikonfigurasi secara terpisah, keduanya bertabrakan. CMP gagal dimuat karena diblokir CSP, atau CSP dilonggarkan begitu jauh demi CMP dan tag iklan sehingga tidak melindungi apa pun lagi.
Panduan ini menjelaskan direktif CSP mana yang biasanya dibutuhkan CMP, bagaimana nonce berinteraksi dengan injeksi skrip, dan bagaimana meluncurkan perubahan tanpa merusak banner Anda.
Yang Biasanya Dibutuhkan CMP dari CSP
Persyaratan pastinya bergantung pada vendor, jadi selalu mulai dari dokumentasi CMP Anda sendiri. Secara umum, periksa direktif berikut:
script-src— domain tempat skrip CMP dimuat, ditambah file skrip tambahan yang dimuatnya.connect-src— endpoint yang dipanggil CMP denganfetchatau XHR, seperti endpoint konfigurasi, daftar vendor, geolokasi, dan pencatatan persetujuan.style-src— domain stylesheet, dan mungkin gaya inline jika CMP menyisipkan elemen<style>atau menetapkan atribut style.img-src— logo, ikon, dan piksel bebas pelacakan yang dipakai CMP.font-src— jika banner memuat fontnya sendiri.frame-src— jika CMP memakai iframe, misalnya untuk berbagi persetujuan lintas domain.
Pada situs TCF, ingat bahwa CMP juga membuat frame locator bernama __tcfapiLocator di halaman. Frame itu dibuat tanpa sumber jarak jauh, sehingga biasanya tidak memerlukan entri frame-src, tetapi tetap perlu dipastikan saat pengujian.
Masalah Stub Inline
Sebagian besar CMP meminta Anda menempatkan skrip inline kecil — stub — di head halaman, agar skrip lain dapat mengantrekan panggilan sebelum CMP utama dimuat. CSP yang ketat memblokir skrip inline kecuali Anda mengizinkannya secara eksplisit. Anda punya tiga pilihan:
- Nonce. Hasilkan nilai acak per respons, tambahkan ke header CSP sebagai
'nonce-...'dan ke tag<script>milik stub. Ini opsi paling fleksibel untuk halaman dinamis. - Hash. Tambahkan hash SHA-256 dari isi persis stub ke
script-src. Ini bekerja baik untuk situs statis, tetapi perubahan apa pun pada stub, bahkan spasi, akan merusaknya. - Menghosting stub sendiri sebagai file eksternal di domain Anda, yang tercakup oleh
'self'. Ini memerlukan kehati-hatian agar tetap dimuat cukup awal.
Hindari 'unsafe-inline' sebagai jalan pintas. Direktif itu mengizinkan setiap skrip inline, yang menghilangkan sebagian besar perlindungan yang diberikan CSP.
Nonce dan Skrip yang Disisipkan CMP
CMP yang memblokir skrip hingga ada persetujuan sering bekerja dengan menahannya lalu menyisipkannya kemudian. Di bawah CSP berbasis nonce, skrip yang disisipkan itu juga perlu diizinkan. Ada dua pendekatan umum:
- Propagasi nonce. CMP membaca nonce dari tag skripnya sendiri dan menambahkannya ke setiap skrip yang disisipkan. Periksa apakah CMP Anda mendukung ini.
'strict-dynamic'. Kata kunci ini memberi tahu browser yang mendukungnya untuk memercayai skrip yang dimuat oleh skrip yang sudah dipercaya. Ini menyederhanakan penggunaan tag manager dan CMP yang menyisipkan skrip, tetapi juga berarti skrip apa pun yang Anda percaya dapat memuat skrip lain, jadi percayalah dengan hati-hati.
Tag manager menimbulkan pertanyaan yang sama. Jika Anda memuat tag iklan dan analitik melalui tag manager, ikuti dokumentasinya tentang nonce dan pastikan CMP dan tag manager memakai pendekatan yang konsisten.
Tag Iklan Mempersulit CSP
Periklanan terprogram memuat skrip dan frame dari banyak domain, dan daftarnya berubah seiring berubahnya mitra permintaan. Penerbit biasanya memilih salah satu dari dua hal:
- CSP yang ketat pada halaman tanpa iklan terprogram, dan kebijakan yang lebih luas di tempat iklan berjalan.
- Kebijakan yang berfokus pada direktif yang tetap dapat dikelola, seperti
frame-ancestors,object-src 'none', danbase-uri, sementara sumber skrip tetap lebih luas.
Apa pun pilihannya, CMP harus ada dalam daftar izin eksplisit, bukan hanya tercakup oleh wildcard, sehingga perubahan CSP tidak pernah menonaktifkan banner secara diam-diam.
Luncurkan dengan Mode Report-Only
Gunakan header Content-Security-Policy-Report-Only lebih dulu. Browser melaporkan pelanggaran tanpa memblokir apa pun, sehingga Anda dapat melihat apa yang akan dirusak oleh kebijakan baru.
- Terapkan kebijakan dalam mode report-only dengan endpoint pelaporan.
- Muat halaman di profil browser yang bersih dan jalani seluruh alur persetujuan: kunjungan pertama, terima semua, tolak semua, pilihan kustom, penarikan persetujuan.
- Tinjau laporan pelanggaran dan konsol browser untuk sumber daya CMP yang diblokir.
- Sesuaikan kebijakan, lalu beralih ke penegakan.
- Biarkan pelaporan tetap aktif setelah penegakan untuk menangkap regresi.
Gejala Konflik CSP
- Banner tidak pernah muncul, dan konsol menunjukkan pelanggaran CSP untuk skrip CMP.
- Banner muncul tetapi tanpa gaya, karena
style-srcmemblokir CSS-nya. - Pilihan tidak tersimpan, karena
connect-srcmemblokir panggilan pencatatan persetujuan. - Iklan atau analitik tidak pernah dimuat setelah persetujuan, karena skrip yang disisipkan tidak memiliki nonce.
__tcfapitidak terdefinisi, karena stub inline diblokir.
Poin Penting
- Periksa
script-src,connect-src,style-src,img-src, danframe-srcuntuk CMP Anda. - Izinkan stub inline dengan nonce atau hash, bukan
'unsafe-inline'. - Pastikan skrip yang disisipkan setelah persetujuan menerima nonce atau tercakup oleh
'strict-dynamic'. - Uji setiap jalur persetujuan dalam mode report-only sebelum menegakkan.
- Pertahankan CMP dalam daftar izin eksplisit agar perubahan CSP tidak dapat menonaktifkannya.