Kebijakan Keamanan Konten

Joe Medley
Joe Medley

Model keamanan web telah mengakar di 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 dibiarkan tetap terisolasi dari web lainnya, sehingga memberi developer sandbox yang aman untuk mem-build dan bermain. Secara teori, ini benar-benar cemerlang. Dalam prakteknya, 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 diinginkan. Hal ini merupakan masalah yang sangat besar, karena browser mempercayai semua kode yang muncul di halaman sebagai bagian sah dari asal keamanan halaman tersebut. Cheat Sheet XSS adalah bagian 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, game sudah berakhir: data sesi pengguna telah dibobol dan informasi yang seharusnya dirahasiakan dikuasai oleh Orang Jahat. Kami jelas ingin mencegah hal itu terjadi.

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 boleh dan apa yang tidak.
  • Pelajari direktif apa saja yang tersedia.
  • Pelajari kata kunci yang digunakannya.
  • 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 disuntikkan dengan maksud jahat 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 mempercayai kode tersebut, tetapi kita tidak dapat mengharapkan browser untuk mengetahuinya 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, apa pun 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 menyetujui atau menampilkan resource dari sumber tersebut. Meskipun penyerang dapat menemukan celah untuk menyuntikkan skrip, skrip tersebut tidak akan cocok dengan daftar yang diizinkan, sehingga tidak akan dieksekusi.

Karena kita mempercayai apis.google.com untuk mengirimkan kode yang valid, dan kita mempercayai diri 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 serangkaian hak istimewa terkait skrip untuk halaman tertentu. Kami telah menentukan 'self' sebagai salah satu sumber skrip yang valid, dan https://apis.google.com sebagai sumber lainnya. Browser dengan patuh mengunduh dan mengeksekusi JavaScript dari apis.google.com melalui HTTPS, serta dari origin halaman saat ini.

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

Dengan didefinisikannya kebijakan ini, browser tinggal melontarkan error, bukan memuat skrip dari sumber lain. Jika penyerang yang pintar berhasil menyuntikkan kode ke dalam situs Anda, mereka akan langsung mendapatkan pesan error, bukan keberhasilan yang mereka harapkan.

Kebijakan berlaku pada berbagai macam resource

Meskipun resource skrip merupakan risiko keamanan yang paling nyata, CSP menyediakan serangkaian direktif kebijakan yang beragam dan memungkinkan kontrol yang cukup terperinci atas resource yang diizinkan untuk dimuat halaman. Anda telah melihat script-src, jadi konsepnya sudah jelas.

Mari kita ikuti direktif resource lainnya dengan cepat. 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 bingkai yang disematkan. Misalnya: child-src https://youtube.com akan memungkinkan 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 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>. Direktif ini tidak dapat digunakan di 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 ke child-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 oleh halaman.
  • report-uri menentukan URL tempat browser akan mengirim laporan saat kebijakan keamanan konten dilanggar. Direktif ini tidak dapat digunakan dalam tag <meta>.
  • style-src adalah pasangan script-src untuk stylesheet.
  • upgrade-insecure-requests memerintahkan agen pengguna untuk menulis ulang skema URL, mengubah HTTP menjadi HTTPS. Direktif ini 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, direktif ini terbuka lebar. Jika Anda tidak menetapkan kebijakan tertentu untuk direktif, misalnya font-src, maka direktif tersebut akan berperilaku secara default seolah 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 direktif default-src. Perintah ini menentukan default untuk sebagian besar direktif yang dibiarkan tidak ditentukan. Umumnya, ini berlaku untuk direktif apa pun yang diakhiri dengan -src. Jika default-src ditetapkan ke https://example.com, dan Anda gagal menetapkan perintah font-src, Anda dapat memuat font dari https://example.com, dan tidak dari tempat lain. Kami hanya menentukan script-src dalam contoh sebelumnya, yang berarti gambar, font, dan sebagainya dapat dimuat dari sumber mana pun.

Direktif berikut tidak menggunakan default-src sebagai pengganti. Ingat 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 direktif ini sesuai dengan aplikasi tertentu, cukup mencantumkannya masing-masing di header HTTP, dengan memisahkan 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. Sesuatu seperti berikut ini akan menetapkan 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 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 berawalan ini. Browser modern (dengan pengecualian IE) mendukung header Content-Security-Policy yang tidak berawalan. Itulah header yang harus digunakan.

Header apa pun yang digunakan, kebijakan didefinisikan berdasarkan per halaman: Anda harus mengirim header HTTP bersama setiap respons yang ingin dipastikan terlindungi. Hal ini memberikan banyak fleksibilitas, karena Anda dapat menyesuaikan kebijakan untuk halaman tertentu berdasarkan kebutuhan spesifiknya. Mungkin serangkaian halaman di situs Anda memiliki tombol +1, sementara yang lainnya tidak memiliki: Anda dapat mengizinkan kode tombol dimuat hanya jika diperlukan.

Daftar sumber di setiap direktif bersifat fleksibel. Anda dapat menentukan sumber berdasarkan skema (data:, https:), atau rentang kekhususan dari khusus nama host (example.com, yang cocok dengan asal 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 mungkin Anda harapkan, tidak cocok dengan apa pun.
  • 'self' cocok dengan origin saat ini, tetapi tidak dengan subdomainnya.
  • 'unsafe-inline' mengizinkan JavaScript dan CSS inline. (Kita akan membahasnya lebih mendetail nanti.)
  • 'unsafe-eval' mengizinkan mekanisme teks-ke-JavaScript seperti eval. (Kami juga akan membahasnya.)

Kata kunci ini memerlukan tanda kutip tunggal. Misalnya, script-src 'self' (dengan tanda kutip) mengotorisasi 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 direktif lagi yang patut dibahas: sandbox. Ini sedikit berbeda dari yang lain yang telah kita lihat, karena direktif ini menempatkan pembatasan pada 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 dalam origin unik, dan mencegah pengiriman formulir, dan lain-lain. Hal ini sedikit di luar cakupan artikel ini, tetapi Anda dapat menemukan detail lengkap tentang atribut sandboxing yang valid di bagian "Sandboxing" pada spesifikasi HTML5.

Tag meta

Mekanisme pengiriman yang disukai CSP adalah header HTTP. Namun, ini dapat berguna untuk menetapkan kebijakan pada halaman secara langsung di markup. Lakukan dengan 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 membahayakan

Jelas sudah bahwa CSP didasarkan pada sumber daftar yang diizinkan, karena itulah cara yang tidak meragukan dalam memerintahkan browser untuk memperlakukan serangkaian resource tertentu sebagai dapat diterima dan untuk menolak selebihnya. 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 mencekal skrip inline sepenuhnya: satu-satunya cara yang meyakinkan.

Larangan ini tidak hanya mencakup skrip yang disematkan langsung di tag script, tetapi juga penangan 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 seperti ini:

<!-- 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 telah ditulis ulang tersebut memiliki banyak keuntungan, sangat bekerja dengan baik bersama CSP; sudah menjadi praktik terbaik, apa pun penggunaan CSP Anda. JavaScript inline mencampur struktur dan perilaku dengan cara persis yang tidak akan Anda lakukan. Resource eksternal lebih mudah di-cache browser, lebih mudah dipahami untuk developer, dan kondusif untuk kompilasi dan minifikasi. Anda akan menulis kode yang lebih baik jika melakukan pemindahan kode ke dalam resource eksternal.

Gaya inline diperlakukan dengan cara yang sama: baik atribut style maupun tag style harus dikonsolidasikan ke dalam stylesheet eksternal untuk melindungi dari berbagai metode eksfiltrasi data yang sangat cerdik yang dimungkinkan oleh CSS.

Jika harus memiliki gaya dan skrip inline, Anda dapat mengaktifkannya dengan menambahkan 'unsafe-inline' sebagai sumber yang diizinkan dalam direktif script-src atau style-src. Anda juga dapat menggunakan tanda nonce atau hash (lihat di bawah ini), tetapi sebaiknya tidak. Pencekalan skrip inline adalah kemenangan keamanan terbesar yang disediakan CSP, dan pencekalan gaya inline juga akan memperkuat aplikasi Anda. Ini merupakan sedikit upaya di awal untuk memastikan semuanya berfungsi dengan benar setelah memindah semua kode ke luar baris, tetapi itulah konsekuensi yang pantas.

Jika Anda terpaksa 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 berguna dalam keadaan darurat.

Untuk menggunakan nonce, berikan tag skrip Anda atribut nonce. Nilainya harus sama 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 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.

Cara kerja hash hampir sama. Sebagai ganti menambahkan kode ke tag skrip, buat hash SHA dari skrip itu sendiri dan tambahkan ke perintah script-src. Misalnya, halaman Anda berisi hal berikut:

<script>
  alert('Hello, world.');
</script>

Kebijakan Anda akan berisi ini:

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>. Juga kapitalisasi dan spasi kosong, termasuk spasi kosong di depan atau di belakang.

Penelusuran Google mengenai pembuatan hash SHA akan mengarahkan Anda pada solusi dalam sejumlah bahasa. Dengan menggunakan 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.

Eval 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 sepenuhnya semua vektor tersebut.

Hal ini memiliki lebih dari beberapa dampak pada cara Anda mem-build aplikasi:

  • Anda harus mengurai JSON melalui JSON.parse bawaan, bukan mengandalkan eval. Operasi JSON native tersedia di setiap browser sejak IE8, dan semuanya benar-benar aman.
  • Tulis ulang semua panggilan setTimeout atau setInterval yang sedang 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 bagus dari pemrograman dinamis, tetapi berisiko mengevaluasi teks berbahaya. Beberapa framework mendukung CSP secara langsung, yang melakukan fallback ke parser yang andal jika tidak ada eval. Direktif ng-csp AngularJS adalah contoh yang baik untuk hal ini.

Namun, pilihan yang lebih baik adalah bahasa pembuatan template yang menawarkan prakompilasi (misalnya, Handlebars). Prakompilasi template dapat membuat pengalaman pengguna menjadi jauh lebih cepat daripada implementasi runtime tercepat, dan juga lebih aman. Jika eval dan saudara teks-ke-JavaScript-nya begitu mendasar bagi aplikasi, Anda dapat mengaktifkannya dengan menambahkan 'unsafe-eval' sebagai sumber yang diizinkan dalam perintah script-src, tetapi kami sangat tidak menyarankannya. Dengan melarang kemampuan untuk mengeksekusi string, penyerang akan lebih sulit mengeksekusi kode tidak sah di situs Anda.

Pelaporan

Kemampuan CSP memblokir sisi klien resource yang tidak tepercaya merupakan kemenangan besar bagi pengguna Anda, tetapi akan sangat membantu jika ada semacam notifikasi yang dikirim kembali ke server sehingga Anda dapat mengidentifikasi dan mengatasi bug apa pun yang memungkinkan penyuntikan berbahaya lebih cepat. Untuk mencapai tujuan ini, Anda dapat memerintahkan browser untuk mengirim 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 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 ditetapkan dalam mode hanya-lapor tidak akan memblokir resource yang dibatasi, tetapi akan mengirim laporan pelanggaran ke lokasi yang Anda tetapkan. Anda bahkan dapat mengirim header kedua, yang 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; jika Anda puas dengan efeknya, mulai terapkan kebijakan baru.

Penggunaan di Dunia Nyata

CSP 1 sangat berguna di Chrome, Safari, dan Firefox, tetapi memiliki dukungan 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 menerapkan header (Studi kasus Twitter patut dibaca), dan standar ini sangat siap untuk mulai Anda terapkan di situs Anda sendiri.

Langkah pertama dalam pembuatan kebijakan untuk aplikasi Anda adalah mengevaluasi resource yang sebenarnya Anda muat. Setelah Anda tahu cara menangani berbagai hal yang dimasukkan dalam aplikasi Anda, siapkan kebijakan berdasarkan persyaratan tersebut. Mari kita pelajari beberapa kasus penggunaan umum dan menentukan cara terbaik untuk mendukungnya dalam batasan protektif 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 agar dapat 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 mengubahnya menjadi child-src. Hal ini tidak lagi diperlukan di CSP Level 3.

  • Tombol Suka Facebook memiliki sejumlah opsi penerapan. Sebaiknya tetap gunakan versi <iframe> karena sandbox-nya aman dari bagian lain situs Anda. Diperlukan direktif child-src https://facebook.com agar dapat berfungsi dengan benar. Perhatikan bahwa, secara default, kode <iframe> yang disediakan Facebook memuat URL relatif, //facebook.com. Ubahlah untuk menetapkan secara eksplisit HTTPS: https://facebook.com. Tidak ada alasan menggunakan HTTP jika Anda tidak perlu.

  • Tombol Tweet Twitter mengandalkan akses ke skrip dan bingkai, 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 menggunakan 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 tetapkan default-src dari 'none', dan amati konsol Anda untuk menentukan resource yang perlu diaktifkan agar widget berfungsi.

Penyertaan beberapa widget sekaligus jadi sederhana: tinggal gabungkan direktif kebijakan, asalkan ingat untuk menggabungkan semua resource dari satu jenis menjadi satu direktif. Jika Anda ingin ketiga widget media sosial, kebijakan tersebut 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: penguncian

Anggaplah sementara Anda menjalankan situs perbankan dan ingin memastikan bahwa hanya resource yang telah Anda tulis sendiri yang nanti bisa dimuat. Dalam skenario ini, mulailah dengan kebijakan default yang akan memblokir secara mutlak segala sesuatu (default-src 'none'), dan bangunlah dari sana.

Anggaplah bank tersebut memuat semua gambar, gaya, dan skrip dari CDN di https://cdn.mybank.net, dan menghubungkan melalui XHR ke https://api.mybank.com/ untuk mengambil berbagai bit data. Bingkai digunakan, tetapi hanya untuk halaman yang bersifat lokal ke situs (tidak ada origin pihak ketiga). Tidak ada Flash di situs tersebut, tidak ada font, tidak ada ekstra. 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: hanya SSL

Admin forum diskusi cincin pernikahan ingin memastikan semua resource hanya dimuat melalui saluran aman, tetapi tidak menulis kode yang banyak; ia tidak mampu menulis ulang potongan besar software forum pihak ketiga yang diisikan ke tepian dengan skrip inline dan gaya. Kebijakan berikut akan berlaku:

Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'

Meskipun https: ditentukan di default-src, direktif skrip dan gaya tidak otomatis mewarisi sumber tersebut. Setiap perintah sepenuhnya menulis ulang default untuk jenis resource tertentu tersebut.

Acara mendatang

Content Security Policy Level 2 adalah Rekomendasi Calon. W3C Web Application Security Working Group 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 dalam diskusi.

Masukan