FlawOpen

flawopen.com/JSON-Parsing/JSON.parse() vs eval()

Ist JSON.parse() sicherer als eval()?

Referenzleitfaden
Kurzantwort

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.

GEFÄHRLICH — altes Muster
// Nicht vertrauenswürdige Daten nicht als Quellcode auswerten.
const data = eval("(" + untrustedJson + ")");
SICHER
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

Kann JSON.parse() Anwendungscode ausführen?

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.

Macht JSON.parse() Eingaben für die spätere Verwendung sicher?

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.

Quellen

Siehe auch JavaScript Prototype Pollution: Ursachen und Schutz Ist lodash.merge() vor Prototype Pollution sicher? Object.assign() und Prototype Pollution: Was ist sicher? Verursacht JSON.parse() Prototype Pollution?