Pengenalan dan Penerapan Content Security Policy pada Website

Muhammad Ridwan Na'im
8 min readOct 24, 2022

Oleh: Muhammad Ridwan Na’im — Prodi Teknik Informatika UNPAM

Pengenalan Content Security Policy

Content Security Policy (CSP) atau dalam Bahasa Indonesia dikenal dengan Kebijakan Keamanan Konten, adalah lapisan keamanan tambahan yang membantu mendeteksi dan mengurangi jenis serangan tertentu, seperti Cross Site Scripting (XSS), serangan injeksi data, pencurian data, perusakan situs, hingga distribusi malware.

Content Security Policy (CSP) dapat diaktifkan dengan melakukan konfigurasi pada webserver seperti Apache, Nginx dan semisalnya. Selain itu, kita juga bisa mengaktifkan CSP melalui tag HTML atau pada bahasa pemrograman backend yang digunakan, seperti PHP dan sejenisnya.

Adapun ilustrasi dari penerapan CSP dan pengaruhnya terhadap client dapat dilihat pada gambar berikut (Gambar 1). Pada gambar tersebut disimulasikan client mengakses website http://example.com yang memiliki asetfile.js’ berupa javascript dan ‘file.css’. yang berupa CSS. Lalu peretas menyisipkan skrip jahat berupa javascript dari website http://malicious.com bernama xss.js. Sementara webserver menerapkan CSP default-src http://www.example.com.

Maka yang akan ditampilkan pada client dan dieksekusi oleh browser hanyalah file.js dan file.css karena kedua file tersebut berasal dari server yang sama. Sedangkan file xss.js yang disisipkan oleh peretas akan diblokir oleh browser yang membaca respon dari HTTP Header Content Security Policy karena bersumber dari website yang berbeda.

Cara kerja Content Security Policy
Gambar 1 — Bagaimana CSP Bekerja
Gambar 2 — Hasil Penerapan Konfigurasi CSP

Sebelum menerapkan Content Security Policy pada website, ada beberapa istilah dan beberapa kondisi pada website atau aplikasi yang harus dipahami. Teknologi yang digunakan pada website atau aplikasi akan mempengaruhi konfigurasi dari CSP itu sendiri. Demikian juga sebaliknya. Adapun istilah-istilah yang harus dipahami kegunaannya pada konfigurasi CSP bisa dilihat pada tabel berikut.

Tabel istilah dalam CSP

Directives pada CSP berfungsi sebagai penentu kebijakan yang akan diterapkan. Sebagai contoh, jika ingin menerapkan directive script-src, artinya kita akan menentukan dari mana saja sumber script yang akan diizinkan untuk dieksekusi. Perlu diperhatikan bahwa directive default-src wajib ada dalam konfigurasi CSP untuk menyesuaikan dengan kompatibilitas browser karena masih ada beberapa browser yang mungkin belum mendukung directive tersebut. Misal, jika browser tidak mendukung directive object-src, maka kebijakan sumber konten akan ditentukan oleh directive default-src. Jika object-src tidak dideklarasikan pada CSP, maka konten yang terkait dengan object seperti tag HTML dan sejenisnya, kebijakannya akan dikembalikan pada default-src. Namun perlu digarisbawahi bahwa tidak semua directive akan dikembalikan kepada default-src. Selanjutnya, directive pada CSP harus diikuti dengan source list karena di sinilah ditentukan sumber-sumber konten yang akan diizinkan.

Macam-macam Directive pada CSP dan Penjelasannya

Referensi Source List

Semua arahan yang diakhiri dengan -src mendukung nilai serupa yang dikenal sebagai source list. Beberapa nilai source list dapat dipisahkan spasi dengan pengecualian ‘none’ yang seharusnya menjadi satu-satunya value.

Penerapan Content Security Policy

Contoh konfigurasi CSP pada Nginx:

add_header Content-Security-Policy "default-src 'self' https://cdn.bootstrap.com; script-src 'self' https://cdn.bootstrap.com; style-src 'self'
https://cdn.bootstrap.com; img-src 'self';";

Contoh konfigurasi CSP pada Apache:

Header set Content-Security-Policy "default-src 'self' https://cdn.bootstrap.com; script-src 'self' https://cdn.bootstrap.com; style-src 'self'
https://cdn.bootstrap.com; img-src 'self';";

Contoh konfigurasi CSP dengan <meta> tag HTML:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://cdn.bootstrap.com; script-src 'self' https://cdn.bootstrap.com; style-src 'self' https://cdn.bootstrap.com; img-src 'self';">

Contoh konfigurasi CSP pada pemrograman PHP:

<?php
header("Content-Security-Policy: default-src 'self' https://cdn.bootstrap.com; script-src 'self' https://cdn.bootstrap.com; style-src 'self' https://cdn.bootstrap.com; img-src 'self';");
?>

Konfigurasi di atas akan menghasilkan kebijakan konten sebagai berikut:

  • default-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa gambar, font style, CSS, koneksi, media, objek hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com.
  • script-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa javascript hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.
  • style-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa CSS hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.
  • img-src ‘self’ artinya konten dan resource yang ditampilkan berupa gambar hanya yang berasal dari website itu sendiri. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.

Penerapan Source dengan Skema (Scheme)

add_header Content-Security-Policy "default-src 'self' https://cdn.bootstrap.com; script-src 'self' https://cdn.bootstrap.com; style-src 'self' https://cdn.bootstrap.com; img-src 'self' data:; object-src 'self' blob:;";

Konfigurasi di atas akan menghasilkan kebijakan konten sebagai berikut:

  • default-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa gambar, font style, CSS, koneksi, media, objek hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com.
  • script-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa javascript hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.
  • style-src ‘self’ https://cdn.bootstrap.com; artinya konten dan resource yang ditampilkan berupa CSS hanya yang berasal dari website itu sendiri dan https://cdn.bootstrap.com. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.
  • img-src ‘self’ data: artinya konten dan resource yang ditampilkan berupa gambar hanya yang berasal dari website itu sendiri dan mengizinkan memuat gambar yang di-encoding dengan base64() seperti format data:image/webp;base64,/b4s364ImAgeEnc0dinG==. Jika directive ini tidak dideklarasikan, maka kebijakan akan dikembalikan pada directive default-src.
  • object-src ‘self’ blob: artinya konten dan resource yang ditampilkan berupa objek baik itu yang dimuat dengan tag frame, object, atau applet harus bersumber dari website itu sendiri dan mengizinkan tipe data object dengan bentuk blob. Seperti blob:https://website.com/123-45jhjfg-123btnbg1-345345.

Penerapan Hash dan Nonce

Jika ada penerapan inline script atau inline style pada website, ‘unsafe-inline’ pada directive script-src atau style-src harus diterapkan. Namun, cara demikian menyebabkan kemanan website kita akan lebih rentan terhadap serangan. Sebagai alternatifnya, CSP menyediakan fitur nonce atau hash. Nonce adalah karakter acak sekali pakai berbentuk base64 yang digunakan pada tag script atau style. Nonce tersebut nantinya didaftarkan pada rule CSP. Sedangkan hash adalah hasil hashing dari inline script tanpa menyertakan tag script atau style.

Gambar 3 — Penerapan Inline Script yang ditolak oleh browser karena Konfigurasi CSP

Ketika ‘unsafe-inline’ tidak diterapkan pada CSP sedangkan website menggunakan inline style atau inline script, maka pada console browser akan tampil error seperti di atas. Pada console akan ditampilan nilai hash dari script yang diblokir atau saran menggunakan nonce.

Misal, sebuah website menerapkan inline script sebagai berikut.

// Without nonce
<script>
alert('Hello World');
</script>

Solusinya menambahkan atribut nonce pada tag script.

<script nonce="s0m3sTrin9rAndomEx4mplE=">
alert('Hello World');
</script>

Kemudian menambahkan nonce value tersebut pada rule CSP.

Content-Security-Policy: "default-src 'self'; script-src 'self' 
'nonce-s0m3sTrin9rAndomEx4mplE=';

Cara kedua adalah membuat hash dari script di atas. Dalam modul ini saya menggunakan fitur script and style hasher pada website https://report-uri.com/. Salin script (tanpa menyertakan tag script) lalu paste pada form yang telah disediakan kemudian klik tombol hash.

Gambar 4 — Script and Style Hasher

Nilai hash akan muncul dan sertakan nilai hash tersebut pada rule CSP yang akan dibuat.

Content-Security-Policy: "default-src 'self'; script-src 'self' 'sha256-DUTqIDSUj1HagrQbSjhJtiykfXxVQ74BanobipgodCo=';

Untuk menjalankan script pada event hanlders seperti script pada atribut onclick, selain menambahkan nilai hash-nya, kita harus menambahkan ‘unsafe-hashes’ pada rule CSP. Contohnya sebagai berikut:

<button type="button" onclick="jsFunction()">

CSP rule-nya adalah sebagai berikut:

Content-Security-Policy: "default-src 'self'; script-src 'self' 'unsafe-hashes' 'sha256-DUTqIDSUj1HagrQbSjhJtiykfXxVQ74BanobipgodCo=;

Perlu diperhatikan ketika akan memilih untuk menggunakan nonce, nonce yang diterapkan haruslah bersifat dinamis, bukan statis. Nonce harus berubah setiap halaman dimuat ulang karena jika nonce tidak berubah-ubah, peretas dapat melakukan bypass terhadap rule CSP yang dibuat. Adapun syarat-syarat lainnya sebagai berikut:

  1. Nonce harus unik untuk setiap HTTP Response
  2. Nonce harus dibuat menggunakan generator acak yang aman secara kriptografis
  3. Nonce harus memiliki panjang yang cukup, bertujuan untuk setidaknya 128 bit entropi (32 karakter hex atau sekitar 24 karakter base64).
  4. Tag script yang memiliki atribut nonce tidak boleh memiliki variabel tidak tepercaya/tidak lolos di dalamnya. Artinya harus terdaftar di rule CSP.

Untuk lebih lengkapnya tentang penerapan dynamic nonce bisa dilihat pada link berikut.

  1. Generate a nonce with Apache 2.4 (for a Content Security Policy header) — Stack Overflow
  2. CSP Nonce support in Nginx

Penerapan directive report-uri dan Konfigurasi URI Reporting pada Website report-uri.com

Pada CSP terdapat fitur reprot-uri dan report-to yang berfungsi untuk melaporkan pelanggaran terhadap CSP. Directive report-uri akan diikuti oleh URL di mana laporan akan dikirim oleh server jika terjadi pelanggaran. Sedangkan report-to diikuti nama grup URL pelaporan yang telah didefinisikan sebelumnya pada HTTP Header Report-To.

Penggunaan report-uri pada CSP:

Content-Security-Policy: "default-src 'self'; script-src 'self' 'unsafe-hashes' 'sha256-DUTqIDSUj1HagrQbSjhJtiykfXxVQ74BanobipgodCo='; report-uri https://report.location.tld;

Penggunaan report-to pada CSP:

Report-To: {"group":"default","max_age":10886400,"endpoints":[{"url":"https://report.location.tld"}],"include_subdomains":true}

Untuk mendapatkan URI Reporting, kita bisa mendaftar secara gratis pada website Report URI: Register. Setelah itu, kita akan mendapatkan link verifikasi pada email kita. Klik link yang dikirimkan untuk menyelesaikan proses registrasi.

Gambar 5— Halaman Registrasi Report URI

Setelah proses registrasi selesai, silakan login pada halaman berikut: Report URI: Login.

Gambar 6— Tampilan Halaman Login Report URI
Gambar 7— Tampilan Dashboard Report URI

Klik icon CUSTOMISE pada Dashboard kemudian website akan mengarahkan ke halaman setup. Pada halaman ini dapat dilakukan kustomisasi URI Reporting dan mendapatkan Reporting API yang dibutuhkan.

Gambar 8— Halaman Setup Report URI

Analisa Security Header dan CSP Scanner

Hasil konfigurasi HTTP Header dan CSP bisa dianalisa dengan website https://securityheaders.com atau dengan extension CSP Scanner pada browser Chrome dan Edge.

Gambar 9— Hasil Analisa HTTP Header terhadap Website https://govcsirt.tangerangkota.go.id
Gambar 10 — Hasil Analisa CSP Header terhadap Website https://govcsirt.tangerangkota.go.id
Gambar 11 — Peringatan Kelemahan Konfigurasi yang Mungkin Bisa diperbaiki pada Website https://govcsirt.tangerangkota.go.id
Gambar 12 — Hasil Analisa CSP Header terhadap Website https://govcsirt.tangerangkota.go.id Menggunakan Extension CSPScanner pada Browser Edge.
Gambar 13 — Warning pada Konfigurasi CSP dari Website https://govcsirt.tangerangkota.go.id yang mungkin bisa diperbaiki.

Referensi
https://content-security-policy.com/
https://scotthelme.co.uk/csp-cheat-sheet/
https://scotthelme.co.uk/content-security-policy-an-introduction/
https://docs.report-uri.com/setup/wizard/

--

--