Sandboxing in JavaScript: Ein tiefer Einblick
Ethan Miller
Product Engineer · Leapcell

In JavaScript ist eine Sandbox ein Sicherheitsmechanismus, der verwendet wird, um laufenden Code zu isolieren und zu verhindern, dass er unnötige Auswirkungen oder Sicherheitsrisiken für andere Teile einer Anwendung oder eines Systems verursacht. Eine Sandbox bietet eine kontrollierte Umgebung, in der Code ausgeführt werden kann, ohne die externe Umgebung zu beeinträchtigen, wodurch Benutzerdaten und Systemsicherheit geschützt werden.
In Browsern bezieht sich eine Sandbox in der Regel auf die isolierte Umgebung, die der Browser für jede Registerkarte bereitstellt. Diese Isolation stellt sicher, dass JavaScript-Code in einer Registerkarte nicht auf Inhalte in einer anderen Registerkarte zugreifen kann, es sei denn, die beiden Seiten befolgen die Same-Origin-Policy (d. h. dasselbe Protokoll, dieselbe Domäne und derselbe Port) oder erlauben explizit den ursprungsübergreifenden Zugriff über CORS (Cross-Origin Resource Sharing). Webcode muss über einen IPC-Kanal (Inter-Process Communication) mit dem Browser-Kernel-Prozess kommunizieren, und der Kommunikationsprozess wird Sicherheitsprüfungen unterzogen. Der Zweck des Sandbox-Designs besteht darin, untrusted Code in einer bestimmten Umgebung ausführen zu können, wobei der Zugriff auf Ressourcen außerhalb der Isolationszone eingeschränkt wird.
Was sind die Anwendungsfälle von Sandboxes in JavaScript?
In JavaScript werden Sandboxes typischerweise verwendet, um die Ausführungsumgebung von Code zu isolieren und zu kontrollieren, um sicherzustellen, dass er in einer sicheren und eingeschränkten Umgebung ausgeführt wird und potenzielle Schäden an der Hauptumgebung vermieden werden.
- Ausführen von JavaScript von Drittanbietern: Wenn Sie JavaScript-Code von Drittanbietern ausführen müssen, der möglicherweise nicht vertrauenswürdig ist.
- Online-Code-Editoren: Viele Online-Code-Editoren führen benutzerdefinierten Code in einer Sandbox aus, um zu verhindern, dass er die Seite selbst beeinträchtigt.
- Webanwendungssicherheit: Wenn JavaScript aus verschiedenen Quellen in einem Browser ausgeführt wird, kann eine Sandbox seine Berechtigungen einschränken und verhindern, dass bösartiger Code auf sensible Ressourcen zugreift oder gefährliche Operationen ausführt.
- Plugins und Skripte von Drittanbietern: Wenn eine Webanwendung Plugins oder Skripte von Drittanbietern laden und ausführen muss, kann eine Sandbox deren Zugriffsrechte einschränken und die Sicherheit der Hauptanwendung und ihrer Daten schützen.
- JSONP: Wenn JSONP-Antworten von einem Server geparst werden und die zurückgegebenen Daten nicht vertrauenswürdig sind, kann eine Sandbox verwendet werden, um die Daten sicher zu parsen und abzurufen.
JSONP-Kommunikationsmechanismus
Das Funktionsprinzip von JSONP basiert auf der Tatsache, dass das <script>
-Tag keine ursprungsübergreifenden Einschränkungen aufweist (ein historisches Relikt), was die Kommunikation mit Drittanbieterdiensten ermöglicht. Wenn eine Kommunikation erforderlich ist, erstellt das Skript auf der aktuellen Seite ein <script>
-Element, das auf die Drittanbieter-API-URL verweist, wie folgt:
<script src="http://www.example.net/api?param1=1¶m2=2"></script>
Eine Callback-Funktion wird bereitgestellt, um die Daten zu empfangen (der Funktionsname kann vereinbart oder über einen URL-Parameter übergeben werden). Die Antwort des Drittanbieters ist eine JSON-verpackte Antwort (daher der Begriff JSONP, was JSON-Padding bedeutet), wie z. B.:
callback({ name: 'hax', gender: 'Male' });
Dadurch ruft der Browser die callback
-Funktion auf und übergibt das geparste JSON-Objekt als Parameter. Das Skript auf der aktuellen Seite kann die empfangenen Daten innerhalb der callback
-Funktion verarbeiten.
Grundlegende Vorgehensweise zum Parsen von JSONP-Daten mithilfe einer Sandbox
- Erstellen eines isolierten iFrames als Sandbox: Erstellen Sie dynamisch einen iFrame auf der Hauptseite, um eine isolierte Ausführungsumgebung für JSONP-Anfragen bereitzustellen. Dieser iFrame hat keinen Zugriff auf das DOM der Hauptseite, wodurch die Auswirkungen des auszuführenden Codes begrenzt werden.
- Initiieren der JSONP-Anfrage innerhalb des iFrames: Fügen Sie ein
<script>
-Tag in den erstellten iFrame ein, sodass das zurückgegebene JSONP-Skript innerhalb der isolierten Umgebung ausgeführt wird. Dadurch wird sichergestellt, dass selbst wenn das zurückgegebene Skript bösartigen Code enthält, seine Auswirkungen auf den iFrame beschränkt sind und die Hauptseite nicht beeinträchtigen. - Sicheres Abrufen von Daten aus dem iFrame: Das Skript innerhalb des iFrames kann das DOM der Hauptseite nicht direkt ändern, aber es kann Daten sicher mit einer vordefinierten Methode, wie z. B. der
postMessage
-API, an die Hauptseite übertragen. Die Hauptseite sollte einen Ereignis-Listener einrichten, um diese Daten zu empfangen und gleichzeitig die Quelle zu überprüfen, um die Sicherheit zu gewährleisten. - Einschränken und Überwachen des iFrame-Verhaltens: Zu den zusätzlichen Sicherheitsmaßnahmen gehören die Verwendung von Content Security Policy (CSP), um die Ressourcen zu begrenzen, die der iFrame laden und ausführen kann, sowie die Nutzung anderer Browser-Sicherheitsfunktionen, um das iFrame-Verhalten zu überwachen und zu steuern.
Durch Befolgen dieser Schritte können potenzielle Bedrohungen effektiv isoliert und kontrolliert werden, selbst wenn die JSONP-Antwort nicht vertrauenswürdige Daten oder Code enthält, wodurch Benutzerdaten und Sicherheit geschützt werden.
Zusammenfassend lässt sich sagen, dass eine Sandbox eine entscheidende Rolle spielt, wenn Sie nicht vertrauenswürdiges JavaScript parsen oder ausführen, die Ausführungsumgebung isolieren oder den Zugriff auf bestimmte Objekte innerhalb des auszuführenden Codes einschränken müssen.
Implementieren einer Sandbox mit with
+ new Function
In JavaScript können Sie eine einfache Sandbox-Umgebung erstellen, indem Sie die Anweisung with
und new Function
verwenden. Diese Methode schränkt den Ausführungsbereich des Codes ein und verhindert, dass er auf globale Variablen zugreift oder unsichere Operationen ausführt.
Innerhalb des with
-Blockbereichs hat der Variablenzugriff Priorität auf die Eigenschaften des bereitgestellten Objekts, bevor er in der Scope-Kette weiter nach oben sucht. Dies ermöglicht effektiv die Überwachung des Variablenzugriffs innerhalb des ausgeführten Codes:
function createSandbox(code) { // Erstellen eines leeren Objekts, das als globales Objekt innerhalb der Sandbox dient const sandbox = {}; // Verwenden der with-Anweisung, um den Gültigkeitsbereich des Codes auf das leere Objekt zu setzen // Verwenden von new Function, um eine neue Funktion zu erstellen, wodurch der Codezugriff auf das Sandbox-Objekt beschränkt wird const script = new Function('sandbox', `with(sandbox) { ${code} }`); // Ausführen der Funktion und Übergeben des Sandbox-Objekts als Argument return function () { script(sandbox); }; } // Verwenden der Sandbox-Umgebung const sandboxedScript = createSandbox('console.log("Hello from the sandbox!"); var x = 10;'); sandboxedScript(); // Ausgabe: Hello from the sandbox! console.log(typeof x); // Ausgabe: undefined, weil x innerhalb der Sandbox definiert wurde und außerhalb nicht zugänglich ist
Hier definieren wir eine Funktion createSandbox
, die einen String code
als Parameter entgegennimmt. Dieser String repräsentiert den JavaScript-Code, der in der Sandbox-Umgebung ausgeführt werden muss. Zuerst erstellen wir ein leeres Objekt sandbox
, das als globales Objekt innerhalb der Sandbox dient. Dann verwenden wir die Anweisung with(sandbox)
, um die Ausführungsumgebung des Sandboxed-Codes auf dieses leere Objekt zu setzen, was bedeutet, dass alle Variablen- und Funktionsdefinitionen innerhalb der Sandbox eingeschlossen werden und nicht auf den globalen Gültigkeitsbereich zugreifen können.
Der Konstruktor new Function
erstellt eine neue Funktion, die den bereitgestellten Code-String ausführt. Dies ermöglicht es uns, JavaScript dynamisch auszuführen und gleichzeitig seinen Gültigkeitsbereich einzuschränken, wodurch verhindert wird, dass er auf die externe Umgebung zugreift oder diese verändert. Schließlich geben wir eine Closure-Funktion zurück, die bei Aufruf den Sandboxed-Code ausführt.
Einschränkungen und Sicherheitsbedenken
Obwohl diese Methode die Ausführungsumgebung bis zu einem gewissen Grad isolieren kann, ist sie nicht vollständig sicher. Die Anweisung with
und new Function
bergen Sicherheitsrisiken, insbesondere wenn der Sandboxed-Code selbst auf den Konstruktor Function
zugreifen kann, was es ihm ermöglichen könnte, die Sandbox-Beschränkungen zu umgehen und beliebigen Code auszuführen. Kurz gesagt, new Function
+ with
ist eine Sandboxing-Methode, die gutartige Benutzer abschrecken kann, aber nicht narrensicher gegen bösartige Akteure ist.
Implementieren einer Sandbox mithilfe von iframe
Die Verwendung eines iframe
zum Erstellen einer Sandbox-Umgebung ist eine gängige Technik in der Webentwicklung. Sie ermöglicht das Einbetten einer vollständig unabhängigen HTML-Seite in die aktuelle Seite, wodurch die JavaScript-Ausführung effektiv isoliert und verhindert wird, dass Skripte auf das DOM oder die JavaScript-Umgebung der Hauptseite zugreifen, wodurch die Sicherheit erhöht wird.
HTML-Struktur
Zuerst müssen wir die HTML-Struktur einrichten:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sandbox Example</title> </head> <body> <iframe id="sandbox" style="display: none"></iframe> <script src="index.js"></script> </body> </html>
JavaScript-Implementierung
In index.js
können wir die Eigenschaft contentWindow
des iframe
manipulieren, um eine einfache Sandbox-Umgebung zu erstellen. Die Idee hierbei ist, Skripte in den iframe
einzufügen und auszuführen, um sicherzustellen, dass sie in einem isolierten Kontext ausgeführt werden:
// index.js function createSandbox(callback) { const iframe = document.getElementById('sandbox'); if (!iframe) { return console.error('Sandbox iframe not found'); } // Sicherstellen, dass der iFrame vollständig geladen ist, bevor Code ausgeführt wird iframe.onload = function () { const iframeWindow = iframe.contentWindow; // Definieren einiger sicherer globaler Variablen oder Funktionen innerhalb der Sandbox, falls erforderlich iframeWindow.safeGlobalVar = { /* Sichere Daten oder Methoden */ }; // Ausführen der Callback-Funktion, Übergeben des Fensterobjekts der Sandbox, um Code darin auszuführen callback(iframeWindow); }; // Neuladen des iFrames, um eine saubere Umgebung zu gewährleisten iframe.src = 'about:blank'; } // Verwenden der Sandbox createSandbox(function (sandboxWindow) { // Ausführen von Code innerhalb der Sandbox sandboxWindow.eval('console.log("Hello from the sandbox!");'); });
Einschränkungen des iframe
-Sandboxing
Die Verwendung eines iframe
für Sandboxing hat einige integrierte Einschränkungen:
<script>
-Tags innerhalb des Sandboxed-iframe
können nicht ausgeführt werden.- AJAX-Anfragen sind nicht erlaubt.
- Auf den lokalen Speicher (z. B.
localStorage
,cookie
) kann nicht zugegriffen werden. - Es können keine neuen Popups (
window.open
) erstellt werden. - Formulare können nicht gesendet werden.
- Plugins wie Flash können nicht geladen werden.
HTML5 führt jedoch das Attribut sandbox
ein, das zusätzliche Einschränkungen bietet, um die Sicherheit weiter zu erhöhen. Das Attribut sandbox
unterstützt die folgenden Werte:
allow-scripts
: Erlaubt die Ausführung von Skripten.allow-same-origin
: Erlaubt die Interaktion mit Dokumenten aus derselben Quelle.allow-forms
: Erlaubt das Senden von Formularen.allow-popups
: Erlaubt Popups, wie z. B. solche, die mitwindow.open
erstellt wurden.allow-top-navigation
: Erlaubt die Navigation zum Frame der obersten Ebene.
Hier ist ein Beispiel für die Verwendung des Attributs sandbox
in einem iframe
:
<iframe src="sandbox.html" sandbox="allow-scripts" id="sandbox"></iframe>
Sichere Kommunikation zwischen der Hauptseite und dem iframe
Wir können die postMessage
-API verwenden, um Daten sicher zwischen der Hauptseite und dem Sandboxed-iframe
auszutauschen. Zuerst auf der Hauptseite:
<!DOCTYPE html> <html> <head> <title>Main Page</title> </head> <body> <iframe src="./sandbox.html" id="sandbox" style="width: 600px; height: 400px"></iframe> <script> var iframe = document.getElementById('sandbox'); // Warten, bis der iFrame geladen ist iframe.onload = function () { var targetOrigin = 'http://127.0.0.1:5500/'; // Ersetzen Sie dies durch den tatsächlichen Ursprung des iFrames iframe.contentWindow.postMessage('Hello, sandbox!', targetOrigin); }; // Auf Nachrichten vom iFrame hören window.addEventListener('message', function (event) { // Überprüfen der Nachrichtenquelle if (event.origin !== 'http://127.0.0.1:5500') { return; // Nachrichten von nicht vertrauenswürdigen Quellen ignorieren } // Verarbeiten empfangener Nachrichten console.log('Received message from iframe:', event.data); }); </script> </body> </html>
Auf der iframe
-Seite (sandbox.html
) hören wir auf Nachrichten:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sandbox</title> </head> <body> <script> window.addEventListener('message', function (event) { // Überprüfen der Nachrichtenquelle if (event.origin !== 'http://127.0.0.1:5500') { return; // Nachrichten von nicht vertrauenswürdigen Quellen ignorieren } // Verarbeiten empfangener Nachrichten console.log('Received message:', event.data); // Eine Antwort zurück an die Hauptseite senden event.source.postMessage('Hello, main page!', event.origin); }); </script> </body> </html>
Durch die Überprüfung von event.origin
und die Angabe des genauen Zielursprungs in postMessage
können wir eine sichere Kommunikation gewährleisten und potenzielle Sicherheitslücken vermeiden.
Implementieren einer Sandbox mit Web Workers
Die Verwendung von Web Workers als Sandbox umfasst das dynamische Erstellen eines Blob
-Objekts, das den JavaScript-Code enthält, den Sie in einem Worker ausführen möchten. Diese Methode ermöglicht das Ausführen von beliebigem JavaScript-Code in einem separaten Thread und stellt gleichzeitig sicher, dass der Code von der Umgebung der Hauptseite isoliert ist. Dies bietet eine Möglichkeit, Code sicher auszuführen.
function workerSandbox(appCode) { var blob = new Blob([appCode]); var appWorker = new Worker(window.URL.createObjectURL(blob)); } workerSandbox('const a = 1; console.log(a);'); // Gibt aus: 1 console.log(a); // ReferenceError: a ist nicht definiert
Dieser Ansatz nutzt Web Workers, um nicht vertrauenswürdigen Code in einer isolierten Umgebung auszuführen und sicherzustellen, dass er die Hauptseite nicht beeinträchtigt. Web Workers sind besonders nützlich, wenn es um rechenintensive Aufgaben geht, da sie die Benutzeroberfläche reaktionsschnell halten, während separate Skripte ausgeführt werden.
Zusammenfassung
Eine JavaScript-Sandbox ist eine isolierte Ausführungsumgebung, die es ermöglicht, Code auszuführen und zu testen, ohne den Zustand oder die Daten der Hauptanwendung zu beeinträchtigen. Durch die Einschränkung des Zugriffs auf globale Variablen und Funktionen bietet eine Sandbox eine sichere Möglichkeit, nicht vertrauenswürdigen Code auszuführen und gleichzeitig potenzielle Sicherheitsrisiken und Datenlecks zu verhindern. Sandboxes sind unerlässlich, um Anwendungen vor bösartigen oder unvorhersehbaren Skripten zu schützen.
Verschiedene Methoden zur Implementierung einer Sandbox umfassen:
-
with
+new Function
:- Bietet grundlegende Isolation.
- Nicht vollständig sicher, da der Sandboxed-Code über
Function
-Konstruktoren entkommen könnte.
-
iframe
-Sandboxing:- Verwendet einen eingebetteten iFrame, um eine separate Ausführungsumgebung zu erstellen.
- Erhöht die Sicherheit, ist jedoch mit einigen Einschränkungen verbunden (z. B. eingeschränkte
localStorage
- undAJAX
-Anfragen). - Kann mit
postMessage
für einen sicheren Datenaustausch kombiniert werden.
-
Web Workers:
- Führt Code in einem separaten Thread aus.
- Bietet eine starke Isolation, hat aber keinen direkten Zugriff auf das DOM.
- Ideal für die Ausführung von nicht vertrauenswürdigen oder rechenintensiven Skripten.
Wann sollte eine Sandbox verwendet werden?
Eine Sandbox ist nützlich, wenn:
- Sie nicht vertrauenswürdiges JavaScript sicher ausführen oder parsen müssen.
- Sie Ausführungsumgebungen isolieren möchten, um zu verhindern, dass Code die Hauptanwendung beeinträchtigt.
- Sie den Zugriff des auszuführenden Codes auf bestimmte Objekte oder APIs einschränken müssen.
Durch die Wahl der richtigen Sandboxing-Technik können Entwickler die Sicherheit verbessern und die sichere Ausführung von Skripten gewährleisten und gleichzeitig die Risiken für die Hauptanwendung minimieren.
Wir sind Leapcell, Ihre erste Wahl für das Hosting von Node.js-Projekten.
Leapcell ist die Next-Gen-Serverless-Plattform für Webhosting, asynchrone Aufgaben und Redis:
Multi-Language-Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt viele Projekte kostenlos bereit
- zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Mio. Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und -protokollierung für verwertbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Auto-Scaling zur einfachen Bewältigung hoher Parallelität.
- Kein operativer Overhead — konzentrieren Sie sich einfach auf das Bauen.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ