1 Punkte von GN⁺ 2024-07-08 | 1 Kommentare | Auf WhatsApp teilen

QuickJS - JavaScript in der WebAssembly-QuickJS-Sandbox ausführen

Dieses TypeScript-Paket ermöglicht es, JavaScript-Code mithilfe der QuickJS-Engine sicher innerhalb einer WebAssembly-Sandbox auszuführen. Es eignet sich zum sicheren Isolieren und Ausführen nicht vertrauenswürdigen Codes und bietet mit der zu WebAssembly kompilierten, leichtgewichtigen und schnellen QuickJS-Engine eine robuste Umgebung für die Codeausführung.

Funktionen

  • Sicherheit: Nicht vertrauenswürdiger JavaScript-Code kann in einer sicheren, isolierten Umgebung ausgeführt werden
  • Dateisystem: Ein virtuelles Dateisystem kann gemountet werden
  • Benutzerdefinierte Node-Module: Benutzerdefinierte Node-Module können gemountet werden
  • Fetch-Client: Ein Fetch-Client für HTTP(S)-Aufrufe kann bereitgestellt werden
  • Test Runner: Enthält einen Test Runner und ein auf chai basierendes expect
  • Performance: Nutzt die Vorteile der leichtgewichtigen und effizienten QuickJS-Engine
  • Vielseitigkeit: Lässt sich einfach in bestehende TypeScript-Projekte integrieren
  • Einfachheit: Bietet eine benutzerfreundliche API zum Ausführen und Verwalten von JavaScript-Code innerhalb der Sandbox

Vollständige Dokumentation ansehen

Beispiele im Repository finden

Grundlegende Verwendung

Hier ist ein einfaches Beispiel für die Verwendung des Pakets:

import { quickJS } from '@sebastianwessel/quickjs'

// Allgemeine Einrichtung wie das Laden und Initialisieren von QuickJS wasm
// Da dies ressourcenintensiv ist, sollte es nach Möglichkeit nur einmal erfolgen
const { createRuntime } = await quickJS()

// Bei jeder Ausführung von JS-Code wird eine Runtime-Instanz erstellt
const { evalCode } = await createRuntime({
  allowFetch: true, // injiziert fetch und erlaubt dem Code, Daten abzurufen
  allowFs: true, // mountet ein virtuelles Dateisystem und stellt das Modul node:fs bereit
  env: {
    MY_ENV_VAR: 'env var value'
  },
})

const result = await evalCode(`
  import { join } as path from 'path'
  const fn = async ()=>{
    console.log(join('src','dist')) // gibt auf dem Host-System "src/dist" im Log aus
    console.log(env.MY_ENV_VAR) // gibt auf dem Host-System "env var value" im Log aus
    const url = new URL('https://example.com')
    const f = await fetch(url)
    return f.text()
  }
  export default await fn()
`)

console.log(result) // { ok: true, data: '<!doctype html>\n<html>\n[....]</html>\n' }

Credits

Diese Bibliothek basiert auf:

  • quickjs-emscripten
  • quickjs-emscripten-sync
  • memfs
  • Chai

Verwendete Tools:

  • Bun
  • Biome
  • Hono
  • poolifier-web-worker
  • tshy
  • autocannon

Lizenz

Dieses Projekt steht unter der MIT-Lizenz.


Dieses Paket ist ideal für Entwickler, die JavaScript-Code sicher innerhalb von TypeScript-Anwendungen ausführen möchten, und gewährleistet dabei Performance und Sicherheit durch die QuickJS-WebAssembly-Sandbox.

Zusammenfassung von GN⁺

Dieser Artikel beschreibt, wie sich JavaScript-Code mit der QuickJS-Engine sicher innerhalb einer WebAssembly-Sandbox ausführen lässt. Das ist besonders nützlich, um nicht vertrauenswürdigen Code zu isolieren und auszuführen. QuickJS bietet eine leichtgewichtige und zugleich schnelle Performance und lässt sich einfach in TypeScript-Projekte integrieren. Projekte mit ähnlicher Funktionalität sind Deno und Node.js.

1 Kommentare

 
GN⁺ 2024-07-08
Hacker-News-Kommentare
  • Der Autor der Bibliothek quickjs-emscripten lobt die Standardbibliothek der Bibliothek

    • fragt, ob sie im Browser oder mit einem Bundler ausgeführt wurde
    • weist auf Kompatibilitätsprobleme mit Bundlern wie Webpack hin
    • Sicherheitswarnung: Die Bibliothek ermöglicht es Gasts-Code, fetch mit denselben Cookies wie die fetch-Funktion des Hosts aufzurufen
    • man sollte vorsichtig sein, wenn man nicht vertrauenswürdigen Code ausführt
    • quickjs-emscripten ist Low-Level und vermeidet magische Funktionen, um Sicherheit zu gewährleisten
    • beim Ausführen nicht vertrauenswürdigen Codes sollten Sandbox und API sorgfältig auditiert werden
    • empfiehlt, den Blogpost von Figma zur Sicherheit der Plugin-Sandbox zu lesen
  • In einem früheren Job wurden bei der Nutzung von quickjs-emscripten viele "segmentation faults" und Fehler erlebt

    • das Projekt wurde eingestellt; wenn man es noch einmal machen würde, würde man die offiziell unterstützten wasm-Bundles verwenden
  • Es gibt mehrere Möglichkeiten, JavaScript zu sandboxen

    • fragt, ob es eine Methode gibt, den DOM-Zugriff zu sandboxen
    • iframes sind die einzige Technik, aber schwergewichtig und langsam
    • schreibt gerade eine App, die Plugins hostet, und wenn man Plugins DOM-Zugriff erlaubt, kann das problematisch werden
  • fragt, ob es im Browser laufen kann

    • konnte keinen Hinweis auf unterstützte Umgebungen finden
  • hat quickjs ausprobiert, sich am Ende aber für isolated-vm entschieden

    • beide Bibliotheken erfüllten die Sicherheitsanforderungen, aber isolated-vm war bei der Performance überlegen
  • Der Autor einer anderen JS-Sandbox-Bibliothek findet den quickjs-emscripten-Ansatz interessant

    • erwähnt, dass JS-in-JS oder JS-in-WASM ein hohes Maß an Isolation bieten
    • weist darauf hin, dass Node.js nicht mit Blick auf Isolation und Sandboxing entworfen wurde
    • fragt, ob createRuntime neben fetch auch Aufrufe an die Host-Umgebung definieren kann
    • erwähnt, dass Browser-Unterstützung nützlich wäre
  • denkt, dass sich diese Bibliothek dafür eignen könnte, von Nutzern bereitgestellten JS-Code auszuführen

    • bittet um Empfehlungen, wie man einen Bundler in einer Sandbox-Umgebung ausführt
  • erwähnt, dass die Performance von QuickJS nicht mit der Host-JS-VM konkurrieren kann

    • ist aber schneller als alte C-Interpreter oder in JavaScript implementierte Interpreter
  • arbeitete an einem High-Level-Wrapper für quickjs-emscripten

    • die API von quickjs-emscripten ist der C-API von quickjs sehr ähnlich und daher schwer zu benutzen
    • die Implementierung von require()-Support ist schwierig
    • verwendet eine Methode, bei der Moduldateien vorab in ein In-Memory-Dateisystem geladen werden
  • Die Bibliothek quickjs-emscripten-sync bietet eine automatische Synchronisierung von Host- und Gastfunktionen, was eine große Angriffsfläche darstellen kann

    • ist besorgt über die Möglichkeit, aus der Sandbox auszubrechen
  • fragt, ob es im Browser laufen kann, weil es zu wasm kompiliert wurde

    • fragt sich, ob man fetch-Anfragen ohne angehängte Cookies senden kann