Kebijakan Keamanan Konten

Joe Medley
Joe Medley

Model keamanan web di-root pada kebijakan origin yang sama. Kode dari https://mybank.com hanya boleh memiliki akses ke data https://mybank.com, dan https://evil.example.com tidak boleh memiliki akses yang diizinkan. Setiap origin akan diisolasi dari bagian web lainnya, sehingga developer memiliki sandbox yang aman untuk membangun dan bermain. Secara teori, ini sangat brilian. Pada kenyataannya, penyerang telah menemukan cara pintar untuk mengalahkan sistem.

Serangan pembuatan skrip lintas situs (XSS), misalnya, mengabaikan kebijakan origin yang sama dengan mengelabui situs agar mengirimkan kode berbahaya bersama dengan konten yang dimaksud. Ini adalah masalah besar, karena browser memercayai semua kode yang muncul di halaman sebagai bagian yang sah dari asal keamanan halaman tersebut. Tips Praktis XSS adalah lintas metode yang sudah lama tetapi representatif dari metode yang dapat digunakan penyerang untuk melanggar kepercayaan ini dengan memasukkan kode berbahaya. Jika penyerang berhasil menyuntikkan kode apa pun, semua masalah pada game sudah berakhir: data sesi pengguna akan disusupi dan informasi yang seharusnya dirahasiakan akan dipindahkan ke The Bad Guys. Tentu saja kami ingin mencegahnya.

Ringkasan ini menyoroti pertahanan yang dapat secara signifikan mengurangi risiko dan dampak serangan XSS di browser modern: Kebijakan Keamanan Konten (CSP).

TL;DR (Ringkasan)

  • Gunakan daftar yang diizinkan untuk memberi tahu klien apa saja yang diizinkan dan tidak diizinkan.
  • Ketahui direktif yang tersedia.
  • Pelajari kata kunci yang mereka gunakan.
  • Kode inline dan eval() dianggap berbahaya.
  • Laporkan pelanggaran kebijakan ke server Anda sebelum memberlakukannya.

Daftar sumber yang diizinkan

Masalah yang dieksploitasi oleh serangan XSS adalah ketidakmampuan browser untuk membedakan antara skrip yang merupakan bagian dari aplikasi Anda dan skrip yang telah dimasukkan dengan berbahaya oleh pihak ketiga. Misalnya, tombol Google +1 di bagian bawah halaman ini memuat dan menjalankan kode dari https://apis.google.com/js/plusone.js dalam konteks asal halaman ini. Kita memercayai kode tersebut, tetapi kita tidak dapat berharap browser mengetahui sendiri bahwa kode dari apis.google.com berfungsi baik, sedangkan kode dari apis.evil.example.com mungkin tidak. Browser dengan senang hati mendownload dan menjalankan kode apa pun yang diminta halaman, apa pun sumbernya.

Alih-alih mempercayai semuanya yang diberikan server, CSP menentukan header HTTP Content-Security-Policy, yang memungkinkan Anda membuat daftar sumber konten tepercaya yang diizinkan, dan menginstruksikan browser untuk hanya mengeksekusi atau merender resource dari sumber tersebut. Meskipun penyerang dapat menemukan lubang untuk memasukkan skrip, skrip tidak akan cocok dengan daftar yang diizinkan, sehingga tidak akan dieksekusi.

Karena kita memercayai apis.google.com untuk memberikan kode yang valid, dan kita memercayai diri sendiri untuk melakukan hal yang sama, mari tentukan kebijakan yang hanya memungkinkan skrip dijalankan saat berasal dari salah satu dari dua sumber tersebut:

Content-Security-Policy: script-src 'self' https://apis.google.com

Sederhana, bukan? Seperti yang mungkin sudah Anda duga, script-src adalah perintah yang mengontrol serangkaian hak istimewa terkait skrip untuk halaman tertentu. Kami telah menentukan 'self' sebagai satu sumber skrip yang valid, dan https://apis.google.com sebagai sumber lainnya. Browser dengan patuh mendownload dan menjalankan JavaScript dari apis.google.com melalui HTTPS, serta dari asal halaman saat ini.

Error konsol: Menolak untuk memuat skrip 'http://evil.example.com/evil.js' karena melanggar perintah Kebijakan Keamanan Konten berikut: skrip-src 'self' https://apis.google.com

Jika kebijakan ini ditentukan, browser hanya akan menampilkan error, bukan memuat skrip dari sumber lain. Jika penyerang yang pintar berhasil memasukkan kode ke dalam situs Anda, mereka akan langsung mendapatkan pesan error, bukan keberhasilan yang diharapkan.

Kebijakan berlaku untuk berbagai resource

Meskipun resource skrip adalah risiko keamanan yang paling jelas, CSP menyediakan serangkaian perintah kebijakan yang memungkinkan kontrol yang cukup terperinci atas resource yang boleh dimuat oleh halaman. Anda sudah melihat script-src, jadi konsepnya harus jelas.

Mari kita telusuri direktif sumber daya lainnya. Daftar di bawah ini mewakili status perintah pada tingkat 2. Spesifikasi level 3 telah dipublikasikan, tetapi sebagian besar tidak diimplementasikan dalam 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 memungkinkan penyematan video dari YouTube, tetapi tidak dari asal lain.
  • connect-src membatasi origin yang dapat Anda hubungkan (melalui XHR, WebSockets, dan EventSource).
  • font-src menentukan origin yang dapat menyediakan font web. Font web Google dapat diaktifkan melalui font-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, nilai tersebut masih akan kembali ke child-src seperti sebelumnya.
  • img-src menentukan origin tempat gambar dapat dimuat.
  • media-src membatasi sumber yang diizinkan untuk mengirim video dan audio.
  • object-src memungkinkan kontrol atas Flash dan plugin lainnya.
  • plugin-types membatasi jenis plugin yang dapat dipanggil oleh halaman.
  • report-uri menentukan URL tempat browser akan mengirim laporan jika kebijakan keamanan konten dilanggar. Perintah ini tidak dapat digunakan di tag <meta>.
  • style-src adalah pasangan script-src untuk stylesheet.
  • upgrade-insecure-requests menginstruksikan agen pengguna untuk menulis ulang skema URL, mengubah HTTP menjadi HTTPS. Perintah ini ditujukan untuk situs web dengan banyak URL lama yang perlu ditulis ulang.
  • worker-src adalah perintah CSP Level 3 yang membatasi URL yang mungkin dimuat sebagai pekerja, pekerja bersama, atau pekerja layanan. Mulai Juli 2017, perintah ini memiliki implementasi terbatas.

Secara {i>default<i}, direktif ini terbuka lebar. Jika Anda tidak menetapkan kebijakan khusus untuk perintah, misalnya font-src, maka 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 Anda biarkan tidak ditentukan. Umumnya, ini berlaku untuk setiap perintah yang diakhiri 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 dari tempat lainnya. 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 tidak menyetelnya sama saja dengan mengizinkan apa pun.

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

Anda dapat menggunakan sebanyak atau sesedikit mungkin perintah ini yang sesuai untuk aplikasi spesifik Anda, cukup mencantumkan setiap perintah di header HTTP dan memisahkan perintah dengan titik koma. Pastikan Anda mencantumkan semua resource yang diperlukan dari jenis tertentu dalam satu perintah tunggal. Jika Anda menulis sesuatu seperti script-src https://host1.com; script-src https://host2.com, perintah kedua akan diabaikan. Sesuatu seperti berikut akan menentukan dengan benar kedua origin sebagai valid:

script-src https://host1.com https://host2.com

Misalnya, jika Anda memiliki aplikasi yang memuat semua resource-nya dari jaringan pengiriman konten (misalnya, https://cdn.example.net), dan tahu bahwa Anda tidak memerlukan konten atau plugin dengan frame, kebijakan Anda mungkin akan 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 berawalan ini. Browser modern (dengan pengecualian IE) mendukung header Content-Security-Policy tanpa awalan. Itulah {i>header<i} yang harus Anda gunakan.

Apa pun header yang digunakan, kebijakan ditetapkan per halaman: Anda harus mengirimkan header HTTP beserta setiap respons yang ingin dipastikan terlindungi. Cara 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 halaman lainnya tidak: Anda dapat mengizinkan kode tombol untuk dimuat hanya jika diperlukan.

Daftar sumber di setiap perintah bersifat fleksibel. Anda dapat menentukan sumber melalui skema (data:, https:), atau mengatur rentang kekhususan dari nama host saja (example.com, yang cocok dengan origin apa pun di host tersebut: skema apa pun, port apa pun) hingga 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 mungkin Anda duga, tidak cocok dengan apa pun.
  • 'self' cocok dengan asal saat ini, tetapi tidak dengan subdomainnya.
  • 'unsafe-inline' mengizinkan JavaScript dan CSS inline. (Kita akan sedikit membahas hal ini lebih detail.)
  • 'unsafe-eval' memungkinkan mekanisme teks ke JavaScript seperti eval. (Kita juga akan membahas ini juga.)

Kata kunci ini memerlukan tanda kutip tunggal. Misalnya, script-src 'self' (dengan tanda kutip) mengizinkan eksekusi JavaScript dari host saat ini; script-src self (tanpa tanda kutip) memungkinkan JavaScript dari server bernama "self" (dan bukan dari host saat ini), yang mungkin bukan yang Anda maksudkan.

Sandboxing

Ada satu perintah lagi yang patut dibahas: sandbox. Ini sedikit berbeda dari contoh lain yang telah kita lihat, karena terdapat pembatasan pada tindakan yang dapat dilakukan oleh halaman, bukan pada resource yang dapat dimuat oleh halaman. Jika perintah sandbox ada, halaman akan diperlakukan seolah-olah dimuat di dalam <iframe> dengan atribut sandbox. Efeknya dapat memiliki berbagai efek pada halaman: antara lain, memaksa halaman ke asal yang unik, dan mencegah pengiriman formulir. Bagian ini sedikit di luar cakupan artikel ini, tetapi Anda dapat menemukan detail lengkap tentang atribut sandbox yang valid di bagian "Sandboxing" pada spesifikasi HTML5.

Tag meta

Mekanisme pengiriman pilihan CSP adalah header HTTP. Namun, sebaiknya tetapkan kebijakan pada halaman langsung di markup. Lakukan hal tersebut 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'"
/>

Tidak dapat digunakan untuk frame-ancestors, report-uri, atau sandbox.

Kode {i>inline<i} dianggap berbahaya

Sudah jelas bahwa CSP didasarkan pada origin daftar yang diizinkan, karena ini merupakan cara yang tidak ambigu dalam memerintahkan browser untuk memperlakukan kumpulan resource tertentu sebagai dapat diterima dan untuk menolak sisanya. Namun, daftar yang diizinkan berbasis asal tidak menyelesaikan ancaman terbesar yang ditimbulkan oleh serangan XSS: injeksi skrip inline. Jika penyerang dapat menginjeksikan tag skrip yang secara langsung berisi beberapa payload berbahaya (<script>sendMyDataToEvilDotCom();</script>), browser tidak memiliki mekanisme untuk membedakannya dari tag skrip inline yang sah. CSP mengatasi masalah ini dengan memblokir skrip inline sepenuhnya: itu satu-satunya cara untuk memastikan.

Pemblokiran 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, serta 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 ini memiliki sejumlah keunggulan, yang sangat berguna dengan CSP; sudah menjadi praktik terbaik, terlepas dari penggunaan CSP Anda. JavaScript inline mencampur struktur dan perilaku dengan cara yang tidak seharusnya. Resource eksternal lebih mudah di-cache browser, lebih mudah dipahami developer, dan kondusif untuk kompilasi dan minifikasi. Anda akan menulis kode yang lebih baik jika 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 pemindahan data yang tidak sah sangat cerdas yang didukung oleh 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 tidak. Memblokir skrip inline adalah kemenangan keamanan terbesar yang disediakan CSP, dan memblokir gaya inline juga akan memperkuat aplikasi Anda. Hal ini merupakan sedikit upaya di awal untuk memastikan bahwa segala sesuatunya berfungsi dengan benar setelah memindahkan semua kode keluar dari barisnya, tetapi itulah konsekuensi yang pantas.

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 satu kali) atau hash. Meskipun mungkin tidak praktis, ini sangat berguna untuk situasi darurat.

Untuk menggunakan nonce, berikan atribut nonce pada tag skrip Anda. Nilainya harus cocok dengan yang ada 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 Anda yang ditambahkan ke kata kunci nonce-.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Ingat bahwa nonce harus dibuat ulang untuk setiap permintaan halaman dan harus tidak dapat ditebak.

{i>Hash<i} bekerja dengan cara yang hampir sama. Daripada menambahkan kode ke tag skrip, buat hash SHA untuk skrip itu sendiri dan tambahkan ke perintah script-src. Misalnya, halaman Anda berisi:

<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. Dalam 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 pembuatan hash SHA akan mengarahkan Anda ke solusi dalam berapa pun 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 tidak dapat memasukkan skrip secara langsung, penyerang mungkin dapat mengelabui aplikasi Anda agar mengonversi teks inert menjadi JavaScript yang dapat dieksekusi dan mengeksekusinya atas nama mereka. eval(), new Function() , setTimeout([string], ...), dan setInterval([string], ...) adalah vektor yang digunakan untuk memasukkan teks yang akhirnya mengeksekusi sesuatu yang berbahaya secara tidak terduga. Respons default CSP terhadap risiko ini adalah memblokir sepenuhnya semua vektor tersebut.

Hal ini berdampak lebih dari sedikit pada cara Anda membangun aplikasi:

  • Anda harus mengurai JSON melalui JSON.parse bawaan, bukan mengandalkan eval. Operasi JSON native tersedia di setiap browser sejak IE8, dan benar-benar aman.
  • Tulis ulang panggilan setTimeout atau setInterval yang saat ini Anda lakukan 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 penerapan pemrograman dinamis yang bagus, tetapi berisiko mengevaluasi teks berbahaya. Beberapa framework langsung mendukung CSP, yang kembali ke parser yang andal tanpa eval. Perintah ng-csp dariAngularJS 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 dapat mengaktifkannya dengan menambahkan 'unsafe-eval' sebagai sumber yang diizinkan dalam direktif script-src, tetapi kami sangat tidak menyarankannya. Pemblokiran kemampuan untuk mengeksekusi string akan semakin mempersulit penyerang untuk mengeksekusi kode yang tidak sah di situs Anda.

Pelaporan

Kemampuan CSP untuk memblokir sisi klien resource yang tidak tepercaya merupakan keuntungan besar bagi pengguna Anda, tetapi akan sangat membantu jika notifikasi dikirim kembali ke server sehingga Anda dapat mengidentifikasi dan menghilangkan bug yang memungkinkan injeksi berbahaya sejak awal. Untuk mencapai tujuan ini, Anda dapat memerintahkan browser untuk melakukan POST laporan pelanggaran berformat JSON 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 sejumlah informasi yang akan membantu Anda melacak penyebab khusus pelanggaran, termasuk halaman tempat pelanggaran terjadi (document-uri), perujuk halaman tersebut (perlu diperhatikan bahwa tidak seperti kolom header HTTP, kuncinya tidak salah eja), resource yang melanggar kebijakan halaman (blocked-uri), perintah spesifik yang dilanggar (violated-directive), dan kebijakan lengkap halaman (original-policy).

Laporan Saja

Jika Anda baru mulai menggunakan CSP, sebaiknya evaluasi status aplikasi Anda saat ini sebelum meluncurkan kebijakan ketat kepada pengguna. Sebagai batu loncatan untuk menyelesaikan deployment, 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 hanya laporan tidak akan memblokir resource yang dibatasi, tetapi akan mengirimkan laporan pelanggaran ke lokasi yang Anda tentukan. Anda bahkan dapat mengirim kedua header, dengan menerapkan satu kebijakan sambil memantau kebijakan yang lain. Ini adalah cara yang bagus untuk mengevaluasi efek perubahan pada CSP aplikasi Anda: aktifkan pelaporan untuk kebijakan baru, pantau laporan pelanggaran, dan perbaiki bug yang muncul. Setelah Anda puas dengan efeknya, mulai terapkan kebijakan baru.

Penggunaan di Dunia Nyata

CSP 1 sangat dapat digunakan di Chrome, Safari, dan Firefox, tetapi memiliki dukungan yang sangat terbatas di IE 10. Anda dapat melihat hal-hal spesifik di caniuse.com. CSP Level 2 telah tersedia di Chrome mulai versi 40. Situs besar seperti Twitter dan Facebook telah men-deploy header (Studi kasus Twitter patut dibaca), dan standarnya sudah sangat siap untuk mulai di-deploy di situs Anda sendiri.

Langkah pertama dalam membuat kebijakan untuk aplikasi Anda adalah mengevaluasi resource yang sebenarnya Anda muat. Setelah Anda merasa dapat menangani cara mengumpulkan berbagai hal dalam aplikasi, siapkan kebijakan berdasarkan persyaratan tersebut. Mari kita pelajari beberapa kasus penggunaan umum dan menentukan cara terbaik untuk mendukungnya dalam batasan perlindungan CSP.

Kasus penggunaan #1: widget media sosial

  • Tombol +1 Google menyertakan skrip dari https://apis.google.com dan menyematkan <iframe> dari https://plusone.google.com. Anda memerlukan kebijakan yang menyertakan kedua origin ini untuk menyematkan tombol. Kebijakan minimal adalah script-src https://apis.google.com; child-src https://plusone.google.com. Anda juga perlu memastikan bahwa cuplikan JavaScript yang disediakan Google ditarik ke dalam file JavaScript eksternal. Jika Anda memiliki kebijakan berbasis Level 1 yang menggunakan frame-src Level 2 mengharuskan Anda untuk mengubahnya menjadi child-src. Hal ini tidak lagi diperlukan di CSP Level 3.

  • Tombol Suka Facebook memiliki sejumlah opsi implementasi. Sebaiknya tetap gunakan versi <iframe> karena akan di-sandbox dengan aman dari bagian lain situs Anda. Diperlukan perintah child-src https://facebook.com agar dapat berfungsi dengan benar. Perlu diperhatikan bahwa, secara default, kode <iframe> yang disediakan Facebook akan memuat URL relatif, //facebook.com. Ubah kebijakan tersebut untuk menentukan HTTPS secara eksplisit: https://facebook.com. Tidak ada alasan untuk menggunakan HTTP jika Anda tidak perlu.

  • 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/menempelnya secara lokal.) Anda akan siap dengan script-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 serupa. Sebaiknya cukup setel default-src dari 'none', dan perhatikan konsol Anda untuk menentukan resource mana yang harus Anda aktifkan agar widget tersebut berfungsi.

Penyertaan beberapa widget menjadi sangat mudah: cukup gabungkan direktif kebijakan, dan ingat untuk menggabungkan semua resource dari satu jenis menjadi satu perintah. Jika Anda ingin 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: kunci total

Anggaplah sementara Anda menjalankan situs perbankan dan ingin memastikan bahwa hanya resource yang telah Anda tulis sendiri yang dapat dimuat. Dalam skenario ini, mulai dengan kebijakan default yang benar-benar memblokir semuanya (default-src 'none'), lalu bangun dari sana.

Anggap bank tersebut memuat semua gambar, gaya, dan skrip dari CDN di https://cdn.mybank.net, dan terhubung melalui XHR ke https://api.mybank.com/ untuk menarik berbagai bit data ke bawah. Frame digunakan, tetapi hanya untuk halaman yang dilokalkan ke situs (tidak ada origin pihak ketiga). Tidak ada Flash di situs tersebut, tidak ada font, atau tidak ada tambahan. Header CSP paling ketat yang dapat kita kirim adalah ini:

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 yang aman, tetapi tidak benar-benar menulis banyak kode; menulis ulang potongan besar software forum pihak ketiga yang diisi hingga tepinya 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: ditetapkan dalam default-src, perintah skrip dan gaya tidak otomatis mewarisi sumber tersebut. Setiap perintah sepenuhnya menimpa nilai default untuk jenis resource tertentu.

Acara mendatang

Kebijakan Keamanan Konten Level 2 adalah Rekomendasi Kandidat. Web Application Security Working Group W3C sudah mulai mengerjakan iterasi berikutnya dari spesifikasi ini, Content Security Policy Level 3.

Jika Anda tertarik dengan diskusi seputar fitur mendatang ini, baca arsip milis public-webappsec@, atau bergabunglah secara langsung.

Masukan