Erweiterungen haben Zugriff auf spezielle Berechtigungen im Browser, was sie zu einem attraktiven Ziel für Angreifer macht. Wenn eine Erweiterung manipuliert wird, ist jeder Nutzer dieser Erweiterung anfällig für böswillige und unerwünschte Eingriffe. Wenn Sie diese Empfehlungen berücksichtigen, können Sie Erweiterungen und ihre Nutzer schützen.
Entwicklerkonten schützen
Erweiterungscode wird über Google-Konten hochgeladen und aktualisiert. Wenn die Konten von Entwicklern manipuliert werden, kann ein Angreifer schädlichen Code direkt an alle Nutzer senden. Schützen Sie diese Konten, indem Sie die 2‑Faktor-Authentifizierung aktivieren, vorzugsweise mit einem Sicherheitsschlüssel.
Geeignete Mitgliedsrollen verwenden
Wenn Ihr Verlag oder Webpublisher mehrere Mitglieder hat, prüfen Sie, ob die Rolle, die jedem Nutzer zugewiesen ist, angemessen ist.
Nie HTTP verwenden
Vermeiden Sie beim Anfordern oder Senden von Daten eine HTTP-Verbindung. Gehen Sie davon aus, dass HTTP-Verbindungen abgehört werden oder Änderungen enthalten. HTTPS sollte immer bevorzugt werden, da es integrierte Sicherheitsfunktionen hat, die die meisten Man-in-the-Middle-Angriffe verhindern.
Mindestberechtigungen anfordern
Der Chrome-Browser beschränkt den Zugriff einer Erweiterung auf Berechtigungen, die explizit im Manifest angefordert wurden. Erweiterungen sollten ihre Berechtigungen minimieren, indem sie nur APIs und Websites registrieren, von denen sie abhängig sind.
Wenn Sie die Berechtigungen einer Erweiterung einschränken, begrenzen Sie auch, was ein potenzieller Angreifer ausnutzen kann.
Cross-Origin-Fetch()
Eine Erweiterung kann nur fetch() und XMLHttpRequest() verwenden, um Ressourcen aus der Erweiterung und aus in den Berechtigungen angegebenen Domains abzurufen. Beachten Sie, dass Aufrufe an beide vom fetch-Handler im Service Worker abgefangen werden.
{
"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
}
Die Erweiterung im obigen Beispiel fordert Zugriff auf alles auf developer.chrome.com und Subdomains von Google an, indem "https://developer.chrome.com/*" und "https://*.google.com/*" in den Berechtigungen aufgeführt werden. Wenn die Erweiterung manipuliert würde, hätte sie trotzdem nur die Berechtigung, mit Websites zu interagieren, die dem Muster für den Abgleich entsprechen. Der Angreifer hätte nur eingeschränkten Zugriff auf "https://user_bank_info.com" oder könnte nur eingeschränkt mit "https://malicious_website.com" interagieren.
Manifestfelder einschränken
Wenn Sie unnötige Schlüssel und Berechtigungen in das Manifest aufnehmen, entstehen Sicherheitslücken und die Erweiterung wird sichtbarer. Beschränken Sie die Manifestfelder auf die Felder, auf die sich die Erweiterung stützt.
Extern verbindbar
Verwenden Sie das Feld "externally_connectable", um anzugeben, mit welchen externen Erweiterungen und Webseiten die Erweiterung Informationen austauschen soll. Einschränken, mit wem die Erweiterung extern eine Verbindung zu vertrauenswürdigen Quellen herstellen kann.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
Webressourcen
Wenn Ressourcen über das Web unter "web_accessible_resources" zugänglich gemacht werden, kann eine Erweiterung von Websites und Angreifern erkannt werden.
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
Je mehr webzugängliche Ressourcen verfügbar sind, desto mehr Möglichkeiten hat ein potenzieller Angreifer, diese auszunutzen. Halten Sie die Anzahl dieser Dateien so gering wie möglich.
Explizite Content Security Policy einfügen
Fügen Sie dem Manifest eine Content Security Policy für die Erweiterung hinzu, um Cross-Site-Scripting-Angriffe zu verhindern. Wenn die Erweiterung nur Ressourcen aus sich selbst lädt, registrieren Sie Folgendes:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
Wenn die Erweiterung WebAssembly verwenden oder die Einschränkungen für Sandbox-Seiten erhöhen muss, können sie hinzugefügt werden:
{
"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
}
„document.write()“ und „innerHTML“ vermeiden
Es ist zwar einfacher, HTML-Elemente dynamisch mit document.write() und innerHTML zu erstellen, aber dadurch können Angreifer schädliche Skripts in die Erweiterung und die Webseiten, von denen die Erweiterung abhängt, einfügen. Erstellen Sie stattdessen DOM-Knoten manuell und verwenden Sie innerText, um dynamische Inhalte einzufügen.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
Inhalts-Scripts mit Bedacht verwenden
Content-Scripts werden zwar in einer isolierten Welt ausgeführt, sind aber nicht vor Angriffen geschützt:
- Inhaltsskripte sind der einzige Teil einer Erweiterung, der direkt mit der Webseite interagiert. Aus diesem Grund können schädliche Webseiten Teile des DOM manipulieren, von denen das Content-Script abhängt, oder überraschendes Verhalten von Webstandards wie benannte Elemente ausnutzen.
- Damit Content-Scripts mit dem DOM von Webseiten interagieren können, müssen sie im selben Renderer-Prozess wie die Webseite ausgeführt werden. Dadurch sind Content-Scripts anfällig für Datenlecks über Seitenkanalangriffe (z.B. Spectre) und für die Übernahme durch einen Angreifer, wenn eine schädliche Webseite den Renderer-Prozess kompromittiert.
Vorgänge, bei denen vertrauliche Daten (z. B. private Informationen eines Nutzers) oder Chrome-APIs mit Zugriff auf die Funktionen des Browsers verwendet werden, sollten im Service Worker der Erweiterung ausgeführt werden. So vermeiden Sie, dass Erweiterungsberechtigungen versehentlich für Inhaltsskripte freigegeben werden:
- Gehen Sie davon aus, dass Nachrichten von einem Content-Script von einem Angreifer stammen könnten. Validieren und bereinigen Sie daher alle Eingaben und schützen Sie Ihre Scripts vor Cross-Site-Scripting.
- Gehen Sie davon aus, dass alle Daten, die an das Inhaltsscript gesendet werden, an die Webseite weitergegeben werden könnten. Senden Sie keine sensiblen Daten (z.B. Secrets aus der Erweiterung, Daten aus anderen Webursprüngen, Browserverlauf) an Content-Scripts.
- Beschränken Sie den Umfang privilegierter Aktionen, die durch Inhaltsskripts ausgelöst werden können. Content-Scripts dürfen keine Anfragen an beliebige URLs auslösen oder beliebige Argumente an Erweiterungs-APIs übergeben (z.B. dürfen keine beliebigen URLs an die Methoden
fetch()oderbrowser.tabs.create()übergeben werden).
Eingaben registrieren und bereinigen
Schützen Sie eine Erweiterung vor schädlichen Skripts, indem Sie Listener auf das beschränken, was die Erweiterung erwartet, die Absender eingehender Daten validieren und alle Eingaben bereinigen.
Eine Erweiterung sollte sich nur für runtime.onMessageExternal registrieren, wenn sie mit einer externen Website oder Erweiterung kommunizieren möchte. Prüfen Sie immer, ob der Absender mit einer vertrauenswürdigen Quelle übereinstimmt.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
browser.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Auch Nachrichten über das runtime.onMessage-Ereignis von der Erweiterung selbst sollten geprüft werden, um sicherzustellen, dass der MessageSender nicht von einem manipulierten Inhaltsscript stammt.
browser.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});