»eval« in JavaScript
Die Werte von Sequenzen
Die Funktion »eval« kann eine Sequenz auswerten, die ihr als Zeichenfolge übergeben werden.
- Auswertung
eval( "console.log( 2 + 3 );" )
5
undefined
Das ausgegebene »undefined« ist der Wert der Sequenz, also der Anweisung »console.log( 2 + 3 );«.
Falls keine Auswertungsanweisung ausgewertet wurde, ist der Wert »undefined«.
- Auswertung
eval( "" )
undefined
Die Werte von Anweisungen
Man sagt, daß eine Auswertungsanweisung einen Wert produziert, nämlich den Wert, den die Auswertung ihres Ausdrucks ergibt. So produziert die Anweisung »2;« beispielsweise den Wert »2«.
Mit »eval« kann der Wert einer Anweisung als Ausdruck notiert und somit auch weiterverarbeitet werden.
- Auswertung
eval( "3;" )+ 2
5
Dies ist die einzige Möglichkeit, den Wert einer Anweisung als Ausdruck zu notieren.
Hier zeigen wir die Auswertung einer Sequenz. (Der Wert einer Sequenz ist der Wert ihrer letzten Anweisung.)
- Auswertung
eval( "1; 2; 3;" )
3
Der von »eval« ermittelte Wert ist auch der Wert, der in vielen JavaScript -Konsolen für eine eingegebene Sequenz ausgegeben wird. Daher kann man sich vorstellen, daß die Konsolen-Eingaben mit »eval« ausgewertet werden.
In JavaScript haben Anweisungen Werte, aber da diese Werte nur mit Hilfe von »eval« weiterverarbeitet werden können und nur selten eine Rolle spielen, werden sie nur selten verwendet. Sie werden aber in vielen Konsolen nach der Eingabe einer Sequenz angezeigt.
Die Auswertung von Ausdrücken
Da ein Ausdruck dank der automatischen Semikolon-Einfügung zu einer Anweisung wird, kann auch eine Zeichenfolge mit einem Ausdruck als Argument verwendet werden.
- Auswertung
eval( "2 + 3" )
5
- Auswertung
typeof eval( "2 + 3" )
"number"
- Auswertung
typeof eval( "'abc'" )
"string"
Der Fähigkeit zur Auswertung (engl. “evaluation ”) einer Anweisung verdankt »eval« seinen Namen.
Anwendungsmöglichkeiten von »eval«
Manchmal liegt eine auszuwertende Anweisung nur als Zeichenfolge vor, etwa, wenn ein vom Benutzer eingegebener Ausdruck ausgewertet werden soll. Dann ist »eval« eine einfache Möglichkeit, dies zu tun.
Relevanz von »eval«
In einigen Fällen ist es auch zum Erlernen und Verständnis von JavaScript oder JavaScript -Implementationen hilfreich, »eval« zu kennen. Denn an Anwendungen von »eval« kann man gut erkennen, warum Sequenzen in JavaScript nicht – wie in anderen Programmiersprachen – ausgeführt, sondern ausgewertet werden. Nur »eval« zeigt den Wert einer Sequenz direkt an.
- Auswertung
eval( "1; 2; 3;" )
3
Warnungen vor »eval«
Manchmal liest man Quellen, die vom Einsatz von »eval« abraten (“eval is evil ”).
- Wenn »eval« Eingaben auswertet, dann könne es eine bösartige Eingabe auswerten, die zu Schäden führt. – Dieses Risiko besteht tatsächlich. Im allgemeinen ist es besonders riskant, wenn eine Partei etwas eingeben kann, das ungeprüft unter der Umgebung einer anderen Partei läuft, weil sie damit der anderen Partei schaden kann. Es besteht aber auch die Möglichkeit, daß eine Partei sich durch unbedachte oder versehentliche Eingaben selbst schädigt. Eine Zeichenfolge, die mit »eval« ausgewertet werden soll, sollte daher in Fällen, in denen ein Risiko gesehen wird, zuvor auf schädliche Inhalte überprüft werden. (Möglichkeiten dazu werden allerdings erst später in diesem Kurs vorgestellt.) Außerdem sollten Lösungen, die ohne »eval« auskommen, bevorzugt verwendet werden, wenn sie keine eigenen schweren Nachteile haben.
- Von Programmierer, die JavaScript noch nicht vollständig kennen, wird »eval« manchmal verwendet, um etwas zu erledigen, daß auch direkt ohne »eval« erledigt werden kann. – Da »eval« im allgemeinen aufwendiger als eine direkte Auswertung ist, sollte man es nur dann verwenden, wenn es keine direkte Möglichkeit ohne den „Umweg“ über »eval« geht. Wenn man noch nicht alle Möglichkeiten der Sprache kennt, sollte man sie erlernen. (Auch dieser Kurs hier stellt noch nicht alle Möglichkeiten der Sprache vor, man kann diese aber dann aus Büchern erlernen.) Dann sollte man immer zuerst versuchen, etwas ohne »eval« zu programmieren, wenn dies nicht wesentlich aufwendiger ist als die Verwendung von »eval«.
- Das Nachvollziehen der Auswertung mit »eval« ausgewerteter Zeichenfolgen in einem Debugger (der Begriff wird später erklärt werden) ist schwieriger als wenn diese direkt ausgewertet werden.
- »eval« soll langsamer sein als eine direkte Auswertung. – Das könnte manchmal stimmen, aber manchmal ist eine direkterere Auswertung nicht möglich oder ihre Programmierung wäre zu aufwendig und in manchen Fällen nicht unbedingt schneller.
Man kann also nicht sagen, daß die Verwendung von »eval« grundsätzlich immer schlecht ist und immer vermieden werden sollte. Wenn es mit Bedacht von einem vollständig ausgebildeten Programmierer eingesetzt wird, kann es manchmal hilfreich sein.
Die Funktion ›eval‹ kann zu Lern- und Übungszwecken verwendet werden, solange die Ergebnisse nicht in sicherheitskritischen Bereichen (beispielsweise auf einem Web-Server) eingesetzt werden. Es ist hilfreich, ›eval‹ zu kennen, weil es das Verständnis von JavaScript vertiefen kann. Außerdem ist es nötig, ›eval‹ zu kennen, um von anderen geschriebene Skripte zu verstehen, in denen es verwendet wird. Die Verwendung von ›eval‹ in Skripten, die in der Praxis eingesetzt werden, setzt jedoch voraus, daß ein Experte geprüft hat, daß eine Verwendung von ›eval‹ in diesem Fall wirklich notwendig ist und nicht zu Sicherheitslücken führt.
Aus der freien Wildbahn Verschleiertes JavaScript
- „Aus der freien Wildbahn“
- Unter der Überschrift „Aus der freien Wildbahn “ stellen wir in diesem Kurs Anwendungsmöglichkeiten der Sprache JavaScript vor, die nicht immer besonders empfehlenswert sind, aber die in der Praxis beobachtet wurden. Es kann helfen, solche Anwendungsmöglichkeiten zu kennen und zu verstehen, auch wenn man sie nicht unbedingt selber einsetzen möchte.
Im Web findet man verschiedene bösartige Skripte, die Werbefenster öffnen oder schädliche Programme installieren. Oft findet man in entsprechenden Webseiten zunächst ein „verschleiertes“ Skript, das man nicht direkt lesen kann. Um dies auszuwerten, wird es bei der Auswertung zunächst entschleiert und dann mit »eval« ausgewertet.
- Auswertung
eval( String.fromCharCode( 97,108,101,114,116,40,39,72,97,33,39,41,59 ));
Die Verschleierung verhindert es nicht nur, daß ein Mensch das Skript auf einfach Weise lesen und verstehen kann, auch Computerprogramme, die nach Aufrufen bestimmter gefährlicher Funktionen suchen, um den Benutzer zu schützen, haben es jetzt schwerer, ihre Arbeit zu tun.
Im Web mit einem Browser zu surfen, in dem JavaScript aktiviert ist, stellt ein Sicherheitsrisiko dar. Verschiedene Stellen raten deswegen dazu, JavaScript zu deaktivieren, und in einigen Organisationen dürfen die Angehörigen nur mit ausgeschaltetem JavaScript surfen. Dies ist sicherer, aber einige Web-Angebote können dann nicht genutzt werden.
Übungsaufgaben
/ Übungsaufgabe
Entschleiern Sie das obenstehende verschleierte Skript so, daß Sie sein Verhalten vorhersagen können, ohne es auszuwerten.
(Bei dieser Aufgabe ist die Benutzung der Konsole erlaubt.)
/ Übungsaufgabe
Bei dem folgenden Skript wurde das Entschleiern noch etwas erschwert. Wie wurde das erreicht? Können Sie auch hier das Verhalten vorhersagen, ohne das Skript auszuwerten?
(Bei dieser Aufgabe ist die Benutzung der Konsole erlaubt.)
- Skript
eval(String.fromCharCode(101,118,97,108,40,83,116,114,105,110,103,46,102,114,
111,109,67,104,97,114,67,111,100,101,40,49,48,49,44,49,49,56,44,57,55,44,49,
48,56,44,52,48,44,56,51,44,49,49,54,44,49,49,52,44,49,48,53,44,49,49,48,44,
49,48,51,44,52,54,44,49,48,50,44,49,49,52,44,49,49,49,44,49,48,57,44,54,55,
44,49,48,52,44,57,55,44,49,49,52,44,54,55,44,49,49,49,44,49,48,48,44,49,48,
49,44,52,48,44,53,55,44,53,53,44,52,52,44,52,57,44,52,56,44,53,54,44,52,52,
44,52,57,44,52,56,44,52,57,44,52,52,44,52,57,44,52,57,44,53,50,44,52,52,44,
52,57,44,52,57,44,53,52,44,52,52,44,53,50,44,52,56,44,52,52,44,53,49,44,53,
55,44,52,52,44,53,53,44,53,48,44,52,52,44,52,57,44,52,57,44,52,57,44,52,52,
44,53,49,44,53,49,44,52,52,44,53,49,44,53,55,44,52,52,44,53,50,44,52,57,44,
52,52,44,53,51,44,53,55,44,52,49,44,52,49,44,53,57,41,41,59));
/ Übungsaufgabe
Schreiben Sie ein verschleiertes Skript, das nicht »String.fromCharCode«, sondern »atob« verwendet.
(Bei dieser Aufgabe ist die Benutzung der Konsole erlaubt.)
Verschleierer *
Das folgende Skript wurde zum Verschleiern verwendet, aber es kann mit dem bisher im Kurs Behandeltem noch nicht verstanden werden.
- Code *
e=x=>x.split('').map(x=>x.charCodeAt()).join(',');