JavaScript-Sandbox-Erkundung

JavaScript-Sandbox-Erkundung

1. Szenario

Ich habe kürzlich an etwas Ähnlichem wie einem webbasierten Plug-in-System gearbeitet und dabei mit der JS-Sandbox herumgespielt, um Code aus Drittanbieteranwendungen auszuführen.

2. Grundfunktionen der Sandbox

Vor der Implementierung (oder eigentlich nach der Recherche einiger Lösungen) wurde festgelegt, dass die Sandbox die Funktionen der oberen Ebene basierend auf event bus Kommunikation implementieren würde. Die grundlegende Schnittstelle ist wie folgt

Schnittstelle IEventEmitter exportieren {
  /**
   * Abhörereignis * @param-Kanal
   * @param-Handle
   */
  ein (Kanal: Zeichenfolge, Handle: (Daten: beliebig) => ungültig): ungültig;

  /**
   * Abhören abbrechen * @param channel
   */
  offByChannel(Kanal: Zeichenfolge): void;

  /**
   * Ereignis auslösen * @param Kanal
   * @param-Daten
   */
  emittieren (Kanal: Zeichenfolge, Daten: beliebig): ungültig;
}

/**
 * Eine grundlegende JS-VM-Funktion */
Exportschnittstelle IJavaScriptShadowbox erweitert IEventEmitter {
  /**
   * Beliebigen Code ausführen * @param Code
   */
  eval(Code: Zeichenfolge): ungültig;

  /**
   * Zerstöre die Instanz */
  zerstören(): ungültig;
}

Neben der Fähigkeit zur Kommunikation sind zwei weitere Methoden erforderlich:

  • eval : Führe einen Teil des JS-Codes aus
  • destroy : Zerstören Sie die Sandbox, damit die interne Implementierung einige Bereinigungsaufgaben erledigen kann.

JavaScript-Sandbox-Diagramm:

Im Folgenden zeigen wir, wie man mit iframe/web worker/quickjs beliebige js ausführt

3. Iframe-Implementierung

Ehrlich gesagt, wenn man über Sandboxen im Web spricht, denkt man wahrscheinlich als Erstes an iframe , aber es verwendet als Einstiegsdatei html statt JS, was nicht sehr benutzerfreundlich ist für Szenarien, in denen Sie JS als Einstieg verwenden möchten, aber nicht unbedingt iframe anzeigen müssen.

Natürlich können Sie den JS-Code in HTML einbinden und dann ausführen

Funktion evalByIframe(Code: Zeichenfolge) {
  const html = `<!DOCTYPE html><body><script>$[code]</script></body></html>`;
  const iframe = document.createElement("iframe");
  iframe.Breite = "0";
  iframe.Höhe = "0";
  iframe.style.display = "keine";
  Dokument.body.appendChild(iframe);
  const blob = neuer Blob([html], { Typ: "text/html" });
  iframe.src = URL.createObjectURL(blob);
  Iframe zurückgeben;
}

evalByIframe(`
document.body.innerHTML = "Hallo Welt"
Konsole.log('Standort.href: ', Standort.href)
Konsole.log('lokaler Speicher: ',lokaler Speicher)
`);

Aber iframe hat die folgenden Probleme:

  • Fast dasselbe wie eval (verwendet hauptsächlich Object.createObjectURL , was zu Homologie führt) – fatal
  • Kann auf alle Browser api – Wir bevorzugen, nur auf die eingefügten api zugreifen zu können, nicht auf alle dom api

4. Web Worker-Implementierung

Ein web worker ist grundsätzlich eine eingeschränkte JS-Laufzeitumgebung, die JS als Einstiegspunkt verwendet und über einen Kommunikationsmechanismus verfügt, der dem iframe

Funktion evalByWebWorker(Code: Zeichenfolge) {
  const blob = neuer Blob([Code], { Typ: "Anwendung/Javascript" });
  const url = URL.createObjectURL(blob);
  gib neuen Worker(URL) zurück;
}

evalByWebWorker(`
Konsole.log('Standort.href: ', Standort.href)
// console.log('localStorage: ', localStorage)
`);

Aber gleichzeitig ist es tatsächlich besser als iframe

  • Es werden nur begrenzte Browser-APIs unterstützt, darunter localStorage/document APIs, auf die nicht zugegriffen werden kann. Weitere Einzelheiten finden Sie unter: [MDN] Funktionen und Klassen, die von Web Workern verwendet werden können
  • Alle eingefügten APIs sind schließlich asynchrone Vorgänge, die auf postMessage/onmessage basieren.

5. Quickjs-Implementierung

Die Hauptinspiration für die Verwendung quickjs stammt aus einem Blogbeitrag über das Plugin-System von Figma, der chinesischen Quickjs-Dokumentation

Was ist Quickjs? Es handelt sich um eine JavaScript-Laufzeitumgebung. Die von uns am häufigsten verwendeten Laufzeitumgebungen sind zwar Browser und nodejs , es gibt jedoch noch viele andere. Weitere finden Sie unter GoogleChromeLabs/jsvu. quickjs ist eine leichte, eingebettete Laufzeitumgebung, die die Kompilierung in wasm unterstützt und im Browser ausgeführt wird. Es unterstützt auch JS-Funktionen bis zu es2020 (einschließlich der beliebten Promise und async/await ).

asynchrone Funktion evalByQuickJS(Code: Zeichenfolge) {
  const quickJS = warte auf getQuickJS();
  const vm = quickJS.createVm();
  const res = vm.dump(vm.unwrapResult(vm.evalCode(code)));
  vm.dispose();
  Rückgabewert;
}

 
console.log(warte auf evalByQuickJS(`1+1`));

Vorteil:

  • Tatsächlich ist es in puncto Sicherheit unübertroffen, da es auf verschiedenen vm ausgeführt wird und es kaum zu Sicherheitsproblemen kommt, die bei vorhandenen, auf Proxy basierenden Mikro-Frontends auftreten können.
  • Obwohl es keinen tatsächlichen Test gibt, weist der Blogbeitrag von figma darauf hin, dass das strukturierte Klonen des Browsers bei der Verarbeitung großer Objekte Leistungsprobleme aufweist, während dieses Problem quickjs nicht auftritt.

Mangel:

  • Es gibt keine globale api , einschließlich der gemeinsamen console/setTimeout/setInterval die keine Funktionen von js sind, sondern vom Browser und nodejs -Laufzeit implementiert werden. Sie müssen daher manuell implementiert und eingefügt werden, was einen erheblichen Nachteil darstellt.
  • Das DevToo Debugging des Browsers kann nicht verwendet werden
  • Da die zugrunde liegende Implementierung in C erfolgt, muss die Speicherfreigabe manuell verwaltet werden.

6. Fazit

Schließlich haben wir uns entschieden, den EventEmitter von Web Worker und QuickJS basierend auf der Schnittstelle zu implementieren und die Möglichkeit zu unterstützen, jederzeit wechseln zu können.

Dies ist das Ende dieses Artikels über die Erkundung von JavaScript-Sandboxen. Weitere relevante JavaScript-Sandbox-Inhalte finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Quickjs kapselt JavaScript-Sandbox-Details
  • Ein kurzer Vortrag über JavaScript Sandbox
  • Eine kurze Diskussion über verschiedene Möglichkeiten zur Implementierung einer Front-End-JS-Sandbox
  • Eine kurze Diskussion über die Node.js-Sandbox-Umgebung
  • Einrichten einer sicheren Sandbox-Umgebung für Node.js-Anwendungen
  • Beispiel für den Sandbox-Modus beim Schließen der JS-Implementierung
  • Beispielanalyse des JS-Sandbox-Modus
  • Sicherheits-Sandbox-Modus des JavaScript-Entwurfsmusters
  • WebWorker kapselt JavaScript-Sandbox-Details

<<:  Detaillierte Erläuterung der CSS BEM-Schreibstandards

>>:  Detaillierte Erklärung des MySQL-Triggerbeispiels

Artikel empfehlen

Tutorial zur Nginx-Standortkonfiguration von Grund auf

Grundlagen Die Reihenfolge der Standortübereinsti...

Vue-Komponente kapselt Beispielcode zum Hochladen von Bildern und Videos

Laden Sie zuerst die Abhängigkeiten herunter: cnp...

Vue implementiert das Hinzufügen von Wasserzeichen zu hochgeladenen Bildern

In diesem Artikel wird der spezifische Implementi...

Wie können die Transaktionseigenschaften von MySQL InnoDB sichergestellt werden?

Vorwort Wenn Sie jemand fragt: „Was sind die Merk...

Docker-Cross-Server-Kommunikations-Overlay-Lösung (Teil 1) Consul-Einzelinstanz

Inhaltsverzeichnis Szenario Aufgabe Idee analysie...

jQuery-Plugin zur Implementierung eines gestapelten Menüs

Jeden Tag ein jQuery-Plugin - gestapeltes Menü. Z...

Grundlegende MySQL-Tabellenabfragen – häufige Fehler beim Left-Join

Überblick Bei kleinen und mittelgroßen Projekten ...

32 typische spalten-/rasterbasierte Websites

Wenn Sie nach Inspiration für spaltenbasiertes Web...

Beispielcode zum Implementieren schöner Uhranimationseffekte mit CSS

Ich suche einen Job!!! Vorbereitung: Zunächst ein...

So verwenden Sie CSS-Overflow: Hidden (Überlauf ausblenden und Floats löschen)

Überlauf ausblenden Damit ist gemeint, dass Text-...

Diskussion über CSS-Stilpriorität und kaskadierende Reihenfolge

Im Allgemeinen : [1 wichtige Flagge] > [4 beson...