Ich frage mich, ob es möglich ist, JavaScript im Browser zu sandboxen, um den Zugriff auf Funktionen zu verhindern, die normalerweise für JavaScript-Code verfügbar sind, der auf einer HTML-Seite ausgeführt wird.
Angenommen, ich möchte Endbenutzern eine JavaScript-API bereitstellen, mit der sie Ereignishandler definieren können, die ausgeführt werden sollen, wenn "interessante Ereignisse" auftreten. Ich möchte jedoch nicht, dass diese Benutzer auf die Eigenschaften und Funktionen des window
Objekts zugreifen . Kann ich das machen?
Nehmen wir im einfachsten Fall an, ich möchte verhindern, dass Benutzer anrufen alert
. Einige Ansätze, die mir einfallen, sind:
- Neu definiert
window.alert
global. Ich denke nicht, dass dies ein gültiger Ansatz wäre, da möglicherweise anderer Code, der auf der Seite ausgeführt wird (dh Dinge, die nicht von Benutzern in ihren Ereignishandlern erstellt wurden), verwendet werden möchtealert
. - Senden Sie den Ereignishandlercode zur Verarbeitung an den Server. Ich bin nicht sicher, ob das Senden des Codes an den Server zur Verarbeitung der richtige Ansatz ist, da die Ereignishandler im Kontext der Seite ausgeführt werden müssen.
Vielleicht würde eine Lösung funktionieren, bei der der Server die benutzerdefinierte Funktion verarbeitet und dann einen Rückruf generiert, der auf dem Client ausgeführt werden soll? Auch wenn dieser Ansatz funktioniert, gibt es bessere Möglichkeiten, dieses Problem zu lösen?
quelle
while (1) {}
--- schützen kann. Er hängt einfach. Ebensoa=[]; while (1) { a=[a,a]; }
.Schauen Sie sich Douglas Crockfords ADsafe an :
Ein Beispiel für die Verwendung von ADsafe finden Sie in den Dateien
template.html
undtemplate.js
im GitHub-Repository des Projekts .quelle
this
, was völlig inakzeptabel ist. Sie können kein gutes Javascript schreiben, ohne es zu verwendenthis
.this
. Es ist nicht schwer, den schlecht benannten Parameter zu vermeiden.this
einen gleichen, äquivalententhis
Weg, dies nicht zu tun (es ist schließlich nur ein Parameter).Ich habe eine Sandbox- Bibliothek namens jsandbox erstellt , die Web-Worker verwendet, um ausgewerteten Code zu sandboxen . Es gibt auch eine Eingabemethode zum expliziten Angeben von Sandbox-Codedaten, die sonst nicht abgerufen werden könnten.
Das Folgende ist ein Beispiel für die API:
quelle
Ich denke, dass js.js hier erwähnenswert ist. Es ist ein in JavaScript geschriebener JavaScript-Interpreter.
Es ist ungefähr 200-mal langsamer als natives JS, aber seine Natur macht es zu einer perfekten Sandbox-Umgebung. Ein weiterer Nachteil ist seine Größe - fast 600 KB, was in einigen Fällen für Desktops akzeptabel sein kann, für mobile Geräte jedoch nicht.
quelle
Wie in anderen Antworten erwähnt, reicht es aus, den Code in einem Sandbox-Iframe zu speichern (ohne ihn an den Server zu senden) und mit Nachrichten zu kommunizieren. Ich würde vorschlagen, einen Blick auf eine kleine Bibliothek zu werfen, die ich hauptsächlich erstellt habe, weil eine API für den nicht vertrauenswürdigen Code bereitgestellt werden muss, genau wie in der Frage beschrieben: Es besteht die Möglichkeit, den jeweiligen Funktionssatz direkt in die Sandbox zu exportieren, in der Der nicht vertrauenswürdige Code wird ausgeführt. Außerdem gibt es eine Demo, die den von einem Benutzer in einer Sandbox übermittelten Code ausführt:
http://asvd.github.io/jailed/demos/web/console/
quelle
Alle Browser-Anbieter und die HTML5-Spezifikation arbeiten auf eine tatsächliche Sandbox-Eigenschaft hin, um Sandbox-Iframes zuzulassen. Sie ist jedoch weiterhin auf die Iframe-Granularität beschränkt.
Im Allgemeinen kann kein Grad an regulären Ausdrücken usw. willkürlich von Benutzern bereitgestelltes JavaScript sicher bereinigen, da es zum Stoppproblem degeneriert: - /
quelle
Eine verbesserte Version des Sandbox-Codes für Webworker von @ RyanOHara in einer einzigen Datei (keine zusätzliche
eval.js
Datei erforderlich).Probier es aus:
https://jsfiddle.net/kp0cq6yw/
Es sollte ausgegeben werden
6
(getestet in Chrome und Firefox).quelle
Ein hässlicher Weg, aber vielleicht funktioniert das für Sie. Ich habe alle Globals genommen und sie im Sandbox-Bereich neu definiert. Außerdem habe ich den strengen Modus hinzugefügt, damit sie das globale Objekt nicht mit einer anonymen Funktion abrufen können.
https://gist.github.com/alejandrolechuga/9381781
quelle
window
darauf zurückzukommen.sandboxcode('console.log((0,eval)("this"))')
function sbx(s,p) {e = eval; eval = function(t){console.log("GOT GOOD")}; sandboxcode(s,p); eval =e}
(_=>_).constructor('return this')()
Ein unabhängiger Javascript-Interpreter liefert mit größerer Wahrscheinlichkeit eine robuste Sandbox als eine Caged-Version der integrierten Browser-Implementierung. Ryan hat js.js bereits erwähnt , aber ein aktuelleres Projekt ist JS-Interpreter . In den Dokumenten wird beschrieben, wie verschiedene Funktionen für den Interpreter verfügbar gemacht werden. Der Umfang ist jedoch ansonsten sehr begrenzt.
quelle
Ab 2019 scheint vm2 die beliebteste und am regelmäßigsten aktualisierte Lösung für dieses Problem zu sein.
quelle
Mit NISP können Sie eine Sandbox-Bewertung durchführen. Obwohl der Ausdruck, den Sie schreiben, nicht genau ein JS ist, schreiben Sie stattdessen S-Ausdrücke. Ideal für einfache DSLs, die keine umfangreiche Programmierung erfordern.
quelle
1) Angenommen, Sie müssen einen Code ausführen:
Angenommen, Sie möchten es in einer Sandbox ausführen:
Diese beiden Zeilen schlagen bei der Ausführung fehl, da die Funktion "alert" in der "Sandbox" nicht verfügbar ist.
2) Und jetzt möchten Sie ein Mitglied des Fensterobjekts mit Ihrer Funktionalität verfügbar machen:
In der Tat können Sie Anführungszeichen hinzufügen und andere polieren, aber ich denke, die Idee ist klar.
quelle
Woher kommt dieser Benutzer JavaScript?
Sie können nicht viel tun, wenn ein Benutzer Code in Ihre Seite einbettet und ihn dann über seinen Browser aufruft (siehe Greasemonkey, http://www.greasespot.net/ ). Es ist nur etwas, was Browser tun.
Wenn Sie das Skript jedoch in einer Datenbank speichern, dann abrufen und auswerten (), können Sie das Skript bereinigen, bevor es ausgeführt wird.
Beispiele für Code, der alle Fenster entfernt. und dokumentieren. Verweise:
Dies versucht zu verhindern, dass Folgendes ausgeführt wird (nicht getestet):
Es gibt viele Einschränkungen, die Sie auf das unsichere Benutzerskript anwenden müssten. Leider ist für JavaScript kein 'Sandbox-Container' verfügbar.
quelle
Ich habe an einer simplen JS-Sandbox gearbeitet, mit der Benutzer Applets für meine Site erstellen können. Obwohl ich immer noch vor einigen Herausforderungen stehe, wenn ich den DOM-Zugriff zulasse (parentNode lässt mich die Dinge einfach nicht sicher halten = /), bestand mein Ansatz darin, das Fensterobjekt mit einigen seiner nützlichen / harmlosen Mitglieder neu zu definieren und dann den Benutzer zu bewerten () Code mit diesem neu definierten Fenster als Standardbereich.
Mein "Kern" -Code sieht so aus ... (Ich zeige ihn nicht ganz;)
Also kann ich eine Sandbox instanziieren und ihre execute () verwenden, um Code zum Laufen zu bringen. Außerdem werden alle neu deklarierten Variablen im ausgewerteten Code letztendlich an den Bereich execute () gebunden, sodass keine Namen in Konflikt geraten oder mit vorhandenem Code in Konflikt geraten.
Obwohl globale Objekte weiterhin zugänglich sind, müssen diejenigen, die dem Sandbox-Code unbekannt bleiben sollten, als Proxys im Sandbox :: scope-Objekt definiert werden.
Hoffe das funktioniert bei dir.
quelle
Sie können den Code des Benutzers in eine Funktion einschließen, die verbotene Objekte als Parameter neu definiert. Diese werden dann
undefined
beim Aufruf angezeigt:Kluge Angreifer können dies natürlich umgehen, indem sie das Javascript-DOM untersuchen und ein nicht überschriebenes Objekt finden, das einen Verweis auf das Fenster enthält.
Eine andere Idee ist das Scannen des Benutzercodes mit einem Tool wie jslint . Stellen Sie sicher, dass keine voreingestellten Variablen vorhanden sind (oder: nur die gewünschten Variablen), und lassen Sie das Skript des Benutzers nicht verwendet werden, wenn globale Werte festgelegt sind oder auf diese zugegriffen wird. Auch hier kann es anfällig sein, das DOM zu durchlaufen - Objekte, die der Benutzer mithilfe von Literalen erstellen kann, enthalten möglicherweise implizite Verweise auf das Fensterobjekt, auf das zugegriffen werden kann, um die Sandbox zu verlassen.
quelle