Rozszerzenia mają dostęp do specjalnych uprawnień w przeglądarce, co czyni je atrakcyjnym celem dla atakujących. Jeśli rozszerzenie zostanie przejęte, każdy użytkownik tego rozszerzenia staje się podatny na złośliwe i niechciane wtargnięcia. Zadbaj o bezpieczeństwo rozszerzenia i ochronę jego użytkowników, stosując te praktyki.
Ochrona kont deweloperów
Kod rozszerzenia jest przesyłany i aktualizowany za pomocą kont Google. Jeśli konta deweloperów zostaną przejęte, atakujący może przesłać złośliwy kod bezpośrednio do wszystkich użytkowników. Chroń te konta, włączając uwierzytelnianie dwuskładnikowe, najlepiej za pomocą klucza bezpieczeństwa.
Używanie odpowiednich ról członków
Jeśli wydawca ma wielu członków, sprawdź, czy rola przyznana każdemu użytkownikowi jest odpowiednia.
Nigdy nie używaj HTTP
Podczas wysyłania danych lub przesyłania próśb o nie unikaj połączenia HTTP. Załóż, że połączenia HTTP będą podsłuchiwane lub modyfikowane. Zawsze należy preferować protokół HTTPS, ponieważ ma on wbudowane zabezpieczenia, które pozwalają uniknąć większości ataków typu „man in the middle”.
Prośba o minimalne uprawnienia
Przeglądarka Chrome ogranicza dostęp rozszerzenia do uprawnień, o które wyraźnie poproszono w pliku manifestu. Rozszerzenia powinny ograniczać swoje uprawnienia, rejestrując tylko interfejsy API i strony, od których są zależne.
Ograniczenie uprawnień rozszerzenia ogranicza możliwości potencjalnego atakującego.
Pobieranie z innej domeny
Rozszerzenie może używać tylko fetch() i XMLHttpRequest(), aby pobierać zasoby z rozszerzenia i z domen określonych w uprawnieniach. Pamiętaj, że wywołania obu funkcji są przechwytywane przez moduł obsługi fetch w skrypcie service worker.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"host_permissions": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"manifest_version": 3
}
To rozszerzenie w przykładzie powyżej żąda dostępu do wszystkiego w domenie developer.chrome.com i subdomenach Google, ponieważ w uprawnieniach wymieniono "https://developer.chrome.com/*" i "https://*.google.com/*". Jeśli rozszerzenie zostanie przejęte, nadal będzie miało uprawnienia tylko do interakcji ze stronami internetowymi, które spełniają wzorzec dopasowania. Atakujący miałby ograniczoną możliwość dostępu do "https://user_bank_info.com" lub interakcji z "https://malicious_website.com".
Ograniczanie pól pliku manifestu
Umieszczanie w pliku manifestu niepotrzebnych kluczy i uprawnień stwarza luki w zabezpieczeniach i zwiększa widoczność rozszerzenia. Ogranicz pola pliku manifestu do tych, na których polega rozszerzenie.
Można połączyć zewnętrznie
W polu "externally_connectable" zadeklaruj, z którymi zewnętrznymi rozszerzeniami i stronami internetowymi rozszerzenie będzie wymieniać informacje. Ograniczanie możliwości łączenia się rozszerzenia ze źródłami zewnętrznymi do zaufanych źródeł.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
Zasoby dostępne w internecie
Udostępnienie zasobów w internecie w sekcji "web_accessible_resources" sprawi, że rozszerzenie będzie wykrywalne przez witryny i osoby atakujące.
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
Im więcej zasobów dostępnych w internecie, tym więcej możliwości wykorzystania przez potencjalnego atakującego. Ogranicz liczbę tych plików do minimum.
Uwzględnij zasady bezpieczeństwa treści dla pełnoletnich
W pliku manifestu rozszerzenia umieść zasady bezpieczeństwa treści, aby zapobiec atakom typu cross-site scripting. Jeśli rozszerzenie wczytuje zasoby tylko z siebie, zarejestruj te elementy:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
Jeśli rozszerzenie musi używać WebAssembly lub zwiększyć ograniczenia dotyczące stron w piaskownicy, można je dodać:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
"sandboxed_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"manifest_version": 3
}
Unikaj instrukcji document.write() i innerHTML
Dynamiczne tworzenie elementów HTML za pomocą funkcji document.write() i innerHTML może być prostsze, ale naraża rozszerzenie i strony internetowe, od których zależy, na wstawianie przez osoby atakujące złośliwych skryptów. Zamiast tego ręcznie utwórz węzły DOM i użyj innerText, aby wstawić treści dynamiczne.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
Ostrożnie korzystaj ze skryptów dotyczących zawartości
Chociaż skrypty treści działają w izolowanym środowisku, nie są odporne na ataki:
- Skrypty treści to jedyna część rozszerzenia, która wchodzi w bezpośrednią interakcję ze stroną internetową. Z tego powodu wrogie strony internetowe mogą manipulować częściami modelu DOM, od których zależy skrypt treści, lub wykorzystywać zaskakujące zachowania standardów internetowych, takie jak nazwane elementy.
- Aby skrypty treści mogły wchodzić w interakcje z modelem DOM stron internetowych, muszą być wykonywane w tym samym procesie renderowania co strona internetowa. Sprawia to, że skrypty treści są podatne na wyciek danych w wyniku ataków z użyciem kanałów bocznych (np. Spectre) i na przejęcie przez atakującego, jeśli złośliwa strona internetowa naruszy proces renderowania.
Operacje wykorzystujące dane wrażliwe (np. prywatne informacje użytkownika) lub interfejsy API Chrome z dostępem do funkcji przeglądarki powinny być wykonywane w skrypcie service worker rozszerzenia. Unikaj przypadkowego udostępniania uprawnień rozszerzenia skryptom dotyczącym zawartości:
- Załóż, że wiadomości ze skryptu treści mogły zostać przygotowane przez osobę przeprowadzającą atak (np. sprawdzaj i oczyszczaj wszystkie dane wejściowe oraz chroń skrypty przed atakiem typu cross-site scripting).
- Załóż, że wszystkie dane wysłane do skryptu treści mogą wyciec na stronę internetową. Nie wysyłaj danych wrażliwych (np. kluczy tajnych z rozszerzenia, danych z innych źródeł internetowych, historii przeglądania) do skryptów treści.
- Ograniczanie zakresu działań uprzywilejowanych, które mogą być wywoływane przez skrypty treści. Nie zezwalaj skryptom treści na wysyłanie żądań do dowolnych adresów URL ani na przekazywanie dowolnych argumentów do interfejsów API rozszerzeń (np. nie zezwalaj na przekazywanie dowolnych adresów URL do metod
fetch()anichrome.tabs.create()).
Rejestrowanie i oczyszczanie danych wejściowych
Chroń rozszerzenie przed złośliwymi skryptami, ograniczając detektory tylko do tych, których rozszerzenie oczekuje, weryfikując nadawców przychodzących danych i oczyszczając wszystkie dane wejściowe.
Rozszerzenie powinno rejestrować się w przypadku zdarzenia runtime.onMessageExternal tylko wtedy, gdy oczekuje komunikacji z zewnętrzną witryną lub rozszerzeniem. Zawsze sprawdzaj, czy nadawca pochodzi z zaufanego źródła.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Nawet wiadomości wysyłane przez zdarzenie runtime.onMessage z samego rozszerzenia powinny być dokładnie sprawdzane, aby upewnić się, że MessageSender nie pochodzi ze skompromitowanego skryptu treści.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});