Das Erweiterungssystem von Chrome erzwingt eine relativ strikte standardmäßige Content Security Policy (CSP).
Die Richtlinieneinschränkungen sind einfach: Das Skript muss in separate
JavaScript-Dateien müssen Inline-Event-Handler zur Verwendung von addEventListener
konvertiert werden und eval()
ist
deaktiviert. Chrome-Apps haben noch strengere Richtlinien und wir sind mit der Sicherheit sehr zufrieden
Eigenschaften dieser Richtlinien.
Wir wissen jedoch, dass eine Vielzahl von Bibliotheken eval()
- und eval
-ähnliche Konstrukte verwendet, z. B.:
new Function()
für die Leistungsoptimierung und einen einfachen Ausdruck. Vorlagenbibliotheken sind
besonders anfällig für diese Art der Implementierung. Einige, wie z. B. Angular.js, unterstützen CSP auswärts.
viele gängige Frameworks noch nicht auf einen Mechanismus aktualisiert, der mit
Erweiterungen Welt mit weniger als eval
. Es hat sich daher als besser erwiesen, dass diese Funktion nicht mehr unterstützt wird.
problematisch als erwartet.
In diesem Dokument wird die sichere Sandbox-Technologie vorgestellt, mit der Sie diese Bibliotheken in Ihre Projekte einbinden können. ohne Abstriche bei der Sicherheit machen zu müssen. Der Einfachheit halber verwenden wir durchgehend Erweiterungen, aber gilt das Konzept gleichermaßen für Anwendungen.
Warum Sandbox?
eval
ist innerhalb einer Erweiterung gefährlich, da der von ihm ausgeführte Code Zugriff auf alles im
Erweiterung mit umfangreichen Berechtigungen. Es stehen zahlreiche leistungsstarke chrome.*
APIs zur Verfügung, die
die Sicherheit und den Datenschutz eines Nutzers erheblich beeinträchtigen; Eine einfache Daten-Exfiltration ist für uns am wenigsten sorgen.
Die angebotene Lösung ist eine Sandbox, in der eval
Code ausführen kann, ohne auf den
die Daten der Erweiterung
oder die hochwertigen APIs der Erweiterung. Keine Daten, keine APIs – kein Problem.
Dies erreichen wir, indem wir bestimmte HTML-Dateien im Erweiterungspaket als Sandbox-Technologie auflisten.
Wenn eine in einer Sandbox ausgeführte Seite geladen wird, wird sie an einen eindeutigen Ursprung verschoben und abgelehnt.
Zugriff auf chrome.*
APIs Wenn wir diese in einer Sandbox ausgeführte Seite über iframe
in unsere Erweiterung laden,
kann es die Nachrichten weiterleiten, es auf diese Nachrichten reagieren und darauf warten, dass es uns ein
Ergebnis. Dieser einfache Nachrichtenmechanismus gibt uns alles, was wir brauchen, um eval
-gesteuerte
im Workflow unserer Erweiterung.
Sandbox erstellen und verwenden
Wenn Sie direkt in den Code einsteigen möchten, holen Sie sich die Sandboxing-Beispielerweiterung deaktiviert. Es ist ein funktionierendes Beispiel für eine winzige Messaging-API, die auf dem Handlebars basiert. Vorlagenbibliothek, die Ihnen alles bietet, was Sie für den Einstieg brauchen. Für diejenigen unter Ihnen, die Erklären, sehen wir uns das Beispiel hier gemeinsam an.
Dateien im Manifest auflisten
Jede Datei, die in einer Sandbox ausgeführt werden soll, muss im Erweiterungsmanifest durch Hinzufügen eines
sandbox
-Property. Dies ist ein wichtiger Schritt, der leicht vergessen wird. Überprüfen Sie daher,
die in der Sandbox ausgeführte Datei im Manifest aufgeführt ist. In diesem Beispiel wird die Datei geschickt in einer Sandbox ausgeführt.
namens "sandbox.html". Der Manifesteintrag sieht so aus:
{
...,
"sandbox": {
"pages": ["sandbox.html"]
},
...
}
In der Sandbox ausgeführte Datei laden
Um mit der in der Sandbox ausgeführten Datei etwas Interessantes zu tun, müssen wir sie in einem Kontext laden, in dem
kann der Code der Erweiterung berücksichtigt werden. Hier wurde sandbox.html in den
Ereignisseite (eventpage.html) der Erweiterung über iframe
. eventpage.js enthält Code.
, die jedes Mal, wenn auf die Browseraktion geklickt wird, eine Nachricht an die Sandbox sendet, indem das iframe
-Objekt gesucht wird.
auf der Seite und führen die postMessage
-Methode auf der entsprechenden contentWindow
aus. Die Nachricht ist ein Objekt
mit zwei Eigenschaften: context
und command
. Wir sehen uns beides gleich an.
chrome.browserAction.onClicked.addListener(function() {
var iframe = document.getElementById('theFrame');
var message = {
command: 'render',
context: {thing: 'world'}
};
iframe.contentWindow.postMessage(message, '*');
});
postMessage
API findest du in der postMessage
-Dokumentation auf MDN . Sie ist ziemlich vollständig und lesenswert. Beachten Sie insbesondere, dass Daten nur dann hin- und hergeleitet werden können, wenn sie serialisierbar sind. Funktionen hingegen nicht.Etwas Gefährliches tun
Wenn sandbox.html
geladen wird, wird die Handlebars-Bibliothek geladen und eine Inline erstellt und kompiliert.
wie in Handlebars vorschlägt:
<script src="handlebars-1.0.0.beta.6.js"></script>
<script id="hello-world-template" type="text/x-handlebars-template">
<div class="entry">
<h1>Hello, !</h1>
</div>
</script>
<script>
var templates = [];
var source = document.getElementById('hello-world-template').innerHTML;
templates['hello'] = Handlebars.compile(source);
</script>
Das scheitert nicht! Handlebars.compile
verwendet zwar letztendlich new Function
, aber es funktioniert
und wir haben eine kompilierte Vorlage in templates['hello']
.
Ergebnis zurückgeben
Wir stellen diese Vorlage zur Verwendung zur Verfügung, indem wir einen Nachrichten-Listener einrichten, der Befehle akzeptiert
aus der Ereignisseite aus. Anhand der übergebenen command
bestimmen wir, was zu tun ist. Sie können
Stellen Sie sich vor, Sie würden mehr tun,
als nur Rendering. vielleicht Vorlagen erstellen? Vielleicht verwalten Sie sie in einigen
und die context
wird zum Rendern direkt an die Vorlage übergeben. Der gerenderte HTML-Code
an die Ereignisseite zurück, damit die Erweiterung später sinnvolle Aktionen durchführen kann:
<script>
window.addEventListener('message', function(event) {
var command = event.data.command;
var name = event.data.name || 'hello';
switch(command) {
case 'render':
event.source.postMessage({
name: name,
html: templates[name](event.data.context)
}, event.origin);
break;
// case 'somethingElse':
// ...
}
});
</script>
Auf der Veranstaltungsseite erhalten wir diese Nachricht und verwenden html
etwas Interessantes.
die uns übergeben wurden. In diesem Fall geben wir sie in einer Desktop-Benachrichtigung wieder, aber
kann dieser HTML-Code sicher als Teil der Benutzeroberfläche der Erweiterung verwendet werden. Einfügen über
innerHTML
stellt kein erhebliches Sicherheitsrisiko dar, da selbst ein vollständiger Kompromittierung der Sandbox
durch einige clevere Angriffe keine gefährlichen Skript- oder Plug-in-Inhalte
den Kontext der Erweiterung mit
hohen Berechtigungen.
Dieser Mechanismus erleichtert das Erstellen von Vorlagen, ist aber natürlich nicht auf Vorlagen beschränkt. Beliebig Code, der gemäß einer strengen Content Security Policy nicht sofort funktioniert, kann in einer Sandbox ausgeführt werden. in Es ist oft nützlich, die Komponenten der Erweiterungen in einer Sandbox auszuführen, die korrekt ausgeführt werden. jedes Teil Ihres Programms auf die kleinstmöglichen Berechtigungen zu beschränken, die erforderlich sind, ordnungsgemäß ausführen. Google-Präsentation Write Secure Web Apps and Chrome Extensions Auf der I/O 2012 finden Sie einige gute Beispiele für diese Techniken in der Praxis. .