Memastikan CSP efektif melawan serangan XSS

Kebijakan Keamanan Konten (CSP) membantu memastikan konten apa pun yang dimuat di halaman dipercaya oleh pemilik situs. CSP memitigasi serangan pembuatan skrip lintas situs (XSS) karena dapat memblokir skrip tidak aman yang dimasukkan oleh penyerang. Namun, CSP dapat dengan mudah diabaikan jika tidak cukup ketat. Lihat Memitigasi pembuatan skrip lintas situs (XSS) dengan Kebijakan Keamanan Konten (CSP) yang ketat untuk informasi selengkapnya. Lighthouse mengumpulkan CSP yang diterapkan pada dokumen utama, dan melaporkan masalah dari CSP Evaluator jika dapat diabaikan.

Laporan Lighthouse memperingatkan bahwa tidak ada CSP yang ditemukan dalam mode penerapan.
Laporan Lighthouse memperingatkan bahwa tidak ada CSP yang ditemukan dalam mode penerapan.

Praktik yang diperlukan untuk CSP yang tidak dapat dilewati

Terapkan praktik berikut untuk memastikan CSP Anda tidak dapat diabaikan. Jika CSP dapat diabaikan, Lighthouse akan mengeluarkan peringatan tingkat keseriusan tinggi.

CSP menargetkan XSS

Untuk menargetkan XSS, CSP harus menyertakan perintah script-src, object-src, dan base-uri. CSP juga harus bebas dari error sintaksis.

script-src dan object-src masing-masing mengamankan halaman dari skrip yang tidak aman dan plugin yang tidak aman. Atau, default-src dapat digunakan untuk mengonfigurasi kebijakan yang luas sebagai pengganti banyak perintah termasuk script-src dan object-src.

base-uri mencegah injeksi tag <base> tidak sah yang dapat digunakan untuk mengalihkan semua URL relatif (seperti skrip) ke domain yang dikontrol penyerang.

CSP menggunakan nonce atau hash untuk menghindari pengabaian daftar yang diizinkan

CSP yang mengonfigurasi daftar yang diizinkan untuk script-src bergantung pada asumsi bahwa semua respons yang berasal dari domain tepercaya aman, dan dapat dijalankan sebagai skrip. Namun, asumsi ini tidak berlaku untuk aplikasi modern; beberapa pola umum dan tidak berbahaya seperti mengekspos antarmuka JSONP dan menghosting salinan library AngularJS memungkinkan penyerang dapat keluar dari batasan CSP.

Dalam praktiknya, meskipun mungkin tidak terlalu jelas bagi penulis aplikasi, sebagian besar daftar yang diizinkan script-src dapat dikelabui oleh penyerang dengan bug XSS, dan memberikan sedikit perlindungan terhadap injeksi skrip. Sebaliknya, pendekatan berbasis nonce dan berbasis hash tidak mengalami masalah ini dan mempermudah penerapan dan pemeliharaan kebijakan yang lebih aman.

Misalnya, kode ini menggunakan endpoint JSONP yang dihosting di domain tepercaya untuk memasukkan skrip yang dikontrol penyerang:

CSP:

script-src https://trusted.example.com

HTML:

<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>

Agar tidak diabaikan, CSP harus mengizinkan skrip satu per satu menggunakan nonce atau hash dan menggunakan 'strict-dynamic', bukan daftar yang diizinkan.

Rekomendasi tambahan untuk CSP yang aman

Terapkan praktik berikut untuk keamanan dan kompatibilitas tambahan. Jika CSP tidak mengikuti salah satu rekomendasi, Lighthouse akan mengeluarkan peringatan tingkat keseriusan sedang.

Mengonfigurasi pelaporan CSP

Mengonfigurasi tujuan pelaporan akan membantu memantau kerusakan. Anda dapat menetapkan tujuan pelaporan menggunakan perintah report-uri atau report-to. report-to saat ini tidak didukung oleh semua browser modern, jadi sebaiknya gunakan keduanya atau hanya report-uri.

Jika ada konten yang melanggar CSP, browser akan mengirim laporan ke tujuan yang dikonfigurasi. Pastikan Anda memiliki aplikasi yang dikonfigurasi di tujuan ini yang menangani laporan ini.

Menentukan CSP di header HTTP

CSP dapat ditentukan dalam tag meta seperti ini:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'">

Namun, Anda harus menentukan CSP di header respons HTTP jika bisa. Injeksi sebelum tag meta akan mengabaikan CSP. Selain itu, frame-ancestors, sandbox, dan pelaporan tidak didukung dalam CSP tag meta.

Memastikan CSP kompatibel dengan versi lama

Tidak semua browser mendukung nonce/hash CSP, jadi sebaiknya tambahkan unsafe-inline sebagai pengganti untuk browser yang tidak mematuhi kebijakan. Jika browser mendukung nonce/hash, unsafe-inline akan diabaikan.

Demikian pula, strict-dynamic tidak didukung oleh semua browser. Sebaiknya tetapkan daftar yang diizinkan sebagai penggantian untuk browser yang tidak mematuhi kebijakan. Daftar yang diizinkan akan diabaikan di browser yang mendukung strict-dynamic.

Cara mengembangkan CSP yang ketat

Berikut adalah contoh penggunaan CSP ketat dengan kebijakan berbasis nonce.

CSP:

script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;

HTML:

<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>

random123 adalah string base64 yang dihasilkan sisi server setiap kali halaman dimuat. unsafe-inline dan https: diabaikan di browser modern karena nonce dan strict-dynamic. Untuk informasi selengkapnya tentang mengadopsi CSP ketat, lihat panduan CSP Ketat.

Anda dapat memeriksa CSP untuk mengetahui potensi pengabaian menggunakan Lighthouse dan CSP Evaluator. Jika Anda ingin menguji CSP baru tanpa risiko merusak halaman yang ada, tentukan CSP dalam mode hanya laporan menggunakan Content-Security-Policy-Report-Only sebagai nama header. Tindakan ini akan mengirimkan pelanggaran CSP ke tujuan pelaporan apa pun yang telah Anda konfigurasi dengan report-to dan report-uri, tetapi tidak benar-benar menerapkan CSP.