Model keamanan web berakar pada
kebijakan origin yang sama. Kode
dari https://mybank.com
hanya boleh memiliki akses ke data
https://mybank.com
, dan https://evil.example.com
tentu tidak boleh diizinkan untuk mengaksesnya.
Setiap origin tetap terisolasi dari seluruh web, sehingga memberi developer sandbox
yang aman untuk mem-build dan bermain. Secara teori, ini sangat brilian. Dalam prakteknya, penyerang telah menemukan cara cerdas untuk mengacaukan sistem.
Serangan Pembuatan skrip lintas situs (XSS), misalnya, mengabaikan kebijakan asal yang sama dengan mengelabui situs agar mengirimkan kode berbahaya bersama dengan konten yang diinginkan. Hal ini merupakan masalah besar, karena browser memercayai semua kode yang muncul di halaman sebagai bagian yang sah dari asal keamanan halaman tersebut. Tips XSS adalah bagian yang sudah lama, tetapi mewakili metode yang mungkin digunakan penyerang untuk melanggar kepercayaan ini dengan memasukkan kode berbahaya. Jika penyerang berhasil memasukkan kode apa pun, game sudah berakhir: data sesi pengguna telah disusupi dan informasi yang seharusnya dirahasiakan diekspor ke Penjahat Internet. Tentu saja kita ingin mencegahnya jika memungkinkan.
Ringkasan ini menyoroti pertahanan yang dapat secara signifikan mengurangi risiko dan dampak serangan XSS di browser modern: Kebijakan Keamanan Konten (CSP).
TL;DR
- Gunakan daftar yang diizinkan untuk memberi tahu klien apa yang diizinkan dan apa yang tidak.
- Pelajari perintah yang tersedia.
- Pelajari kata kunci yang diambilnya.
- Kode inline dan
eval()
dianggap berbahaya. - Laporkan pelanggaran kebijakan ke server Anda sebelum menerapkannya.
Daftar yang diizinkan sumber
Masalah yang dieksploitasi oleh serangan XSS adalah ketidakmampuan browser untuk membedakan
antara skrip yang merupakan bagian dari aplikasi Anda dan skrip yang telah
dimasukkan secara berbahaya oleh pihak ketiga. Misalnya, tombol Google +1 di
bagian bawah halaman ini memuat dan mengeksekusi kode dari
https://apis.google.com/js/plusone.js
dalam konteks asal halaman ini. Kita
percaya kode tersebut, tetapi kita tidak dapat mengharapkan browser untuk mengetahui sendiri bahwa kode
dari apis.google.com
sangat bagus, sedangkan kode dari apis.evil.example.com
mungkin tidak. Browser dengan senang hati mendownload dan mengeksekusi kode apa pun yang diminta halaman, terlepas dari sumbernya.
Bukannya mempercayai begitu saja semuanya yang ditayangkan oleh server, CSP mendefinisikan header HTTP Content-Security-Policy
, yang memungkinkan Anda membuat daftar sumber konten tepercaya yang diizinkan, dan menginstruksikan browser untuk hanya menjalankan atau merender resource dari sumber tersebut. Meskipun penyerang dapat menemukan celah untuk memasukkan skrip, skrip tersebut tidak akan cocok dengan daftar yang diizinkan, sehingga tidak akan dijalankan.
Karena kita memercayai apis.google.com
untuk mengirimkan kode yang valid, dan kita memercayai diri kita sendiri untuk melakukan hal yang sama, mari kita tentukan kebijakan yang hanya mengizinkan skrip dieksekusi jika berasal dari salah satu dari dua sumber tersebut:
Content-Security-Policy: script-src 'self' https://apis.google.com
Sederhana, bukan? Seperti yang mungkin Anda duga, script-src
adalah perintah yang
mengontrol kumpulan hak istimewa terkait skrip untuk halaman tertentu. Kita telah menentukan
'self'
sebagai salah satu sumber skrip yang valid, dan https://apis.google.com
sebagai
sumber lainnya. Browser dengan patuh mendownload dan mengeksekusi JavaScript dari
apis.google.com
melalui HTTPS, serta dari origin halaman saat ini.

Dengan kebijakan ini ditentukan, browser hanya akan menampilkan error, bukan memuat skrip dari sumber lain. Saat penyerang cerdas berhasil menyisipkan kode ke situs Anda, mereka akan langsung melihat pesan error, bukan kesuksesan yang mereka harapkan.
Kebijakan berlaku untuk berbagai resource
Meskipun resource skrip adalah risiko keamanan yang paling jelas, CSP menyediakan kumpulan
perintah kebijakan yang beragam yang memungkinkan kontrol yang cukup terperinci atas resource
yang diizinkan untuk dimuat halaman. Anda telah melihat script-src
, sehingga konsepnya
harus jelas.
Mari kita bahas dengan cepat perintah resource lainnya. Daftar di bawah ini mewakili status perintah mulai level 2. Spesifikasi level 3 telah dipublikasikan, tetapi sebagian besar tidak diterapkan di browser utama.
base-uri
membatasi URL yang dapat muncul di elemen<base>
halaman.child-src
mencantumkan URL untuk pekerja dan konten frame tersemat. Misalnya:child-src https://youtube.com
akan mengaktifkan penyematan video dari YouTube, tetapi tidak dari sumber lain.connect-src
membatasi origin yang dapat Anda hubungkan (melalui XHR, WebSocket, dan EventSource).font-src
menentukan origin yang dapat menayangkan font web. Font web Google dapat diaktifkan melaluifont-src https://themes.googleusercontent.com
.form-action
mencantumkan endpoint yang valid untuk pengiriman dari tag<form>
.frame-ancestors
menentukan sumber yang dapat menyematkan halaman saat ini. Perintah ini berlaku untuk tag<frame>
,<iframe>
,<embed>
, dan<applet>
. Perintah ini tidak dapat digunakan dalam tag<meta>
dan hanya berlaku untuk resource non-HTML.frame-src
tidak digunakan lagi di level 2, tetapi dipulihkan di level 3. Jika tidak ada,child-src
akan tetap kembali kechild-src
seperti sebelumnya.img-src
menentukan asal tempat gambar dapat dimuat.media-src
membatasi origin yang diizinkan untuk mengirimkan video dan audio.object-src
memungkinkan kontrol atas Flash dan plugin lainnya.plugin-types
membatasi jenis plugin yang dapat dipanggil halaman.report-uri
menentukan URL tempat browser akan mengirim laporan saat kebijakan keamanan konten dilanggar. Perintah ini tidak dapat digunakan dalam tag<meta>
.style-src
adalah pasanganscript-src
untuk stylesheet.upgrade-insecure-requests
menginstruksikan agen pengguna untuk menulis ulang skema URL, mengubah HTTP menjadi HTTPS. Perintah ini ditujukan untuk situs dengan banyak URL lama yang perlu ditulis ulang.worker-src
adalah perintah CSP Level 3 yang membatasi URL yang dapat dimuat sebagai pekerja, pekerja bersama, atau pekerja layanan. Mulai Juli 2017, perintah ini memiliki penerapan terbatas.
Secara default, perintah terbuka lebar. Jika Anda tidak menetapkan kebijakan tertentu untuk
perintah, misalnya font-src
, perintah tersebut akan berperilaku secara default seolah-olah
Anda telah menentukan *
sebagai sumber yang valid (misalnya, Anda dapat memuat font dari
mana saja, tanpa batasan).
Anda dapat mengganti perilaku default ini dengan menentukan perintah
default-src
. Perintah ini menentukan setelan default untuk sebagian besar perintah yang tidak Anda tentukan. Umumnya, hal ini berlaku untuk perintah apa pun yang
berakhir dengan -src
. Jika default-src
ditetapkan ke https://example.com
, dan Anda gagal
menentukan perintah font-src
, Anda dapat memuat font dari
https://example.com
, dan tidak di tempat lain. Kita hanya menentukan script-src
dalam
contoh sebelumnya, yang berarti gambar, font, dan sebagainya dapat dimuat dari
asal mana pun.
Perintah berikut tidak menggunakan default-src
sebagai penggantian. Perlu diingat bahwa
gagal menetapkannya sama dengan mengizinkan apa pun.
base-uri
form-action
frame-ancestors
plugin-types
report-uri
sandbox
Anda dapat menggunakan perintah ini sebanyak atau sesedikit yang sesuai untuk
aplikasi tertentu, cukup cantumkan setiap perintah di header HTTP, pisahkan
perintah dengan titik koma. Pastikan Anda mencantumkan semua
resource yang diperlukan dari jenis tertentu dalam satu perintah. Jika Anda menulis
sesuatu seperti script-src https://host1.com; script-src https://host2.com
,
perintah kedua akan diabaikan. Seperti berikut ini, kedua origin akan ditentukan dengan benar sebagai valid:
script-src https://host1.com https://host2.com
Misalnya, jika Anda memiliki aplikasi yang memuat semua resource-nya dari
jaringan penayangan konten (misalnya, https://cdn.example.net
), dan mengetahui bahwa Anda
tidak memerlukan konten atau plugin berbingkai, kebijakan Anda mungkin terlihat
seperti berikut:
Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'
Detail implementasi
Anda akan melihat header X-WebKit-CSP
dan X-Content-Security-Policy
dalam berbagai
tutorial di web. Ke depannya, Anda harus mengabaikan header
dengan awalan ini. Browser modern (kecuali IE) mendukung header Content-Security-Policy
tanpa awalan. Itu adalah header yang harus Anda gunakan.
Terlepas dari header yang Anda gunakan, kebijakan ditentukan berdasarkan halaman: Anda harus mengirim header HTTP bersama dengan setiap respons yang ingin Anda pastikan dilindungi. Hal ini memberikan banyak fleksibilitas, karena Anda dapat menyesuaikan kebijakan untuk halaman tertentu berdasarkan kebutuhan spesifiknya. Mungkin satu kumpulan halaman di situs Anda memiliki tombol +1, sementara yang lain tidak: Anda dapat mengizinkan kode tombol dimuat hanya jika diperlukan.
Daftar sumber dalam setiap perintah bersifat fleksibel. Anda dapat menentukan sumber berdasarkan
skema (data:
, https:
), atau berkisar dalam kekhususan dari khusus nama host
(example.com
, yang cocok dengan origin apa pun di host tersebut: skema apa pun, port apa pun) ke
URI yang sepenuhnya memenuhi syarat (https://example.com:443
, yang hanya cocok dengan HTTPS, hanya
example.com
, dan hanya port 443). Karakter pengganti diterima, tetapi hanya sebagai skema,
port, atau di posisi paling kiri nama host: *://*.example.com:*
akan
cocok dengan semua subdomain example.com
(tetapi bukan example.com
itu sendiri), menggunakan
skema apa pun, di port apa pun.
Daftar sumber juga menerima empat kata kunci:
'none'
, seperti yang Anda harapkan, tidak cocok dengan apa pun.'self'
cocok dengan origin saat ini, tetapi tidak dengan subdomainnya.'unsafe-inline'
memungkinkan JavaScript dan CSS inline. (Kita akan membahasnya lebih detail nanti.)'unsafe-eval'
memungkinkan mekanisme text-to-JavaScript sepertieval
. (Kita juga akan membahasnya.)
Kata kunci ini memerlukan tanda petik tunggal. Misalnya, script-src 'self'
(dengan tanda kutip)
memberi otorisasi eksekusi JavaScript dari host saat ini; script-src self
(tanpa tanda kutip) mengizinkan JavaScript dari server bernama "self
" (dan bukan dari
host saat ini), yang mungkin bukan yang Anda maksud.
Sandboxing
Ada satu lagi perintah yang perlu dibahas: sandbox
. Ini sedikit
berbeda dengan yang telah kita lihat, karena membatasi tindakan yang
dapat dilakukan halaman, bukan pada resource yang dapat dimuat halaman. Jika perintah
sandbox
ada, halaman akan diperlakukan seolah-olah dimuat
di dalam <iframe>
dengan atribut sandbox
. Hal ini dapat memiliki berbagai
efek pada halaman: memaksa halaman ke origin unik, dan mencegah pengiriman
formulir, antara lain. Hal ini sedikit di luar cakupan artikel ini, tetapi Anda
dapat menemukan detail lengkap tentang atribut sandboxing yang valid di
bagian "Sandboxing" dalam spesifikasi HTML5.
Tag meta
Mekanisme pengiriman yang disukai CSP adalah header HTTP. Namun, menetapkan kebijakan di halaman langsung dalam markup dapat berguna. Lakukan hal itu menggunakan tag <meta>
dengan
atribut http-equiv
:
<meta
http-equiv="Content-Security-Policy"
content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'"
/>
Ini tidak dapat digunakan untuk frame-ancestors
, report-uri
, atau sandbox
.
Kode inline dianggap berbahaya
Perlu diketahui bahwa CSP didasarkan pada asal daftar yang diizinkan, karena itu adalah
cara yang tidak ambigu untuk menginstruksikan browser agar memperlakukan kumpulan resource tertentu
sebagai dapat diterima dan menolak sisanya. Namun, daftar yang diizinkan berbasis origin tidak
menyelesaikan ancaman terbesar yang ditimbulkan oleh serangan XSS: injeksi skrip inline.
Jika penyerang dapat memasukkan tag skrip yang secara langsung berisi beberapa payload malicious (<script>sendMyDataToEvilDotCom();</script>
), browser tidak memiliki mekanisme untuk membedakannya dari tag skrip inline yang sah. CSP mengatasi masalah ini dengan melarang skrip inline sepenuhnya:
ini adalah satu-satunya cara untuk memastikannya.
Larangan ini tidak hanya mencakup skrip yang disematkan langsung dalam tag script
, tetapi juga
pengendali peristiwa inline dan URL javascript:
. Anda harus memindahkan konten
tag script
ke file eksternal, dan mengganti URL javascript:
dan <a ... onclick="[JAVASCRIPT]">
dengan panggilan addEventListener()
yang sesuai. Misalnya,
Anda dapat menulis ulang kode berikut dari:
<script>
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>
menjadi sesuatu yang lebih seperti:
<!-- amazing.html -->
<script src="amazing.js"></script>
<button id="amazing">Am I amazing?</button>
<div style="clear:both;"></div>
// amazing.js
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('amazing').addEventListener('click', doAmazingThings);
});
Kode yang ditulis ulang memiliki sejumlah keunggulan di atas dan di luar berfungsi dengan baik dengan CSP; ini sudah merupakan praktik terbaik, terlepas dari penggunaan CSP Anda. JavaScript inline menggabungkan struktur dan perilaku dengan cara yang tidak seharusnya. Resource eksternal lebih mudah di-cache oleh browser, lebih mudah dipahami oleh developer, dan kondusif untuk kompilasi dan minifikasi. Anda akan menulis kode yang lebih baik jika melakukan pekerjaan untuk memindahkan kode ke resource eksternal.
Gaya inline diperlakukan dengan cara yang sama: atribut style
dan tag style
harus digabungkan ke dalam stylesheet eksternal untuk melindungi dari
berbagai metode eksfiltrasi data yang sangat cerdik
yang diaktifkan CSS.
Jika harus memiliki skrip dan gaya inline, Anda dapat mengaktifkannya
dengan menambahkan 'unsafe-inline'
sebagai sumber yang diizinkan dalam perintah
script-src
atau style-src
. Anda juga dapat menggunakan nonce atau hash (lihat di bawah), tetapi sebaiknya jangan.
Melarang skrip inline adalah manfaat keamanan terbesar yang diberikan CSP, dan
melarang gaya inline juga akan meningkatkan keamanan aplikasi Anda. Ini adalah sedikit
upaya di awal untuk memastikan semuanya berfungsi dengan benar setelah memindahkan semua kode
ke luar baris, tetapi itu adalah kompromi yang sangat berharga.
Jika Anda benar-benar harus menggunakannya
CSP Level 2 menawarkan kompatibilitas mundur untuk skrip inline dengan memungkinkan Anda menambahkan skrip inline tertentu ke daftar yang diizinkan menggunakan nonce kriptografis (angka yang digunakan sekali) atau hash. Meskipun mungkin merepotkan, hal ini berguna dalam keadaan darurat.
Untuk menggunakan nonce, berikan atribut nonce ke tag skrip Anda. Nilainya harus cocok dengan salah satu dalam daftar sumber tepercaya. Contoh:
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
// Some inline code I can't remove yet, but need to asap.
</script>
Sekarang, tambahkan nonce ke perintah script-src
yang ditambahkan ke kata kunci nonce-
.
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
Ingat bahwa nonce harus dibuat ulang untuk setiap permintaan halaman dan tidak boleh dapat ditebak.
Hash berfungsi dengan cara yang hampir sama. Daripada menambahkan kode ke tag skrip,
buat hash SHA skrip itu sendiri dan tambahkan ke perintah script-src
.
Misalnya, halaman Anda berisi hal berikut:
<script>
alert('Hello, world.');
</script>
Kebijakan Anda akan berisi hal berikut:
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
Ada beberapa hal yang perlu diperhatikan di sini. Awalan sha*-
menentukan algoritma
yang menghasilkan hash. Pada contoh di atas, sha256-
digunakan. CSP juga
mendukung sha384-
dan sha512-
. Saat membuat hash, jangan sertakan tag <script>
. Selain itu, kapitalisasi dan spasi kosong juga penting, termasuk spasi kosong di awal atau di akhir.
Penelusuran Google tentang cara membuat hash SHA akan mengarahkan Anda ke solusi dalam berbagai bahasa. Dengan Chrome 40 atau yang lebih baru, Anda dapat membuka DevTools, lalu memuat ulang halaman. Tab Konsol akan berisi pesan error dengan hash sha256 yang benar untuk setiap skrip inline Anda.
Evaluasi juga
Meskipun penyerang tidak dapat memasukkan skrip secara langsung, mereka mungkin dapat mengelabui
aplikasi Anda untuk mengonversi teks yang tidak aktif menjadi JavaScript yang dapat dieksekusi
dan mengeksekusinya atas nama mereka. eval()
, Function() baru, setTimeout([string], ...)
, dan
setInterval([string], ...)
adalah semua vektor yang melaluinya teks
yang dimasukkan mungkin akan mengeksekusi sesuatu yang tidak terduga dan berbahaya. Respons default
CSP terhadap risiko ini adalah memblokir semua vektor ini sepenuhnya.
Hal ini memiliki lebih dari beberapa dampak pada cara Anda mem-build aplikasi:
- Anda harus mengurai JSON melalui
JSON.parse
bawaan, bukan mengandalkaneval
. Operasi JSON native tersedia di setiap browser sejak IE8, dan operasi tersebut sepenuhnya aman. - Tulis ulang panggilan
setTimeout
atausetInterval
yang saat ini Anda buat dengan fungsi inline, bukan string. Contoh:
setTimeout("document.querySelector('a').style.display = 'none';", 10);
akan lebih baik ditulis sebagai:
setTimeout(function () {
document.querySelector('a').style.display = 'none';
}, 10);
- Hindari pembuatan template inline saat runtime: Banyak library pembuatan template menggunakan
new Function()
secara bebas untuk mempercepat pembuatan template saat runtime. Ini adalah aplikasi program dinamis yang rapi, tetapi berisiko mengevaluasi teks berbahaya. Beberapa framework mendukung CSP secara langsung, kembali ke parser yang andal jika tidak adaeval
. Perintah ng-csp AngularJS adalah contoh yang baik untuk hal ini.
Namun, pilihan yang lebih baik adalah bahasa template yang menawarkan
prakompilasi (misalnya, Handlebars). Prakompilasi template dapat membuat pengalaman pengguna lebih cepat
daripada implementasi runtime tercepat, dan juga lebih aman. Jika eval dan
saudara teks-ke-JavaScript-nya sangat penting untuk aplikasi Anda, Anda dapat
mengaktifkannya dengan menambahkan 'unsafe-eval'
sebagai sumber yang diizinkan dalam perintah
script-src
, tetapi sebaiknya jangan lakukan hal ini. Dengan melarang kemampuan untuk menjalankan string, penyerang akan jauh lebih sulit untuk menjalankan kode tidak sah di situs Anda.
Pelaporan
Kemampuan CSP untuk memblokir resource tidak tepercaya sisi klien adalah keuntungan besar bagi
pengguna Anda, tetapi akan sangat membantu jika ada semacam notifikasi
yang dikirim kembali ke server sehingga Anda dapat mengidentifikasi dan menghapus bug apa pun yang memungkinkan
injeksi berbahaya sejak awal. Untuk tujuan ini, Anda dapat menginstruksikan browser untuk mengirim laporan pelanggaran berformat JSON POST
ke lokasi yang ditentukan dalam perintah report-uri
.
Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
Laporan tersebut akan terlihat seperti berikut:
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer": "http://evil.example.com/",
"blocked-uri": "http://evil.example.com/evil.js",
"violated-directive": "script-src 'self' https://apis.google.com",
"original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
}
}
Halaman ini berisi banyak informasi yang akan membantu Anda melacak
penyebab spesifik pelanggaran, termasuk halaman tempat pelanggaran
terjadi (document-uri
), perujuk halaman tersebut (perhatikan bahwa tidak seperti kolom header
HTTP, kuncinya tidak salah eja), resource yang melanggar
kebijakan halaman (blocked-uri
), perintah spesifik yang dilanggarnya
(violated-directive
), dan kebijakan lengkap halaman (original-policy
).
Hanya Laporan
Jika Anda baru memulai CSP, sebaiknya evaluasi status aplikasi Anda saat ini sebelum meluncurkan kebijakan yang ketat kepada pengguna.
Sebagai batu loncatan untuk deployment yang lengkap, Anda dapat meminta browser untuk memantau
kebijakan, melaporkan pelanggaran, tetapi tidak menerapkan pembatasan. Sebagai ganti
mengirim header Content-Security-Policy
, kirim
header Content-Security-Policy-Report-Only
.
Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
Kebijakan yang ditentukan dalam mode khusus laporan tidak akan memblokir resource yang dibatasi, tetapi akan mengirimkan laporan pelanggaran ke lokasi yang Anda tentukan. Anda bahkan dapat mengirim kedua header, yang menerapkan satu kebijakan sekaligus memantau kebijakan lainnya. Ini adalah cara yang bagus untuk mengevaluasi dampak perubahan pada CSP aplikasi Anda: aktifkan pelaporan untuk kebijakan baru, pantau laporan pelanggaran, dan perbaiki bug yang muncul; jika Anda puas dengan dampaknya, mulai terapkan kebijakan baru.
Penggunaan di Dunia Nyata
CSP 1 cukup dapat digunakan di Chrome, Safari, dan Firefox, tetapi memiliki dukungan yang sangat terbatas di IE 10. Anda dapat melihat detailnya di caniuse.com. CSP Level 2 telah tersedia di Chrome sejak versi 40. Situs besar seperti Twitter dan Facebook telah men-deploy header (studi kasus Twitter patut dibaca), dan standar ini sangat siap untuk Anda mulai deploy di situs Anda sendiri.
Langkah pertama dalam membuat kebijakan untuk aplikasi Anda adalah mengevaluasi resource yang sebenarnya Anda muat. Setelah Anda merasa memahami cara menyusun semuanya di aplikasi, siapkan kebijakan berdasarkan persyaratan tersebut. Mari kita bahas beberapa kasus penggunaan umum dan tentukan cara terbaik untuk mendukung kasus tersebut dalam batasan perlindungan CSP.
Kasus penggunaan #1: widget media sosial
Tombol +1 Google menyertakan skrip dari
https://apis.google.com
, dan menyematkan<iframe>
darihttps://plusone.google.com
. Anda memerlukan kebijakan yang menyertakan kedua origin ini untuk menyematkan tombol. Kebijakan minimum adalahscript-src https://apis.google.com; child-src https://plusone.google.com
. Anda juga perlu memastikan bahwa cuplikan JavaScript yang disediakan Google diambil ke dalam file JavaScript eksternal. Jika Anda memiliki kebijakan berbasis Level 1 yang menggunakanframe-src
, Level 2 mengharuskan Anda mengubahnya menjadichild-src
. Hal ini tidak lagi diperlukan di CSP Level 3.Tombol Suka Facebook memiliki sejumlah opsi penerapan. Sebaiknya gunakan versi
<iframe>
karena sandbox-nya aman dari bagian situs Anda yang lain. Hal ini memerlukan perintahchild-src https://facebook.com
agar berfungsi dengan benar. Perhatikan bahwa, secara default, kode<iframe>
yang disediakan Facebook memuat URL relatif,//facebook.com
. Ubah untuk menentukan HTTPS secara eksplisit:https://facebook.com
. Tidak ada alasan untuk menggunakan HTTP jika Anda tidak perlu melakukannya.Tombol Tweet Twitter mengandalkan akses ke skrip dan frame, yang keduanya dihosting di
https://platform.twitter.com
. (Twitter juga menyediakan URL relatif secara default; edit kode untuk menentukan HTTPS saat menyalin/menempelkannya secara lokal.) Anda akan siap menggunakanscript-src https://platform.twitter.com; child-src https://platform.twitter.com
, selama Anda memindahkan cuplikan JavaScript yang disediakan Twitter ke file JavaScript eksternal.Platform lain memiliki persyaratan serupa, dan dapat ditangani dengan cara yang sama. Sebaiknya tetapkan
default-src
dari'none'
, dan amati konsol Anda untuk menentukan resource yang perlu diaktifkan agar widget berfungsi.
Menyertakan beberapa widget sangat mudah: cukup gabungkan perintah kebijakan, jangan lupa untuk menggabungkan semua resource dari satu jenis ke dalam satu perintah. Jika Anda menginginkan ketiga widget media sosial, kebijakannya akan terlihat seperti ini:
script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com
Kasus penggunaan #2: lockdown
Anggaplah Anda menjalankan situs perbankan dan ingin memastikan bahwa
hanya resource yang Anda tulis sendiri yang dapat dimuat. Dalam skenario ini,
mulai dengan kebijakan default yang memblokir semua hal (default-src 'none'
), lalu buat kebijakan dari sana.
Misalnya, bank memuat semua gambar, gaya, dan skrip dari CDN di
https://cdn.mybank.net
, dan terhubung melalui XHR ke https://api.mybank.com/
untuk
mengambil berbagai bit data. Frame digunakan, tetapi hanya untuk halaman lokal di situs (tidak ada origin pihak ketiga). Tidak ada Flash di situs, tidak ada font, tidak ada
tambahan. Header CSP yang paling ketat yang dapat kami kirim adalah:
Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; child-src 'self'
Kasus penggunaan #3: Khusus SSL
Admin forum diskusi cincin pernikahan ingin memastikan bahwa semua resource hanya dimuat melalui saluran aman, tetapi tidak terlalu banyak menulis kode; menulis ulang sebagian besar software forum pihak ketiga yang penuh dengan skrip dan gaya inline berada di luar kemampuannya. Kebijakan berikut akan berlaku:
Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'
Meskipun https:
ditentukan dalam default-src
, perintah skrip dan gaya tidak otomatis mewarisi sumber tersebut. Setiap perintah sepenuhnya
mengganti default untuk jenis resource tertentu tersebut.
Acara mendatang
Kebijakan Keamanan Konten Level 2 adalah Rekomendasi Calon. Web Application Security Working Group W3C telah mulai mengerjakan iterasi spesifikasi berikutnya, Content Security Policy Level 3.
Jika Anda tertarik dengan diskusi seputar fitur mendatang ini, baca sekilas arsip milis public-webappsec@, atau bergabunglah sendiri.