Ekstensi memiliki akses ke hak istimewa khusus 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 menerapkan praktik ini.
Melindungi akun developer
Kode ekstensi diupload dan diperbarui melalui Akun Google. Jika akun pengembang 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 .
Buat grup tetap selektif
Jika menggunakan publikasi grup, pastikan grup tetap terbatas untuk developer tepercaya. Jangan terima permintaan keanggotaan dari orang yang tidak dikenal.
Jangan pernah gunakan HTTP
Saat meminta atau mengirim data, hindari koneksi HTTP. Asumsikan bahwa setiap koneksi HTTP akan memiliki penyadap atau berisi modifikasi. HTTPS harus selalu diutamakan, karena memiliki keamanan bawaan yang mengakali 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 izin 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 ekstensi itu 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 saja di developer.chrome.com dan subdomain Google dengan
mencantumkan "/*"
dan "https://*google.com/"
dalam izin. Jika ekstensi disusupi, ekstensi hanya akan 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 diperlukan dalam manifes akan menciptakan kerentanan dan membuat ekstensi lebih terlihat. Batasi kolom manifes ke kolom yang diandalkan ekstensi dan berikan pendaftaran kolom spesifik.
Dapat dihubungkan secara eksternal
Gunakan kolom externally_connectable
untuk mendeklarasikan dengan ekstensi dan halaman web mana ekstensi akan bertukar informasi. Membatasi orang-orang yang dapat terhubung secara eksternal dengan ekstensi ke sumber tepercaya.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Resource yang dapat diakses melalui web
Dengan menjadikan resource dapat diakses oleh web, di bagian web_accessible_resources
, ekstensi akan dapat dideteksi oleh situs dan penyerang.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Semakin banyak sumber daya yang dapat diakses melalui web, semakin banyak peluang yang dapat dieksploitasi oleh penyerang. Minimalkan file-file ini.
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 ekstensi itu sendiri, daftarkan resource 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 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
,
hal ini membiarkan ekstensi, dan halaman web yang diandalkan ekstensi, terbuka bagi penyerang yang menyisipkan
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()
Jika memungkinkan, hindari penggunaan eval()
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();
Gunakan skrip konten dengan hati-hati
Meskipun skrip konten ada di dunia yang terisolasi, skrip tersebut 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-bagian DOM yang menjadi dependensi 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 saluran samping (misalnya, Spectre), dan diambil alih oleh penyerang jika halaman web berbahaya mengganggu proses perender.
Pekerjaan yang sensitif harus dilakukan dalam proses khusus, seperti skrip latar belakang ekstensi. Hindari mengekspos hak istimewa ekstensi secara tidak sengaja ke skrip konten:
- Asumsikan bahwa pesan dari skrip konten mungkin telah dibuat oleh penyerang (mis. memvalidasi dan membersihkan semua input dan melindungi skrip Anda dari pembuatan skrip lintas situs).
- Asumsikan bahwa data yang dikirim ke skrip konten mungkin bocor ke halaman web. Jangan kirim data sensitif (mis. rahasia dari ekstensi, data dari asal web lain, histori penjelajahan) ke skrip konten.
- 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 hanya membatasi pemroses ke hal yang diharapkan oleh ekstensi, memvalidasi pengirim data yang masuk, dan membersihkan semua input.
Ekstensi hanya boleh didaftarkan ke 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 diteliti untuk memastikan MessageSender bukan 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 menjalankan skrip penyerang dengan membersihkan input pengguna dan data yang 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, '"');
}