yast another jason unverständnis - eval



  • hi

    var s = 'alert("HI")';
    

    man sieht hier und da eval beispiele, die so

    eval ( s );
    

    aber auch so

    eval('(' + s + ')');
    

    geschrieben werden. ist das egal oder hat das nen grund, nen unterschied?


  • Mod

    niemals nie auf keinen Fall eval fuer JSON benutzen. Eigentlich in JS niemals nie auf keinen Fall jemals eval benutzen.

    Variante 2 wird oft als sicher verkauft, aber eval ist eval und eval ist in JS immer schlecht.



  • nie benutzen? iwo, ist schön bequem und tut keinem weh.
    🙂



  • Shade Of Mine schrieb:

    niemals nie auf keinen Fall eval fuer JSON benutzen. Eigentlich in JS niemals nie auf keinen Fall jemals eval benutzen.

    Variante 2 wird oft als sicher verkauft, aber eval ist eval und eval ist in JS immer schlecht.

    Ich habe das schon einige male gehört, dass eval für JSON nicht gut ist. Aber ich verstehe nicht ganz warum.

    Der Code, der da bei JSON ausgeführt wird, kommt doch von dem gleichen Server, wie die Seite, die den JSON request ausgeliefert hat. Das heisst, wenn der JSON code potentiell unsicher ist, ist auch die Seite, auf der der Request ausgeführt wird bereits unsicher.

    Wäre fein, wenn das jemand das erklären könnte.


  • Mod

    ich bins schrieb:

    Wäre fein, wenn das jemand das erklären könnte.

    Weil man sowas nicht tut. Man führt keinen Code blind aus, auch wenn er von einem selber kommt.

    Genauso wie man Daten immer per htmlentities() sicher macht wenn man sie anzeigt, genauso evald man keinen Code. Denn man kann sich nie sicher sein das alles immer OK ist. Was wenn zB eine PHP Fehlermeldung statt einem gültigen JSON Objekt als Antwort kommt? Dann evald man plötzlich Daten die man garnicht evalen will.

    Genauso wie man immer alle Parameter in SQL Queries escaped - auch wenn sie nicht vom User direkt kommen. Denn was wenn sich die Struktur der Seite mal ändert und plötzlich kommen die Input Parameter von wo anders, zB von einem Plugin statt von dir selber?

    Niemals nie externen Eingabewerten trauen. Das ist die Grundlage.



  • yaju schrieb:

    eval('(' + s + ')');
    

    ?

    Soweit ich das verstanden habe, wird mit '(' + s + ')' ein besonderer Kontext erzeugt (ähnlich wie mit '(function(){return'+s+';})()' ) der irendwie sicherstellen sollte, dass da keine Variablen innerhalb der Funktion überschrieben werden können.



  • Shade Of Mine schrieb:

    ich bins schrieb:

    Wäre fein, wenn das jemand das erklären könnte.

    Weil man sowas nicht tut. Man führt keinen Code blind aus, auch wenn er von einem selber kommt.

    Genauso wie man Daten immer per htmlentities() sicher macht wenn man sie anzeigt, genauso evald man keinen Code. Denn man kann sich nie sicher sein das alles immer OK ist. Was wenn zB eine PHP Fehlermeldung statt einem gültigen JSON Objekt als Antwort kommt? Dann evald man plötzlich Daten die man garnicht evalen will.

    Genauso wie man immer alle Parameter in SQL Queries escaped - auch wenn sie nicht vom User direkt kommen. Denn was wenn sich die Struktur der Seite mal ändert und plötzlich kommen die Input Parameter von wo anders, zB von einem Plugin statt von dir selber?

    Niemals nie externen Eingabewerten trauen. Das ist die Grundlage.

    Zu einer Fehlermeldung gehört auch ein Fehlercode, den man tunlichst immer vorher abfragen muss, bevor man mit eval die Parameter ausführt. Dann kann doch nichts passieren. Wenn er von einem selber kommt, dann ist das auch nicht blind.

    Und ich escape nie Parameter in SQL Queries. Ich verwende immer Platzhalter in meinen SQL Strings. Baue nie SQL Queries aus Parametern zusammen. Verwende immer prepared statements mit Parametern.


  • Mod

    ich bins schrieb:

    Zu einer Fehlermeldung gehört auch ein Fehlercode, den man tunlichst immer vorher abfragen muss, bevor man mit eval die Parameter ausführt. Dann kann doch nichts passieren. Wenn er von einem selber kommt, dann ist das auch nicht blind.

    Der Server kann einen unerwarteten Fehler produziert haben. Eben zB einen PHP Fehler.

    Fakt ist, dass der Server irgendwas liefern kann. Es kann immer irgendwas schief gehen was man vorher nicht bedacht hatte. Deshalb bauen clevere Leute ihre Software robust.

    Der einzige Grund eval zu verwenden ist Faulheit.
    Und wenn Faulheit der Grund ist etwas zu machen, dann ist man fast immer besser dran es anders zu machen.

    Und ich escape nie Parameter in SQL Queries. Ich verwende immer Platzhalter in meinen SQL Strings. Baue nie SQL Queries aus Parametern zusammen. Verwende immer prepared statements mit Parametern.

    Das nennt man escapen. Ob du jetzt selber escapst oder sagst was escaped werden soll - ist ziemlich das selbe.



  • Shade Of Mine schrieb:

    Fakt ist, dass der Server irgendwas liefern kann. Es kann immer irgendwas schief gehen was man vorher nicht bedacht hatte. Deshalb bauen clevere Leute ihre Software robust.

    Der einzige Grund eval zu verwenden ist Faulheit.
    Und wenn Faulheit der Grund ist etwas zu machen, dann ist man fast immer besser dran es anders zu machen.

    Ich stimme Dir voll zu. Und ich erwarte, dass der Server bei einem HTTP-OK genau das liefert, was mein Programm produziert. Wenn der HTTP-Server eine Fehlermeldung produziert, sollte er das mit HTTP code 500 (internal server error) oder etwas ähnliches tun.

    Also kann ich doch davon ausgehen, dass wenn ich den HTTP-Code 200 bekomme, die Antwort gefahrlos mit eval parsen kann. Wenn ich aus Faulheit den HTTP-Felercode nicht auswerte, dann ist genau das falsch. Und wenn der Server einen HTTP-OK schickt, es aber nicht OK ist, dann ist der Server falsch.

    Shade Of Mine schrieb:

    Und ich escape nie Parameter in SQL Queries. Ich verwende immer Platzhalter in meinen SQL Strings. Baue nie SQL Queries aus Parametern zusammen. Verwende immer prepared statements mit Parametern.

    Das nennt man escapen. Ob du jetzt selber escapst oder sagst was escaped werden soll - ist ziemlich das selbe.

    Da stimme ich Dir nicht ganz zu. Wenn ich prepared Statements verwende, werden die Parameter eben nicht escaped. Eventuell tut das die API, aber das Programm tut es nicht.

    Ich sehe einfach zu oft Code, wo eben mit SQLescape oder wie auch immer die Funktionen heissen, SQL-Statements zusammen gebaut werden. Das ist die Quelle des Übels, bzw. der SQL-Injections. Wenn die API eine Schnittstelle anbietet, bei dem ich die Parameter getrennt übergeben kann, dann sollte ich das immer immer tun. Bietet die API das nicht, dann sollte ich eine andere API verwenden.


  • Mod

    ich bins schrieb:

    Ich stimme Dir voll zu. Und ich erwarte, dass der Server bei einem HTTP-OK genau das liefert, was mein Programm produziert. Wenn der HTTP-Server eine Fehlermeldung produziert, sollte er das mit HTTP code 500 (internal server error) oder etwas ähnliches tun.

    Also kann ich doch davon ausgehen, dass wenn ich den HTTP-Code 200 bekomme, die Antwort gefahrlos mit eval parsen kann. Wenn ich aus Faulheit den HTTP-Felercode nicht auswerte, dann ist genau das falsch. Und wenn der Server einen HTTP-OK schickt, es aber nicht OK ist, dann ist der Server falsch.

    So sieht die reale Welt nicht aus. Tut mir leid, aber auch bei einem 200er kann der Server dir einen Fehler produziert haben.

    Da stimme ich Dir nicht ganz zu. Wenn ich prepared Statements verwende, werden die Parameter eben nicht escaped. Eventuell tut das die API, aber das Programm tut es nicht.

    Sie werden escaped. Du du jetzt sagst
    name=sqlescape(name = sql_escape(name);
    oder
    $query->bind('name', $name);
    ist nur syntaktischer Zucker.



  • Shade Of Mine schrieb:

    ich bins schrieb:

    Ich stimme Dir voll zu. Und ich erwarte, dass der Server bei einem HTTP-OK genau das liefert, was mein Programm produziert. Wenn der HTTP-Server eine Fehlermeldung produziert, sollte er das mit HTTP code 500 (internal server error) oder etwas ähnliches tun.

    Also kann ich doch davon ausgehen, dass wenn ich den HTTP-Code 200 bekomme, die Antwort gefahrlos mit eval parsen kann. Wenn ich aus Faulheit den HTTP-Felercode nicht auswerte, dann ist genau das falsch. Und wenn der Server einen HTTP-OK schickt, es aber nicht OK ist, dann ist der Server falsch.

    So sieht die reale Welt nicht aus. Tut mir leid, aber auch bei einem 200er kann der Server dir einen Fehler produziert haben.

    Dann ist das erst mal ein Fehler im Server und kein Sicherheitsrisiko. Besser wäre es doch dann, den Server zu fixen.

    Shade Of Mine schrieb:

    Da stimme ich Dir nicht ganz zu. Wenn ich prepared Statements verwende, werden die Parameter eben nicht escaped. Eventuell tut das die API, aber das Programm tut es nicht.

    Sie werden escaped. Du du jetzt sagst
    name=sqlescape(name = sql_escape(name);
    oder
    $query->bind('name', $name);
    ist nur syntaktischer Zucker.

    Es gibt Datenbanken, die unterstützen echte prepared statements. Da werden die Parameter im Protokoll separat vom SQL-String übertragen. Da ist im Protokoll spezifiziert, welche Teile SQL sind und welche Daten. Da werden die Daten dann nicht escaped. Escapen ist nur eine Lösungsmöglichkeit.

    Meines Wissens gilt das zumindest mal für PostgreSQL und Oracle. Die C-APIs von Mysql und sqlite3 unterstützen das auch, so dass auch hier kein escaping notwendig ist. Ob die beiden es auch auf Protokollebene dann machen, weiß ich nicht. Na ja - bei sqlite3 gibt es kein Protokoll. Da würde es mich wundern, wenn die Parameter erst escaped würden und dann wieder zurück.

    Wenn ich mir das so überlege, fällt mir jetzt kein einziger Anwendungsfall ein, wo ich die Daten escapen müsste.



  • Es gibt wunderbare, native Json-Implementierungen in den Browsern.

    Alternativ: https://github.com/douglascrockford/JSON-js oder JQuery.

    Oder auch:
    http://msdn.microsoft.com/en-us/library/cc836458(v=vs.85).aspx
    https://developer.mozilla.org/En/Using_native_JSON

    > Dann ist das erst mal ein Fehler im Server und kein Sicherheitsrisiko.

    Defense in Depth. Fehlerketten sollten an unterbrochen werden.

    > Der einzige Grund eval zu verwenden ist Faulheit.

    ⚠ Exakt ⚠


Anmelden zum Antworten