Sistem ekstensi Chrome menerapkan Kebijakan Keamanan Konten (CSP) default yang cukup ketat.
Pembatasan kebijakannya sangat jelas: skrip harus dipindahkan keluar baris menjadi
File JavaScript, pengendali peristiwa inline harus dikonversi untuk menggunakan addEventListener
, dan eval()
adalah
dinonaktifkan. Aplikasi Chrome memiliki kebijakan yang lebih ketat, dan kami cukup puas dengan keamanannya
yang disediakan oleh
kebijakan ini.
Namun, kami menyadari bahwa berbagai library menggunakan konstruksi seperti eval()
dan eval
seperti
new Function()
untuk pengoptimalan performa dan kemudahan berekspresi. Library template
sangat rentan terhadap
gaya implementasi ini. Meskipun beberapa (seperti Angular.js) mendukung CSP out
standar, banyak kerangka kerja populer yang belum
diperbarui menjadi mekanisme yang kompatibel dengan
ekstensi' Dunia lebih sedikit eval
. Menghapus dukungan untuk fungsi tersebut terbukti lebih
bermasalah dari yang diharapkan bagi developer.
Dokumen ini memperkenalkan sandboxing sebagai mekanisme yang aman untuk menyertakan library-library ini dalam project Anda tanpa mengorbankan keamanan. Untuk singkatnya, kami akan menggunakan istilah ekstensi secara keseluruhan, tapi konsep ini berlaku sama untuk aplikasi.
Mengapa menggunakan sandbox?
eval
berbahaya di dalam ekstensi karena kode yang dijalankan memiliki akses ke semua hal di
lingkungan izin akses tinggi ekstensi. Tersedia berbagai API chrome.*
andal yang dapat
sangat memengaruhi keamanan dan privasi pengguna; pemindahan data secara tidak sah adalah
hal yang paling tidak kami khawatirkan.
Solusi yang ditawarkan adalah sandbox tempat eval
dapat mengeksekusi kode tanpa akses ke
data ekstensi atau API bernilai tinggi dari ekstensi. Tidak ada data, tidak ada API, tidak masalah.
Kami melakukannya dengan mencantumkan file HTML tertentu di dalam paket ekstensi sebagai yang di-sandbox.
Setiap kali halaman dalam sandbox dimuat, halaman tersebut akan dipindahkan ke asal yang unik, dan akan ditolak
akses ke chrome.*
API. Jika kita memuat halaman yang di-sandbox ini ke dalam ekstensi melalui iframe
, kita bisa
meneruskan pesannya, membiarkannya bertindak terhadap pesan itu
dengan cara tertentu, dan menunggunya memberikan kembali
hasil pengujian tersebut. Mekanisme pesan yang sederhana ini memberikan semua yang kami butuhkan untuk menyertakan aman berbasis eval
dalam alur kerja ekstensi kita.
Membuat dan menggunakan sandbox.
Jika Anda ingin langsung mempelajari kode, ambil ekstensi contoh sandboxing dan ikuti nonaktif. Ini adalah contoh API pesan kecil yang berfungsi dan dibangun di atas Handlebar membuat template library, dan ini akan memberi Anda semua yang Anda perlukan untuk memulai. Bagi Anda yang ingin seperti sedikit penjelasan lebih lanjut, mari kita kita bahas contoh itu bersama-sama di sini.
Mencantumkan file dalam manifes
Setiap file yang harus dijalankan di dalam sandbox harus tercantum dalam manifes ekstensi dengan menambahkan elemen
sandbox
. Ini adalah langkah yang penting, dan mudah dilupakan, jadi periksa kembali apakah
file yang telah di-sandbox akan tercantum di manifes. Dalam contoh ini, kami meng-{i>sandbox<i} file dengan cerdas
bernama "sandbox.html". Entri manifes akan terlihat seperti ini:
{
...,
"sandbox": {
"pages": ["sandbox.html"]
},
...
}
Memuat file dalam sandbox
Untuk melakukan sesuatu yang menarik dengan file {i>sandbox<i}, kita perlu mengunggahnya dalam konteks di mana
dapat ditangani oleh kode ekstensi. Di sini, sandbox.html telah dimuat ke dalam
Halaman Peristiwa ekstensi (eventpage.html) melalui iframe
. eventpage.js berisi kode
yang mengirim pesan ke sandbox setiap kali tindakan browser diklik dengan mencari iframe
di halaman, dan menjalankan metode postMessage
di contentWindow
. Pesan adalah objek
yang berisi dua properti: context
dan command
. Kita akan segera membahas keduanya.
chrome.browserAction.onClicked.addListener(function() {
var iframe = document.getElementById('theFrame');
var message = {
command: 'render',
context: {thing: 'world'}
};
iframe.contentWindow.postMessage(message, '*');
});
postMessage
API, lihat dokumentasi postMessage
di MDN . Konten ini cukup lengkap dan layak dibaca. Secara khusus, perlu diperhatikan bahwa data hanya dapat diteruskan bolak-balik jika dapat diserialisasi. Fungsi, misalnya, tidak bersifat umum.Lakukan hal berbahaya
Saat sandbox.html
dimuat, library ini akan memuat library Handlebars, serta membuat dan mengompilasi sebuah inline
seperti yang disarankan oleh Handlebars:
<script src="handlebars-1.0.0.beta.6.js"></script>
<script id="hello-world-template" type="text/x-handlebars-template">
<div class="entry">
<h1>Hello, !</h1>
</div>
</script>
<script>
var templates = [];
var source = document.getElementById('hello-world-template').innerHTML;
templates['hello'] = Handlebars.compile(source);
</script>
Ini tidak gagal! Meskipun Handlebars.compile
akhirnya menggunakan new Function
, semuanya berfungsi
seperti yang diharapkan, dan kita mendapatkan template yang dikompilasi di templates['hello']
.
Meneruskan hasilnya kembali
Kita akan menyediakan template ini untuk digunakan dengan menyiapkan pemroses pesan yang menerima perintah
dari Halaman Peristiwa. Kita akan menggunakan command
yang diteruskan untuk menentukan apa yang harus dilakukan (Anda dapat
bayangkan melakukan lebih
dari sekadar rendering; mungkin membuat {i>template<i}? Mungkin mengelolanya di beberapa
?), dan context
akan diteruskan ke template secara langsung untuk rendering. HTML yang dirender
akan diteruskan kembali ke Halaman Peristiwa sehingga ekstensi dapat melakukan sesuatu yang bermanfaat di lain waktu:
<script>
window.addEventListener('message', function(event) {
var command = event.data.command;
var name = event.data.name || 'hello';
switch(command) {
case 'render':
event.source.postMessage({
name: name,
html: templates[name](event.data.context)
}, event.origin);
break;
// case 'somethingElse':
// ...
}
});
</script>
Kembali ke Halaman Acara, kita akan menerima pesan ini, dan melakukan sesuatu yang menarik dengan html
data yang telah kita teruskan. Dalam hal ini, kita hanya akan menggemakannya melalui Notifikasi Desktop, tetapi
HTML ini dapat digunakan dengan aman
sebagai bagian dari UI ekstensi. Menyisipkannya melalui
innerHTML
tidak menimbulkan risiko keamanan yang signifikan, bahkan penyusupan sepenuhnya terhadap proses sandbox
kode melalui beberapa serangan pintar tidak akan dapat
menginjeksikan skrip berbahaya atau konten {i>plugin<i} ke
konteks ekstensi dengan izin tinggi.
Mekanisme ini membuat pembuatan template menjadi mudah, tetapi tentu saja tidak terbatas pada pembuatan template. Apa saja kode yang tidak berfungsi secara langsung dalam Kebijakan Keamanan Konten yang ketat dapat di-sandbox; inci Namun, sering kali ada baiknya untuk melakukan sandbox komponen ekstensi Anda yang akan berjalan dengan benar dalam urutan untuk membatasi setiap bagian dari program Anda ke rangkaian hak istimewa terkecil yang diperlukan agar dapat berjalan dengan baik. Presentasi Writing Secure Web Apps and Chrome Extensions dari Google I/O 2012 memberikan beberapa contoh yang baik dari penerapan teknik ini, dan bernilai 56 menit dari baik.