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 perlindungan penggunanya dengan menyertakan praktik ini.
Melindungi akun developer
Kode ekstensi diupload dan diperbarui melalui Akun Google. Jika akun developer diretas, penyerang dapat mengirimkan kode berbahaya langsung ke semua pengguna. Lindungi akun ini dengan membuat akun developer secara khusus dan mengaktifkan autentikasi 2 langkah, sebaiknya dengan kunci keamanan .
Membuat grup tetap selektif
Jika menggunakan penayangan grup, pastikan grup hanya berisi developer tepercaya. Jangan terima permintaan keanggotaan dari orang yang tidak dikenal.
Jangan pernah gunakan HTTP, Selalu
Saat meminta atau mengirim data, hindari koneksi HTTP. Asumsikan bahwa setiap koneksi HTTP akan memiliki penyadap atau berisi modifikasi. HTTPS harus selalu diutamakan, karena HTTPS memiliki layanan bawaan keamanan yang menghindari sebagian besar serangan man in the middle.
Meminta izin minimal
Browser Chrome membatasi akses ekstensi ke hak istimewa yang telah diminta secara eksplisit di manifes. Ekstensi harus meminimalkan izinnya dengan hanya mendaftarkan API dan {i>website<i} yang mereka andalkan. 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 domainnya sendiri dan dari domainnya yang ditentukan dalam izin akses.
{
"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
disusupi, namun ekstensi hanya memiliki izin untuk berinteraksi dengan situs web yang memenuhi
pola yang cocok. Penyerang tidak akan dapat mengakses "https://user_bank_info.com"
atau
berinteraksi dengan "https://malicious_website.com"
.
Membatasi kolom manifes
Menyertakan pendaftaran yang tidak diperlukan dalam manifes akan menciptakan kerentanan dan membuat ekstensi terlihat. Batasi kolom manifes ke kolom yang digunakan ekstensi dan berikan pendaftaran kolom tertentu.
Dapat dihubungkan secara eksternal
Gunakan kolom externally_connectable
untuk mendeklarasikan ekstensi eksternal dan halaman web yang akan menjadi tujuan pertukaran informasi ekstensi. Batasi kepada siapa ekstensi dapat terhubung secara eksternal
ke sumber tepercaya.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Referensi yang dapat diakses dari web
Membuat materi dapat diakses oleh web, di bagian web_accessible_resources
akan membuat
ekstensi yang dapat dideteksi oleh
situs web dan penyerang.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Makin banyak resource yang dapat diakses web, makin banyak peluang yang dapat dieksploitasi oleh calon penyerang. Pertahankan file ini seminimal mungkin.
Menyertakan kebijakan keamanan konten vulgar
Sertakan kebijakan keamanan konten untuk ekstensi dalam manifes guna mencegah serangan pembuatan skrip lintas situs. Jika ekstensi hanya memuat resource dari halaman itu 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
}
Menghindari API yang dapat dieksekusi
API yang mengeksekusi kode harus diganti dengan alternatif yang lebih aman.
document.write() dan innerHTML
Meskipun mungkin lebih mudah untuk membuat elemen HTML secara dinamis dengan document.write()
dan innerHTML
,
ekstensi akan meninggalkan ekstensi, dan laman web yang
ditempatkan oleh ekstensi, terbuka bagi penyerang yang memasukkan
skrip berbahaya. 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 menjalankan 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 skrip konten berada di dunia yang terisolasi, skrip tersebut tidak kebal terhadap serangan:
- Skrip konten adalah satu-satunya bagian dari ekstensi yang berinteraksi langsung dengan halaman web. Karena itu, laman web yang berbahaya dapat memanipulasi bagian DOM yang menjadi tempat bergantung skrip konten, atau mengeksploitasi perilaku standar web yang mengejutkan, 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 channel samping (mis., Spectre), dan diambil alih oleh penyerang jika halaman web berbahaya membahayakan proses perender.
Pekerjaan sensitif harus dilakukan dalam proses khusus, seperti latar belakang ekstensi skrip. Hindari mengekspos hak istimewa ekstensi secara tidak sengaja ke skrip konten:
- Mengasumsikan bahwa pesan dari skrip konten mungkin dibuat oleh penyerang (mis. memvalidasi dan membersihkan semua input dan melindungi skrip Anda dari pembuatan skrip lintas situs).
- Asumsikan data apa pun yang dikirim ke skrip konten dapat bocor ke halaman web. Jangan kirim data sensitif (misalnya rahasia dari ekstensi, data dari origin web lain, histori penjelajahan) ke konten skrip.
- Batasi cakupan tindakan dengan hak istimewa yang dapat dipicu oleh skrip konten. Jangan izinkan
skrip konten untuk memicu permintaan ke URL arbitrer atau meneruskan argumen arbitrer ke
API ekstensi (misalnya, jangan izinkan penerusan URL arbitrer ke
fetch
atauchrome.tabs.create
API).
Mendaftarkan dan membersihkan input
Lindungi ekstensi dari skrip berbahaya dengan membatasi pemroses hanya pada hal yang diharapkan ekstensi, memvalidasi pengirim data yang 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 memastikan MessageSender tidak berasal dari skrip konten yang disusupi.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});
Cegah ekstensi agar tidak mengeksekusi skrip penyerang dengan membersihkan input pengguna dan input data, 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, '"');
}