Ekstensi memiliki akses ke hak istimewa di dalam browser, menjadikannya target yang menarik bagi penyerang. Jika ekstensi disusupi, setiap pengguna ekstensi tersebut menjadi rentan terhadap gangguan yang berbahaya dan tidak diinginkan. Jaga keamanan ekstensi dan lindungi penggunanya dengan menerapkan praktik ini.
Melindungi akun developer
Kode ekstensi diupload dan diperbarui melalui Akun Google. Jika akun developer disusupi, penyerang dapat mengirimkan kode berbahaya langsung ke semua pengguna. Lindungi akun ini dengan membuat akun developer khusus dan mengaktifkan autentikasi 2 langkah , sebaiknya dengan kunci keamanan .
Menjaga agar grup tetap selektif
Jika menggunakan penayangan grup, batasi grup hanya untuk developer tepercaya. Jangan menerima permintaan keanggotaan dari orang yang tidak dikenal.
Jangan Pernah Menggunakan HTTP
Saat meminta atau mengirim data, hindari koneksi HTTP. Asumsikan bahwa setiap koneksi HTTP akan memiliki penyadap atau berisi modifikasi. HTTPS harus selalu menjadi pilihan utama, karena memiliki keamanan bawaan yang dapat mencegah sebagian besar serangan man-in-the-middle.
Meminta izin minimal
Browser Chrome membatasi akses ekstensi ke hak istimewa yang telah diminta secara eksplisit dalam manifes. Ekstensi harus meminimalkan izinnya dengan hanya mendaftarkan API dan situs yang menjadi dependensinya. Kode arbitrer harus diminimalkan.
Membatasi hak istimewa ekstensi akan membatasi apa yang dapat dieksploitasi oleh calon penyerang.
XMLHttpRequest lintas origin
Ekstensi hanya dapat menggunakan XMLHttpRequest untuk mendapatkan resource dari dirinya sendiri dan dari domain yang ditentukan dalam izin.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"permissions": [
"/*",
"https://*.google.com/"
],
"manifest_version": 2
}
Ekstensi ini meminta akses ke apa pun di developer.chrome.com dan subdomain Google dengan mencantumkan "/*" dan "https://*google.com/" dalam izin. Jika ekstensi disusupi, ekstensi tersebut tetap hanya memiliki izin untuk berinteraksi dengan situs yang memenuhi
pola kecocokan. Penyerang tidak akan dapat mengakses "https://user_bank_info.com" atau berinteraksi dengan "https://malicious_website.com".
Membatasi kolom manifes
Menyertakan pendaftaran yang tidak perlu dalam manifes akan menimbulkan kerentanan dan membuat ekstensi lebih terlihat. Batasi kolom manifes hanya untuk kolom yang diandalkan ekstensi dan berikan pendaftaran kolom spesifik.
Dapat dihubungkan secara eksternal
Gunakan kolom externally_connectable untuk menyatakan ekstensi eksternal dan halaman web mana yang akan digunakan ekstensi untuk bertukar informasi. Membatasi siapa yang dapat dihubungkan secara eksternal oleh ekstensi ke sumber tepercaya.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Referensi yang dapat diakses melalui web
Membuat resource dapat diakses oleh web, di bagian web_accessible_resources akan membuat ekstensi dapat dideteksi oleh situs dan penyerang.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Makin banyak resource yang dapat diakses web, makin banyak jalur yang dapat dieksploitasi oleh calon penyerang. Kurangi jumlah file ini seminimal mungkin.
Menyertakan kebijakan keamanan konten eksplisit
Sertakan kebijakan keamanan konten untuk ekstensi dalam manifes guna mencegah serangan scripting lintas situs. Jika ekstensi hanya memuat resource dari dirinya sendiri, daftarkan hal berikut:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self'"
"manifest_version": 2
}
Jika ekstensi perlu menyertakan skrip dari host tertentu, skrip tersebut dapat disertakan:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self' https://extension.resource.com"
"manifest_version": 2
}
Hindari API yang dapat dieksekusi
API yang menjalankan kode harus diganti dengan alternatif yang lebih aman.
document.write() dan innerHTML
Meskipun lebih mudah membuat elemen HTML secara dinamis dengan document.write() dan innerHTML,
hal ini membuat ekstensi, dan halaman web yang bergantung pada ekstensi tersebut, rentan terhadap penyisipan
skrip berbahaya oleh penyerang. Sebagai gantinya, buat node DOM secara manual dan gunakan innerText untuk menyisipkan konten dinamis.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
eval()
Hindari penggunaan eval() jika memungkinkan untuk mencegah serangan, karena eval() akan mengeksekusi kode apa pun yang diteruskan ke dalamnya, yang mungkin berbahaya.
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// WARNING! Might be evaluating an evil script!
var resp = eval("(" + xhr.responseText + ")");
...
}
}
xhr.send();
Sebagai gantinya, pilih metode yang lebih aman dan lebih cepat, seperti JSON.parse()
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();
Menggunakan skrip konten dengan hati-hati
Meskipun berada di dunia terisolasi, skrip konten tidak kebal dari serangan:
- Skrip konten adalah satu-satunya bagian ekstensi yang berinteraksi langsung dengan halaman web. Oleh karena itu, halaman web yang berbahaya dapat memanipulasi bagian DOM yang bergantung pada skrip konten, atau mengeksploitasi perilaku standar web yang tidak terduga, seperti item bernama.
- Untuk berinteraksi dengan DOM halaman web, skrip konten harus dijalankan dalam proses perender yang sama dengan halaman web. Hal ini membuat skrip konten rentan terhadap kebocoran data melalui serangan saluran samping (misalnya, Spectre), dan dapat diambil alih oleh penyerang jika halaman web berbahaya membahayakan proses perender.
Tugas sensitif harus dilakukan dalam proses khusus, seperti skrip latar belakang ekstensi. Hindari pemaparan hak istimewa ekstensi secara tidak sengaja ke skrip konten:
- Asumsikan bahwa pesan dari skrip konten mungkin telah dibuat oleh penyerang (misalnya, validasi dan bersihkan semua input dan lindungi skrip Anda dari cross-site scripting).
- Asumsikan bahwa data apa pun yang dikirim ke skrip konten mungkin bocor ke halaman web. Jangan mengirim data sensitif (misalnya, rahasia dari ekstensi, data dari origin web lain, histori penjelajahan) ke skrip konten.
- Membatasi cakupan tindakan istimewa yang dapat dipicu oleh skrip konten. Jangan izinkan
skrip konten memicu permintaan ke URL arbitrer atau meneruskan argumen arbitrer ke
API ekstensi (misalnya, jangan izinkan penerusan URL arbitrer ke API
fetchatauchrome.tabs.create).
Mendaftarkan dan membersihkan input
Lindungi ekstensi dari skrip berbahaya dengan membatasi pemroses hanya pada apa yang diharapkan ekstensi, memvalidasi pengirim data masuk, dan membersihkan semua input.
Ekstensi hanya boleh mendaftar untuk runtime.onRequestExternal, jika mengharapkan
komunikasi dari situs atau ekstensi eksternal. Selalu validasi bahwa pengirim cocok dengan sumber tepercaya.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Bahkan pesan melalui peristiwa runtime.onMessage dari ekstensi itu sendiri harus diperiksa untuk memastikan MessageSender bukan berasal dari skrip konten yang disusupi.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});
Mencegah ekstensi menjalankan skrip penyerang dengan membersihkan input pengguna dan data masuk, bahkan dari ekstensi itu sendiri dan sumber yang disetujui. Hindari API yang dapat dieksekusi.
function sanitizeInput(input) {
return input.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}