flawopen.com/JSON-Parsing/JSON.parse() vs eval()
Ist JSON.parse() sicherer als eval()?
Stell dir die Eingabe als Notiz vor: JSON.parse() liest Felder aus einem strukturierten Formular, während eval() die Notiz einem Interpreter als auszuführende Anweisungen übergibt. JSON.parse() folgt der JSON-Grammatik und führt kein JavaScript aus dem Text aus; die resultierenden Werte müssen vor der Verwendung trotzdem geprüft werden.
// Nicht vertrauenswürdige Daten nicht als Quellcode auswerten.
const data = eval("(" + untrustedJson + ")");
const data = JSON.parse(untrustedJson);
// JSON als Daten parsen; ungültiges JSON löst SyntaxError aus.
Warum diese Frage aufkommt
Bevor JSON.parse() weit verbreitet war, verwendete älterer JavaScript-Code manchmal eval() zum Einlesen von JSON, weil JSON-Text sich mit der Syntax von JavaScript-Ausdrücken überschneidet. Dabei wird ein JavaScript-Programm ausgewertet. Angreifergesteuerte Eingaben können deshalb als Code statt als begrenzte JSON-Werte behandelt werden. Verwende für JSON den JSON-Parser.
Wovor JSON.parse() nicht schützt
JSON.parse() prüft keine Geschäftsregeln, autorisiert keine Aktionen und macht geparste Werte nicht automatisch sicher für HTML, SQL, Shell-Befehle oder URLs. Prüfe die erwartete Datenstruktur und verwende kontextgerechte Ausgabe-Kodierung oder parametrisierte APIs. Wenn du einen reviver übergibst, wird dieser von der Anwendung bereitgestellte Callback während des Parsens ausgeführt. Halte ihn vertrauenswürdig, einfach und frei von Seiteneffekten auf Basis angreifergesteuerter Werte.
Häufige Fragen
Der JSON-Text selbst wird als Daten geparst und nicht als JavaScript ausgeführt. Wenn die Anwendung jedoch einen reviver übergibt, wird dieser vertrauenswürdige Callback für geparste Werte aufgerufen und kann Code ausführen. Lass angreifergesteuerte Daten nicht die ausführbare Callback-Logik auswählen oder erzeugen.
Nein. Prüfe den geparsten Wert anhand des erwarteten Anwendungsschemas und der Autorisierungsregeln. Verwende Ausgabe-Kodierung für HTML und parametrisierte Abfragen für SQL; das Parsen bereinigt Werte nicht für diese Kontexte.