Javascript eval (und Freunde)

8

Einige behaupten, Eval sei böse.

Jede reguläre HTML-Seite könnte so aussehen:

%Vor%

Das heißt, vorausgesetzt, die Person, die dies tut, kennt ihren Job und lässt JavaScript am Ende der Seite laden.

Hier laden wir im Grunde eine Skriptdatei in den Webbrowser. Einige Leute sind tiefer gegangen und verwenden dies als eine Möglichkeit, mit einem 3rd-Party-Server zu kommunizieren ...

%Vor%

An diesem Punkt wurde festgestellt, dass es wichtig ist, diese Skripte zur Laufzeit aus irgendeinem Grund zu laden.

Was ist mein Punkt? Während die Mechanik unterschiedlich ist, machen wir das gleiche ... einen Text als Code auszuführen - aka eval() .

Nun, da ich meinen Punkt klar gemacht habe, geht hier die Frage ...

Unter bestimmten Bedingungen, wie etwa einer AJAX-Anfrage oder (interessanterweise) einer Websocket-Verbindung, was ist der beste Weg, um eine Antwort vom Server auszuführen?

Hier ist ein Paar, um dich zum Nachdenken zu bringen ...

  • eval() Die Ausgabe des Servers. (War der Typ da drüben nur in Ohnmacht gefallen?)
  • Führe eine benannte Funktion aus, die vom Server zurückgegeben wird: var resp = sock.msg; myObj[resp]();
  • Erstelle meinen eigenen Parser, um herauszufinden, was der Server mir zu sagen versucht, ohne das Javascript direkt zu stören.
Christian 13.02.2012, 19:10
quelle

5 Antworten

5
  

Unter bestimmten Bedingungen, wie einer AJAX-Anfrage oder (interessanter) einer Websocket-Verbindung, was ist der beste Weg, um eine Antwort vom Server auszuführen?

Der Hauptkritikpunkt von eval beim Analysieren von Nachrichten ist, dass es übertrieben ist - Sie benutzen einen Vorschlaghammer, um eine Fliege mit all dem zusätzlichen Risiko, das von übermächtigen Werkzeugen kommt, zu schlagen - sie können zurückschlagen und zuschlagen du.

Lassen Sie uns die Arten der Antworten in ein paar verschiedene Kategorien aufteilen:

  1. Statisches Javascript wird bei Bedarf geladen
  2. Eine dynamische Antwort von einer vertrauenswürdigen Quelle auf einem sicheren Kanal, die keinen von nicht vertrauenswürdigen Parteien angegebenen Inhalt enthält.
  3. Eine dynamische Antwort aus gemischten Quellen (möglicherweise meist vertrauenswürdig, aber enthält codierte Zeichenfolgen, die von nicht vertrauenswürdigen Parteien angegeben werden), bei denen es sich hauptsächlich um Daten
  4. handelt
  5. Nebenwirkungen basierend auf Daten

Für (1) gibt es keinen Unterschied zwischen XHR + eval und <script src> , aber XHR + eval hat wenige Vorteile.

Für (2), kleiner Unterschied. Wenn Sie die Antwort mit JSON.parse entpacken können, werden Sie wahrscheinlich weniger Probleme haben, aber eval 's zusätzliche Autorität wird weniger wahrscheinlich mit Daten aus einer vertrauenswürdigen Quelle missbraucht als sonst, also keine große Sache, wenn Sie hat einen guten positiven Grund für eval .

Für (3) gibt es einen großen Unterschied. eval 's extra-missbrauchbare Autorität wird Sie wahrscheinlich beißen, selbst wenn Sie sehr vorsichtig sind. Dies ist sicherheitshalber spröde. Tu es nicht.

Für (4) ist es am besten, wenn Sie es in ein Datenproblem und ein Codeproblem aufteilen können. JSONP ermöglicht dies, wenn Sie das Ergebnis vor der Ausführung validieren können. Parsen Sie die Daten mit JSON.parse oder etwas anderem mit wenig Missbrauchsberechtigung, so dass eine Funktion, die Sie geschrieben und für die externe Verwendung freigegeben haben, die Nebenwirkungen hat. Dies minimiert die überschüssige Missbrauchsautorität. Naive eval ist hier gefährlich.

    
Mike Samuel 13.02.2012, 19:19
quelle
5

"Böse" bedeutet nicht "verboten" . Manchmal gibt es durchaus gute Gründe, sogenannte "böse" Eigenschaften zu verwenden. Sie werden nur "böse" genannt, weil sie missbraucht werden können.

In Ihrem Fall darf das clientseitige Skript nur Anfragen an "seinen eigenen" Server stellen. Dies ist derselbe Server, von dem das ursprüngliche JavaScript stammt. Daher ist die dynamische Antwort genauso vertrauenswürdig wie der ursprüngliche Code. Ein perfekt gültiges Szenario für eval() .

    
Ferdinand Beyer 13.02.2012 19:18
quelle
4

Wenn Sie Code von einer Domäne abrufen, die Sie nicht kontrollieren, bedeutet die Übergabe des Codes "raw" an den JavaScript-Interpreter immer, dass Sie dieser Domäne vollständig vertrauen müssen, oder dass Sie sich nicht darum kümmern müssen, ob sie schädlich ist Code verdirbt Ihre eigenen Seiten.

Wenn Sie die Domain kontrollieren, dann tun Sie, was Sie wollen.

    
Pointy 13.02.2012 19:18
quelle
2

Der Server sollte Ihnen Daten und keinen Code liefern. Sie sollten den Server mit JSON-Daten antworten lassen, damit Ihr JS-Code entsprechend handeln kann. Wenn der Server Namen von Funktionen sendet, die mit myObj[resp](); aufgerufen werden sollen, wird die Serverlogik immer noch eng mit der Clientlogik verbunden.

Es ist schwierig, ohne einen Beispielcode mehr Vorschläge zu machen.

    
Juan Mendes 13.02.2012 19:18
quelle
2

Lassen Sie Ihren Server JSON zurückgeben und interpretieren Sie diesen JSON auf dem Client. Der Client wird herausfinden, was mit dem JSON zu tun ist, genau wie der Server weiß, was er mit den vom Client empfangenen Anfragen machen soll.

Wenn Ihr Server beginnt, ausführbaren Code zurückzugeben, haben Sie ein Problem. NICHT, weil etwas "schlechtes" passieren wird (obwohl es möglich ist), sondern weil Ihr Server nicht dafür verantwortlich ist, zu wissen, was der Client tun soll .

Das ist so, als würde man Code an den Server senden und erwarten, dass der Server ihn ausführt. Es sei denn, Sie haben einen wirklich guten Grund (z. B. eine IDE im Browser), das ist eine schlechte Idee.

Verwenden Sie eval so oft wie Sie möchten, stellen Sie nur sicher, dass Sie die Verantwortlichkeiten trennen.

Bearbeiten:

Ich sehe den Fehler in dieser Logik. Der Server teilt dem Client offensichtlich mit, was er tun soll, einfach weil er die Skripte liefert, die der Client ausführt. Mein Punkt ist jedoch, dass der serverseitige Code nicht sein sollte, um Skripte im laufenden Betrieb zu erzeugen. Der Server sollte orchestrieren, nicht produzieren.

    
Christopher Harris 13.02.2012 19:19
quelle