Kebijakan Keamanan Konten

Joe Medley
Joe Medley

Model keamanan web berakar pada kebijakan origin yang sama. Kode dari https://mybank.com hanya boleh mengakseshttps://mybank.com data, dan https://evil.example.com tentu saja tidak boleh mengizinkan akses. Setiap origin tetap terisolasi dari keseluruhan web, sehingga memberikan keamanan bagi developer sandbox tempat membangun dan bermain. Secara teori, ini benar-benar brilian. Di beberapa penyerang telah menemukan cara cerdas untuk menumbangkan sistem.

Pembuatan skrip lintas situs (XSS) serangan, misalnya, mengabaikan kebijakan origin yang sama dengan mengelabui situs agar mengirimkan kode berbahaya beserta konten yang diinginkan. Ini adalah pengalaman karena browser memercayai semua kode yang muncul di halaman sebagai merupakan bagian sah dari asal keamanan halaman tersebut. Tujuan Tips Praktis XSS adalah lintas metode yang sudah lama namun representatif dan mungkin digunakan melanggar kepercayaan ini dengan cara memasukkan kode berbahaya. Jika penyerang berhasil memasukkan kode apa pun, ini sudah selesai: data sesi pengguna disusupi dan informasi yang harus dirahasiakan yang dipindahkan ke The Bad Teman-teman. Tentu saja kami akan mencegah hal itu terjadi.

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

TL;DR

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

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 secara berbahaya oleh pihak ketiga. Misalnya, tombol +1 Google di bagian bawah halaman ini memuat dan menjalankan kode dari https://apis.google.com/js/plusone.js dalam konteks asal halaman ini. Rab memercayai kode itu, tetapi kita tidak bisa berharap {i>browser<i} mengetahui kode itu sendiri dari apis.google.com luar biasa, sedangkan kode dari apis.evil.example.com mungkin tidak. Browser dengan senang hati mendownload dan mengeksekusi kode apa pun permintaan, terlepas dari sumbernya.

CSP mendefinisikan atribut semua yang diberikan server, bukan memercayai header HTTP Content-Security-Policy, yang memungkinkan Anda membuat daftar sumber konten tepercaya, dan menginstruksikan browser untuk hanya menjalankan atau merender resource dari sumber tersebut. Bahkan jika penyerang dapat menemukan lubang yang bisa dilalui untuk memasukkan skrip, skrip tidak akan cocok dengan daftar yang diizinkan, sehingga tidak akan telah dijalankan.

Karena kita memercayai 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 untuk dieksekusi berasal dari salah satu dari dua sumber berikut:

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

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

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

Setelah kebijakan ini ditetapkan, browser akan menampilkan error, bukan memuat skrip dari sumber lain. Ketika penyerang yang pintar berhasil memasukkan kode ke situs, maka mereka akan langsung menerima pesan {i>error<i}, dari kesuksesan yang mereka harapkan.

Kebijakan berlaku untuk berbagai macam resource

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

Mari kita telusuri dengan cepat perintah sumber daya lainnya. Daftar di bawah ini mewakili status perintah pada tingkat 2. Spesifikasi level 3 telah dipublikasikan, tetapi sebagian besar tidak diterapkan dalam laporan browser.

  • base-uri membatasi URL yang dapat muncul di elemen <base> halaman.
  • child-src mencantumkan URL untuk pekerja dan konten frame tersemat. Sebagai contoh: child-src https://youtube.com akan mengaktifkan penyematan video dari YouTube, tetapi bukan dari origin yang lain.
  • connect-src membatasi origin yang dapat Anda hubungkan (melalui XHR, WebSockets, dan EventSource).
  • font-src menentukan origin yang dapat menyalurkan font web. Web Google font 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 di tag <meta> dan hanya berlaku untuk non-HTML Google Cloud Platform.
  • 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 origin yang diizinkan untuk menayangkan video dan audio.
  • object-src memungkinkan kontrol atas plugin Flash dan plugin lainnya.
  • plugin-types membatasi jenis plugin yang dapat dipanggil oleh halaman.
  • report-uri menentukan URL yang akan digunakan browser untuk mengirim laporan kebijakan keamanan konten dilanggar. Perintah ini tidak dapat digunakan di <meta> {i>tag<i}.
  • style-src adalah pasangan script-src untuk stylesheet.
  • upgrade-insecure-requests menginstruksikan agen pengguna untuk menulis ulang skema URL, mengubah HTTP ke HTTPS. Perintah ini ditujukan untuk situs web dengan sejumlah besar 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, direktif memiliki penerapan yang terbatas.

Secara default, direktif terbuka lebar. Jika Anda tidak menetapkan kebijakan khusus untuk , misalkan font-src, maka perintah tersebut secara default akan berperilaku sebagai meskipun Anda telah menentukan * sebagai sumber yang valid (misalnya, Anda dapat memuat font dari di mana saja, tanpa batasan).

Anda dapat mengganti perilaku default ini dengan menentukan default-src direktif. Direktif ini mendefinisikan default untuk sebagian besar direktif yang tidak ditentukan. Umumnya, ini berlaku untuk setiap direktif yang diakhiri dengan -src. Jika default-src disetel ke https://example.com, dan Anda gagal untuk menentukan direktif font-src, maka Anda dapat memuat font dari https://example.com, dan tidak di tempat lain. Kita hanya menentukan script-src dalam contoh sebelumnya, yang berarti bahwa gambar, {i>font<i}, dan sebagainya dapat dimuat dari asal apa pun.

Perintah berikut tidak menggunakan default-src sebagai penggantian. Perlu diingat bahwa gagal mengaturnya sama dengan mengizinkan apa pun.

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

Anda dapat menggunakan sebanyak atau sesedikit mungkin direktif ini yang sesuai untuk aplikasi tertentu, cukup mencantumkan masing-masing di {i>header<i} HTTP, 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 direktif kedua akan diabaikan. Sesuatu seperti berikut ini akan menentukan kedua origin dengan benar sebagai valid:

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

Misalnya, jika Anda memiliki aplikasi yang memuat semua sumber dayanya dari jaringan penayangan konten (misalnya, https://cdn.example.net), dan mengetahui bahwa Anda tidak memerlukan konten atau plugin berbingkai, maka kebijakan Anda mungkin terlihat seperti berikut ini:

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 awalan ini {i>header<i}. Browser modern (dengan pengecualian IE) mendukung awalan Header Content-Security-Policy. Itulah {i>header<i} yang harus Anda gunakan.

Terlepas dari header yang Anda gunakan, kebijakan ditentukan berdasarkan halaman demi halaman: Anda harus mengirim {i>header<i} HTTP beserta setiap respons yang ingin Anda dipastikan terlindungi. Hal ini memberikan banyak fleksibilitas, karena Anda dapat melakukan penyesuaian kebijakan untuk halaman tertentu berdasarkan kebutuhan spesifik mereka. Mungkin satu set halaman di situs Anda memiliki tombol +1, sementara yang lain tidak: Anda dapat mengizinkan kode tombol hanya dimuat jika diperlukan.

Daftar sumber di setiap perintah bersifat fleksibel. Anda dapat menentukan sumber dengan skema (data:, https:), atau dengan kekhususan mulai dari nama host saja (example.com, yang cocok dengan origin apa pun di host tersebut: skema apa pun, port apa pun) dengan 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 dari example.com (tetapi bukan example.com itu sendiri), menggunakan skema apa pun, di porta apa pun.

Daftar sumber juga menerima empat kata kunci:

  • 'none', seperti yang mungkin Anda harapkan, tidak cocok.
  • 'self' cocok dengan asal saat ini, tetapi tidak subdomainnya.
  • 'unsafe-inline' mengizinkan JavaScript dan CSS inline. (Kita akan membahasnya di secara lebih detail sebentar lagi.)
  • 'unsafe-eval' mengizinkan mekanisme teks ke JavaScript seperti eval. (Kita akan mendapatkan dengan teks ini juga.)

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

Sandboxing

Ada satu perintah lagi yang patut dibahas: sandbox. Sedikit peduli berbeda dari yang lain yang telah kita lihat, karena perintah ini menempatkan pembatasan pada tindakan yang diambil oleh halaman, bukan pada resource yang dapat dimuat halaman. Jika Perintah sandbox ada, halaman diperlakukan seolah-olah dimuat di dalam <iframe> dengan atribut sandbox. {i>Dataframe<i} ini dapat memiliki berbagai efek pada halaman: memaksa halaman ke asal yang unik, dan mencegah formulir kiriman, antara lain. Ini sedikit di luar cakupan artikel ini, tetapi Anda Anda dapat menemukan detail selengkapnya tentang atribut sandbox yang valid di "Sandbox" di bagian spesifikasi HTML5.

Tag meta

Mekanisme pengiriman yang disukai CSP adalah header HTTP. Hal ini dapat berguna, untuk menetapkan kebijakan pada laman langsung di {i>markup<i}. Lakukan hal ini 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'"
/>

Fitur ini tidak dapat digunakan untuk frame-ancestors, report-uri, atau sandbox.

Kode {i>inline<i} dianggap berbahaya

Harus jelas bahwa CSP didasarkan pada origin daftar yang diizinkan, karena cara yang tidak ambigu dalam memerintahkan browser untuk memperlakukan kumpulan resource tertentu masih dapat diterima dan menolak sisanya. Daftar yang diizinkan berbasis origin tidak tetapi, mengatasi ancaman terbesar yang ditimbulkan oleh serangan XSS: injeksi skrip inline. Jika penyerang dapat menyuntikkan tag skrip yang secara langsung berisi beberapa {i>malware <i} payload (<script>sendMyDataToEvilDotCom();</script>), browser tidak memiliki mekanisme untuk membedakannya dari browser tag skrip inline. CSP mengatasi masalah ini dengan memblokir skrip inline sepenuhnya: satu-satunya cara untuk memastikannya.

Larangan ini tidak hanya mencakup skrip yang disematkan langsung dalam tag script, tetapi juga pengendali peristiwa inline, dan javascript: URL. Anda harus memindahkan konten script tag ke dalam file eksternal, dan ganti URL javascript: dan <a ... onclick="[JAVASCRIPT]"> dengan panggilan addEventListener() yang sesuai. Misalnya, Anda dapat menulis ulang kode berikut ini:

<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 lebih dari sekedar bekerja dengan baik dengan CSP; itu sudah menjadi praktik terbaik, apa pun penggunaan CSP Anda. Bagian dari teks JavaScript mencampur struktur dan perilaku dengan cara yang tidak seharusnya Anda lakukan. Sumber daya eksternal lebih mudah di-cache oleh browser, lebih mudah dipahami developer, dan kondusif untuk kompilasi dan minifikasi. Anda akan menulis dengan lebih baik kode jika Anda melakukan pekerjaan untuk memindahkan kode ke resource eksternal.

Gaya inline diperlakukan dengan cara yang sama: atribut style dan style tag harus digabungkan ke dalam stylesheet eksternal untuk melindungi dari variasi yang sangat pintar metode pemindahan data yang tidak sah yang dimungkinkan oleh CSS.

Jika harus memiliki skrip dan gaya inline, Anda dapat mengaktifkannya dengan menambahkan 'unsafe-inline' sebagai sumber yang diizinkan di script-src atau style-src direktif. Anda juga dapat menggunakan nonce atau {i>hash<i} (lihat di bawah ini), tetapi sebaiknya tidak. Pemblokiran skrip sebaris adalah kemenangan keamanan terbesar yang disediakan CSP, dan {i>banning<i} {i>inline<i} juga akan mengeraskan aplikasi Anda. Ini sedikit dari awal untuk memastikan bahwa semuanya bekerja dengan benar setelah memindahkan semua kode di luar cakupan, tapi itu adalah kompromi yang layak dilakukan.

Jika Anda terpaksa harus

CSP Level 2 menawarkan kompatibilitas mundur untuk skrip sebaris dengan memungkinkan Anda untuk tambahkan skrip inline tertentu ke daftar yang diizinkan menggunakan nonce kriptografi (angka digunakan sekali) atau sebuah {i>hash.<i} Meskipun mungkin merepotkan, cara ini berguna terburu-buru.

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

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

<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 {i>hash<i}. Dalam contoh di atas, sha256- digunakan. CSP juga mendukung sha384- dan sha512-. Saat membuat {i>hash<i}, jangan sertakan Tag <script>. Kapitalisasi dan spasi kosong juga penting, termasuk awal atau spasi kosong di akhir.

Penelusuran Google tentang pembuatan {i>hash<i} SHA akan mengarahkan Anda ke solusi dalam hal apa pun jumlah bahasa. Dengan Chrome 40 atau yang lebih baru, Anda bisa membuka DevTools lalu muat ulang halaman Anda. Tab Console akan berisi pesan {i>error<i} dengan {i>hash sha256<i} untuk setiap skrip {i>inline<i} Anda.

Evaluasi juga

Bahkan ketika penyerang tidak dapat menyuntikkan skrip secara langsung, mereka mungkin dapat mengelabui aplikasi Anda menjadi konversi teks inert yang lain menjadi JavaScript yang dapat dieksekusi dan mengeksekusinya atas nama mereka. eval(), baru Function() , setTimeout([string], ...), dan setInterval([string], ...) adalah semua vektor yang diinjeksikan mungkin akhirnya mengeksekusi sesuatu yang berbahaya secara tidak terduga. Default CSP respons terhadap risiko ini adalah dengan memblokir semua vektor ini.

Dampaknya tidak cukup besar pada cara Anda membangun aplikasi:

  • Anda harus mengurai JSON melalui JSON.parse bawaan, bukan mengandalkan eval. Operasi JSON bawaan tersedia di semua browser sejak IE8, dan ini benar-benar aman.
  • Menulis 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 aplikasi yang bagus dari pemrograman dinamis, tetapi berisiko mengevaluasi teks berbahaya. Beberapa kerangka kerja mendukung CSP siap pakai, kembali ke parser yang andal jika tidak ada eval. Perintah ng-csp dari AngularJS adalah contoh yang baik.

Namun, pilihan yang lebih baik adalah bahasa template yang menawarkan prakompilasi (Handlebars melakukannya, ). Prakompilasi {i>template<i} Anda dapat membuat pengalaman pengguna lebih cepat daripada implementasi {i>runtime<i} tercepat, dan juga lebih aman. Jika eval dan saudara teks-ke-JavaScript-nya sangat penting untuk aplikasi Anda, Anda dapat aktifkan dengan menambahkan 'unsafe-eval' sebagai sumber yang diizinkan di script-src tetapi kami sangat tidak menyarankannya. Memblokir kemampuan untuk menjalankan {i>string<i} akan mempersulit penyerang untuk melakukan eksekusi tanpa izin pada situs Anda.

Pelaporan

Kemampuan CSP untuk memblokir sumber daya yang tidak tepercaya dari sisi klien adalah kemenangan besar bagi pengguna, tetapi akan sangat membantu untuk memiliki beberapa jenis notifikasi dikirim kembali ke server sehingga Anda dapat mengidentifikasi dan menghancurkan semua {i>bug<i} yang memungkinkan injeksi berbahaya sejak awal. Untuk tujuan ini, Anda dapat menginstruksikan browser agar POST laporan pelanggaran berformat JSON ke suatu 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"
  }
}

Ini berisi sepotong informasi yang baik yang akan membantu Anda melacak penyebab spesifik pelanggaran, termasuk halaman tempat pelanggaran terjadi (document-uri), perujuk halaman tersebut (perhatikan bahwa tidak seperti permintaan HTTP header, kunci tidak salah eja), resource yang melanggar kebijakan halaman (blocked-uri), perintah spesifik yang dilanggar (violated-directive), dan kebijakan lengkap halaman (original-policy).

Hanya Laporan

Jika Anda baru mulai menggunakan CSP, masuk akal untuk mengevaluasi aplikasi Anda sebelum meluncurkan kebijakan yang kejam kepada pengguna. Sebagai batu loncatan untuk menyelesaikan deployment, Anda dapat meminta browser untuk memantau kebijakan, melaporkan pelanggaran tetapi tidak menerapkan pembatasan. Daripada fokus pada mengirim header Content-Security-Policy, mengirim 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 laporan saja tidak akan memblokir resource yang dibatasi, tetapi Google akan mengirimkan laporan pelanggaran ke lokasi yang Anda tentukan. Anda bahkan dapat mengirim kedua header, menerapkan satu kebijakan sekaligus memantau kebijakan lainnya. Ini adalah cara untuk mengevaluasi efek perubahan pada CSP aplikasi Anda: aktifkan untuk membuat kebijakan baru, memantau laporan pelanggaran, dan memperbaiki {i>bug<i} munculkan; jika Anda puas dengan penerapannya, mulailah menerapkan kebijakan baru.

Penggunaan di Dunia Nyata

CSP 1 sangat berguna di Chrome, Safari, dan Firefox, tetapi sangat terbatas. di IE 10. Anda dapat lihat detailnya di caniuse.com. CSP Level 2 telah tersedia di Chrome sejak versi 40. Situs besar seperti Twitter dan Facebook telah menyebarkan {i>header<i} (Studi kasus Twitter layak dibaca), dan standarnya sangat siap untuk mulai menerapkan di situs Anda sendiri.

Langkah pertama dalam membuat kebijakan untuk aplikasi Anda adalah mengevaluasi sumber daya yang benar-benar Anda muat. Setelah Anda berpikir bahwa Anda dapat memahami semua hal dikumpulkan di aplikasi Anda, siapkan kebijakan berdasarkan hal-hal tersebut lainnya. Mari kita telusuri beberapa kasus penggunaan umum dan tentukan bagaimana kita paling mampu mendukung mereka 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 untuk menyematkan tombol. Kebijakan minimalnya adalah script-src https://apis.google.com; child-src https://plusone.google.com. Anda juga memerlukan untuk memastikan bahwa cuplikan JavaScript yang disediakan Google ditarik ke dalam file JavaScript eksternal. Jika Anda memiliki kebijakan berbasis Level 1 menggunakan frame-src Level 2 mengharuskan Anda untuk mengubahnya menjadi child-src. Tindakan ini tidak lagi diperlukan di CSP Level 3.

  • Tombol Suka Facebook memiliki sejumlah opsi implementasi. Sebaiknya tetap ikuti <iframe> karena di-sandbox dengan aman dari bagian lain situs Anda. Ini memerlukan perintah child-src https://facebook.com agar dapat berfungsi dengan baik. Catatan secara default, kode <iframe> yang disediakan Facebook akan memuat URL, //facebook.com. Ubah untuk menentukan HTTPS secara eksplisit: https://facebook.com. Anda tidak perlu menggunakan HTTP jika tidak perlu.

  • Tombol Tweet Twitter bergantung pada akses ke skrip dan {i>frame<i}, keduanya di-{i>host<i} di https://platform.twitter.com. (Twitter juga menyediakan URL relatif dengan default; edit kode untuk menentukan HTTPS saat menyalin/menempelnya 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 dalam file JavaScript eksternal.

  • Platform lain memiliki persyaratan serupa, dan dapat ditangani dengan cara serupa. Kami sarankan cukup setel default-src dari 'none', dan tonton konsol Anda untuk menentukan resource yang harus Anda aktifkan agar widget berfungsi.

Penyertaan beberapa widget sangat mudah: cukup gabungkan kebijakan perintah, ingat untuk menggabungkan semua sumber daya dari satu jenis menjadi satu direktif. Jika Anda ingin ketiga widget media sosial tersebut, kebijakan 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

Asumsikan bahwa Anda menjalankan situs perbankan dan ingin memastikan bahwa hanya sumber daya yang Anda tulis sendiri yang dapat dimuat. Dalam skenario ini, mulailah dengan kebijakan default yang memblokir semua (default-src 'none') dan membangun dari sana.

Katakanlah bank 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. Bingkai digunakan, namun hanya untuk laman yang bersifat lokal untuk (tidak ada origin pihak ketiga). Tidak ada Flash di situs, tidak ada font, tidak tambahan. Header CSP paling ketat yang bisa 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 sumber daya hanya dimuat melalui saluran aman, tetapi tidak benar-benar menulis banyak kode; menulis ulang potongan besar perangkat lunak forum pihak ketiga yang penuh dengan skrip dan gaya inline di luar kemampuannya. Kebijakan berikut akan efektif:

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

Meskipun https: ditentukan dalam default-src, skrip dan gaya tidak secara otomatis mewarisi sumber tersebut. Setiap perintah sepenuhnya menimpa default untuk jenis resource tertentu.

Acara mendatang

Kebijakan Keamanan Konten Tingkat 2 adalah Rekomendasi Kandidat. Grup Kerja Keamanan Aplikasi Web W3C telah mulai mengerjakan iterasi spesifikasi berikutnya, Kebijakan Keamanan Konten Level 3.

Jika Anda tertarik untuk diskusi seputar fitur-fitur yang akan datang ini, membaca sekilas arsip milis publik-webappsec@, atau bergabung dalam diri Anda sendiri.

Masukan