Rozszerzenia mają dostęp do specjalnych uprawnień w przeglądarce, dzięki czemu są idealnym celem ataków. Jeśli rozszerzenie zostanie naruszone, każdy użytkownik tego rozszerzenia stanie się podatny na złośliwe i niechciane wtargnięcia. Aby zapewnić bezpieczeństwo rozszerzenia i jego użytkowników, stosuj te praktyki.
Ochrona kont deweloperów
Kod rozszerzenia jest przesyłany i aktualizowany przy użyciu kont Google. Jeśli konta deweloperów zostaną naruszone, 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.
Zachowaj grupy selektywnie
Jeśli korzystasz z publikowania grupowego, ogranicz grupę do zaufanych programistów. Nie akceptuj próśb o dołączenie od nieznanych osób.
Nigdy nie używaj HTTP
Podczas wysyłania lub odbierania danych nie używaj połączenia HTTP. Zakładaj, że wszystkie połączenia HTTP będą zawierać podsłuchi lub modyfikacje. Należy zawsze preferować protokół HTTPS, ponieważ ma on wbudowane zabezpieczenia, które zapobiegają większości ataków typu „man in the middle”.
Poproś o minimalne uprawnienia
Przeglądarka Chrome ogranicza dostęp rozszerzenia do uprawnień, które zostały wyraźnie wymagane w manifest. Rozszerzenia powinny minimalizować uprawnienia, rejestrując tylko interfejsy API i strony internetowe, od których zależą.
Ograniczenie uprawnień rozszerzenia ogranicza możliwości potencjalnego atakującego.
Pobieranie z innej domeny
Rozszerzenie może używać tylko uprawnień fetch()
i XMLHttpRequest()
do uzyskiwania zasobów z rozszerzenia i z domen określonych w uprawnieniach. Pamiętaj, że wywołania obu tych metod są przechwytywane przez obsługę funkcji fetch w usługach pracujących w tle.
{
"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 wymaga dostępu do wszystkich stron na developer.chrome.com i w subdomenach Google, dodając w uprawnieniach uprawnienia "https://developer.chrome.com/*"
i "https://*.google.com/*"
. Nawet jeśli rozszerzenie zostanie naruszone, będzie mieć uprawnienia tylko do interakcji z witrynami, które spełniają wzorzec dopasowania. Atakujący będzie miał ograniczone możliwości dostępu do "https://user_bank_info.com"
lub interakcji z "https://malicious_website.com"
.
Ograniczanie pól pliku manifestu
Dodanie do pliku manifestu niepotrzebnych kluczy i uprawnień powoduje powstanie luk w zabezpieczeniach i zwiększa widoczność rozszerzenia. Ogranicz pola pliku manifestu do tych, których używa rozszerzenie.
można połączyć zewnętrznie.
W polu "externally_connectable"
możesz zadeklarować, z którymi rozszerzeniami zewnętrznymi i stronami internetowymi rozszerzenie będzie wymieniać informacje. Ogranicz, z jakimi zaufowanymi źródłami zewnętrznymi rozszerzenie może się łączyć.
{
"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ępnianie zasobów w internecie w ramach "web_accessible_resources"
spowoduje, że rozszerzenie będzie wykrywalne przez witryny i atakujących.
{
...
"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
Aby zapobiec atakom typu cross-site scripting, uwzględnij w pliku manifestu politykę bezpieczeństwa treści dla rozszerzenia. Jeśli rozszerzenie wczytuje tylko zasoby z samego siebie, zarejestruj te informacje:
{
"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ć pakietu internetowego lub zwiększać ograniczenia dotyczące stron w piaskownicy, możesz 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
Chociaż dynamiczne tworzenie elementów HTML za pomocą metod document.write()
i innerHTML
może być łatwiejsze, pozostawi to rozszerzenie i strony, od których zależy to rozszerzenie, otwarte na wstawianie złośliwych skryptów. Zamiast tego musisz ręcznie utworzyć węzły DOM i używać interfejsu innerText
do wstawiania treści dynamicznych.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
Ostrożnie korzystaj ze skryptów treści
Chociaż skrypty treści działają w odizolowanym środowisku, nie są odporne na ataki:
- Skrypty treści to jedyna część rozszerzenia, która bezpośrednio oddziałuje na stronę internetową. W związku z tym strony internetowe mogą manipulować częściami DOM, od których zależy skrypt treści, lub wykorzystywać zaskakujące standardowe zachowania internetowe, takie jak elementy o nazwie.
- Aby wchodzić w interakcję z modelem DOM stron internetowych, skrypty treści muszą być wykonywane w tym samym procesie renderowania co strona internetowa. Skrypty treści są wtedy podatne na wyciek danych w ramach ataków typu side-channel (np. Spectre) oraz przejęcia kontroli przez atakującego, jeśli złośliwa strona internetowa skompromituje proces mechanizmu renderowania.
Operacje korzystające z danych wrażliwych (np. prywatnych informacji o użytkowniku) lub interfejsów API Chrome z dostępem do funkcji przeglądarki powinny być wykonywane w workerze usługi rozszerzeń. Aby uniknąć przypadkowego udostępniania uprawnień rozszerzenia skryptom treści:
- Zakładaj, że wiadomości ze skryptu treści mogły zostać spreparowane przez atakującego (np. sprawdź i oczyść wszystkie dane wejściowe oraz chroń skrypty przed skryptami międzywitrynowymi).
- Zakładamy, że wszystkie dane wysyłane do skryptu treści mogą wyciec na stronę internetową. Nie wysyłaj danych wrażliwych (np. obiektów tajnych z rozszerzenia, danych z innych źródeł, historii przeglądania) do skryptów treści.
- Ogranicz zakres działań z podwyższonymi uprawnieniami, które mogą być wywoływane przez skrypty treści. Nie zezwalaj skryptom treści na wywoływanie żądań do dowolnych adresów URL ani przekazywanie dowolnych argumentów do interfejsów API rozszerzeń (np. nie zezwalaj na przekazywanie dowolnych adresów URL do metod
fetch()
lubchrome.tabs.create()
).
Rejestrowanie i oczyszczanie danych wejściowych
Chroń rozszerzenie przed złośliwymi skryptami, ograniczając odbiorców do tych, których oczekuje rozszerzenie, weryfikując nadawców przychodzących danych i oczyszczając wszystkie dane wejściowe.
Rozszerzenie powinno rejestrować runtime.onMessageExternal
tylko wtedy, gdy oczekuje komunikacji z zewnętrznej witryny lub rozszerzenia. Zawsze sprawdzaj, czy nadawca jest zaufanym źródłem.
// 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 przesyłane za pomocą zdarzenia runtime.onMessage z samej wtyczki powinny być dokładnie sprawdzane, aby mieć pewność, że MessageSender nie pochodzi z uszkodzonego skryptu treści.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});