Ich verstehe, dass die Verwendung von eval(json_str)
auf dem Client anfällig für bösartigen Code ist. Meine Frage ist, wenn json_str
ein Array wäre, das durch die PHP-Funktion json_encode
erstellt würde, wäre ich sicher?
Zum Beispiel
%Vor% Wäre es jetzt völlig sicher, eval(json_str)
im clientseitigen Code zu verwenden?
Ja und nein:
Ja: PHP erzeugt gültige JSON
Nein: PHP kann auch bösartigen Code wie in JSON zurückgeben.
Wenn Sie der Quelle vertrauen können oder wenn Sie sogar die volle Kontrolle darüber haben (weil es Ihre ist), gibt es kein Problem.
Was pures JavaScript angeht, ja, Sie sind sicher: Die Ausgabe von json_encode
kann niemals etwas anderes als statische Werte enthalten, die keine unerwartete Seite haben, wenn sie an eval
übergeben wird. (Obwohl Sie normalerweise Ihre JSON-Zeichenfolge mit ()
umgeben müssen, wenn Sie eval
verwenden, um zu vermeiden, dass ein Objektliteralausdruck als Anweisungsblock falsch interpretiert wird.)
Nebenbei: Dies gilt nicht unbedingt für alle JSON-Encoder, da einige Zeichen in einer JSON-Zeichenfolge enthalten sind, die in JavaScript nicht gültig sind. Vor allem U + 2028 und U + 2029, die in JavaScript-String-Literalen nicht unausgearbeitet bleiben können, da sie Zeilenumbrüche darstellen. Der Encoder von PHP codiert jedoch alle Nicht-ASCII-Zeichen (zB als "\u2028"
), daher ist das hier kein Problem.
Im Hinblick auf JavaScript, das in eine andere Sprache eingebettet ist (normalerweise HTML), sind Sie nicht unbedingt sicher. Zum Beispiel:
%Vor% Was ist in diesem Beispiel, wenn value
eine Zeichenfolge mit der Zeichenfolge </script
enthält? Dies würde es dem Wert ermöglichen, den Skriptblock vorzeitig zu beenden und somit in HTML-Markup zu gelangen, wo er dann andere bösartige Skripte injizieren könnte.
Um dieses Problem zu vermeiden, codieren Sie beim Einfügen von JSON-Inhalt in HTML immer das Zeichen <
in Zeichenfolgenliteralen als \x3C
oder in JSON-kompatiblen Begriffen \u003C
. Um Kompatibilität mit XHTML-Nicht-CDATA-Skriptblöcken zu gewährleisten, verwenden Sie auch &
. Um die Kompatibilität mit JS innerhalb von Event-Handler-Attributen sicherzustellen, müssen Sie auch Anführungszeichen verwenden.
PHP macht das für Sie mit den richtigen Optionen zu json_encode()
:
(Sie können eine Verknüpfungsfunktion definieren, um das Schreiben zu beschleunigen.)
Wenn Sie Content Security Policy (CSP) verwenden möchten, können Sie keine Inline-Skript-Tags ausführen. Dies würde also bodinces ansonsten erstaunliche Antwort unmöglich machen, da CSP erfordert, dass alle JavaScript-Dateien in separaten Dateien gespeichert sind.
Ein Weg, dies zu umgehen, besteht darin, den JSON mit PHP zu kodieren (was XSS verhindern sollte) und dann auf ein verstecktes Element zu übertragen und dann JavaScript zu verwenden, um den Inhalt dieses Tags zu erhalten (angepasst von OWASP ):
Fügen Sie dies inline ein (beachten Sie, dass es nicht ausgeführt wird):
%Vor%Dann in Ihrer JavaScript-Datei:
%Vor%Tu es nicht.
Es ist sehr wahrscheinlich, dass Ihr Server niemals kompromittiert wird und dass Ihre Anwendung meist sicher ist, bla bla bla, das ist nicht der Punkt. Es ist möglich, dass ein Server teilweise kompromittiert wird (zu viele Angriffsvektoren, was ist, wenn die PHP json_encode
-Funktion auf Ihrem Server kompromittiert wurde?).
Die einfache Lösung besteht nicht darin, irgendetwas zu vertrauen, das von irgendjemand gesendet wurde. Moderne Browser haben native JSON-Parser und www.json.org bietet eine lange Liste von JSON-Parsern für verschiedene Sprachen. Die JS-Versionen werden auf die native Implementierung für Geschwindigkeit zurückgreifen.
Was das alles bedeutet, ist, dass keinen Grund gibt, eval
für das JSON-Parsing zu verwenden.
Es sollte sicher sein, aber auf dem Client wird nicht garantiert, dass json_str
nicht von einer anderen Quelle injiziert wurde.