Ist es möglich, JSON-Antworten mit dem richtigen JavaScript-String-Escape durch XSS auszunutzen?

Lesezeit: 9 Minuten

Benutzer-Avatar
Chris Mountford

JSON-Antworten können ausgenutzt werden, indem Array-Konstruktoren überschrieben werden oder wenn feindliche Werte nicht mit JavaScript-String-Escapezeichen versehen werden.

Nehmen wir an, beide Vektoren werden auf normale Weise adressiert. Google fängt die direkte Beschaffung von JSON-Antworten bekanntermaßen ab, indem es allen JSON-Dateien etwas voranstellt wie:

throw 1; < don't be evil' >

Und dann folgt der Rest des JSON. Dr. Evil kann dies also nicht, indem er die Art von Exploit verwendet, die besprochen wurde hier. Holen Sie sich Ihr Cookie (vorausgesetzt, Sie sind eingeloggt), indem Sie Folgendes auf seine Website stellen:

<script src="http://yourbank.com/accountStatus.json"> 

Was die String-Escape-Regeln angeht, nun, wenn wir doppelte Anführungszeichen verwenden, müssen wir jedem Backslash einen Backslash voranstellen und jedem Backslash einen weiteren Backslash usw.

Aber meine Frage ist, was ist, wenn Sie das alles tun?

Burp-Suite (das automatisierte Sicherheitstool) erkennt eingebettete XSS-Versuche, die in einer JSON-Antwort ohne HTML-Escapezeichen zurückgegeben werden, und meldet dies als XSS-Schwachstelle. Mir wurde gemeldet, dass meine Anwendung Sicherheitslücken dieser Art enthält, aber ich bin nicht davon überzeugt. Ich habe es versucht und kann einen Exploit nicht zum Laufen bringen.

Also das finde ich nicht richtig.

Es gibt einen speziellen Fall, nämlich das IE-MIME-artige Sniffing, von dem ich glaube, dass es zu einem Exploit führen könnte. Immerhin hatte IE 7 noch das “Feature”, dass in Bildkommentare eingebettete Script-Tags unabhängig vom Content-Type-Header ausgeführt wurden. Lassen wir ein solches offensichtlich dummes Verhalten erstmal beiseite.

Sicherlich würde der JSON entweder vom nativen JavaScript-Parser (Window.JSON in Firefox) oder von einem eval() gemäß dem alten Standard-jQuery-Verhalten. In keinem Fall würde der folgende Ausdruck dazu führen, dass die Warnung ausgeführt wird:

{"myJSON": "legit", "someParam": "12345<script>alert(1)</script>"}

Habe ich recht oder liege ich falsch?

Benutzer-Avatar
Turm

Diese potenzielle xss-Schwachstelle kann vermieden werden, indem die richtige verwendet wird Content-Type. Bezogen auf RFC-4627 Alle JSON-Antworten sollten die verwenden application/json Typ. Der folgende Code ist nicht angreifbar zu xss, testen Sie es:

<?php
header('Content-type: application/json'); 
header("x-content-type-options: nosniff");
print $_GET['json'];
?>

Das nosniff Header wird verwendet, um Content-Sniffing in alten Versionen von Internet Explorer zu deaktivieren. Eine andere Variante ist wie folgt:

<?php
header("Content-Type: application/json");
header("x-content-type-options: nosniff");
print('{"someKey":"<body onload=alert(\'alert(/ThisIsNotXSS/)\')>"}');
?>

Wenn der obige Code von einem Browser angezeigt wird, wurde der Benutzer aufgefordert, eine JSON-Datei herunterzuladen. das JavaScript wurde auf modernen Versionen von Chrome, FireFox und Internet Explorer nicht ausgeführt. Dies wäre eine RFC-Verletzung.

Wenn Sie JavaScript verwenden, um eval() das JSON oben oder schreiben Sie die Antwort auf die Seite, dann wird es DOM-basiertes XSS. DOM-basiertes XSS wird auf dem Client gepatcht, indem JSON bereinigt wird, bevor auf diese Daten reagiert wird.

  • OK, ich nehme an, ich hätte es klarer machen können, aber die JSON-Antwort, von der ich spreche, wird durch das Vorhandensein des Content-Type-Headers mit dem Wert „application/json“ definiert. Sie scheinen also zu bestätigen, dass es keinen Exploit gibt. Kann Ihr Code nicht durch direktes Sourcing auf einer feindlichen Domäne ausgenutzt werden, d. h. durch Verwenden des Skript-Tags und Parametrisieren der Quelle, um Code einzuschließen, der dann im Kontext der Domäne ausgeführt wird, von der er stammt? In diesem Fall wären die Cookies dieser Domain zugänglich und könnten von der aufrufenden Seite mit document.write erfasst werden. Recht?

    – Chris Mountford

    1. Juli 2010 um 4:44 Uhr


  • @Chris Mountford Das injizierte JavaScript wird nicht ausgeführt, da der Server dem Browser dies auch nicht mitteilt. Stellen Sie sich das so vor: Was wäre, wenn Sie JavaScript in einer .exe-Datei hätten? Dies könnte führen Dom-basiertes XSS, aber andere Designs könnten das auch. Dom-basiertes xss wird mit derselben Richtlinie ausgeführt, von der aus es ausgeführt wird. Die einzige Möglichkeit, dass dies ein Problem für Sie sein kann, ist, wenn Sie es sind eval()ing den Code auf Ihrer eigenen Website.

    – Turm

    1. Juli 2010 um 6:23 Uhr

  • Mein Verständnis war, dass JSON in der Vergangenheit sehr häufig eval() war, zumindest standardmäßig auf jQuery (wie gesagt). Ich interessiere mich jedoch nicht für die JavaScript-Injection, sondern für die HTML-Injection in JSON, die zur Ausführung von JavaScript führt. Können Sie dazu etwas sagen? Wie ich bereits sagte, kann IE, so neu wie v7, den Content-Type-Header unter bestimmten Umständen IGNORIEREN. Ja, das ist ein Fehler im IE, aber Microsoft hat nein argumentiert (unabhängig vom RFC) und am Ende ist es aus Sicherheitsgründen nur wichtig, was die Browser tun, nicht was die Spezifikation sagt.

    – Chris Mountford

    1. Juli 2010 um 23:54 Uhr

  • Rook, ich habe es noch nicht im Detail gelesen, also verzeihen Sie mir, wenn ich mich verlesen habe oder einfach nur dumm bin, aber ich glaube das diesen Blogbeitragbereitgestellt von @anon unten, beschreibt einen Angriff, durch den Internet Explorer dazu gebracht werden kann, Antworten mit dem zu behandeln application/json Inhaltstyp, als ob es sich um HTML handeln würde, was reflektierte XSS-Angriffe trotz des Headers ermöglicht. Wenn ich das alles richtig verstehe, bedeutet das, dass Ihre Antwort hier falsch ist. Vielleicht magst du dir das mal anschauen?

    – Mark Amery

    13. Januar 2014 um 10:54 Uhr


  • @Rook Sie haben den Beitrag zu früh entlassen. Das bisschen über eval war in einer Einführungspassage über bereits bekannte Exploits und gilt offensichtlich nur, wenn die JSON-Antwort irgendwo mit geparst wird eval. Wenn Sie weiterlesen, beginnt die eigentlich beschriebene Schwachstelle nach der Zeile, die besagt Wir haben eine Möglichkeit entdeckt, JSON-Antworten im IE durch direktes Durchsuchen zu rendern. Ich habe meine eigene Antwort gepostet, die dies beschreibt (obwohl die schmerzhafte Detailgenauigkeit für Leute gedacht ist, die mit XSS nicht vertraut sind – ich weiß, dass es für Sie nicht notwendig ist!)

    – Mark Amery

    18. Januar 2014 um 23:38 Uhr


Benutzer-Avatar
Alexej Lebedew

Burpsuite (das automatisierte Sicherheitstool) erkennt eingebettete XSS-Versuche, die in einer JSON-Antwort ohne HTML-Escapezeichen zurückgegeben werden, und meldet dies als XSS-Schwachstelle.

Möglicherweise versucht es, die im beschriebene Schwachstelle zu verhindern Regel 3.1 des OWASP XSS-Spickzettels.

Sie geben das folgende Beispiel für anfälligen Code:

<script>
    var initData = <%= data.to_json %>;
</script>

Selbst wenn doppelte Anführungszeichen, Schrägstriche und Zeilenumbrüche korrekt maskiert sind, können Sie aus JSON ausbrechen, wenn es in HTML eingebettet ist:

<script>
    var initData = {"foo":"</script><script>alert('XSS')</script>"};
</script>

jsFiddle.

to_json() -Funktion kann dieses Problem verhindern, indem jedem Schrägstrich ein umgekehrter Schrägstrich vorangestellt wird. Wenn JSON im HTML-Attribut verwendet wird, muss die gesamte JSON-Zeichenfolge HTML-escaped sein. Wenn es in einem verwendet wird href="javascript:" -Attribut muss URL-escaped sein.

  • Dies ist ein sehr grundlegender Fehler in PHP (ich nehme an, es ist PHP). Sie dürfen keine verdorbenen Daten in HTML einfügen, ohne dass HTML maskiert wird. Aber wie ich in meiner Frage angedeutet habe, tue ich dies nicht. Obwohl es möglich ist, dass Burpsuite versucht, dieses Problem zu verhindern, ist dieser Ansatz fehlgeleitet.

    – Chris Mountford

    21. Januar 2014 um 10:14 Uhr


  • Welcher Ansatz ist falsch? Ich verstehe Sie nicht. Was “Sie dürfen keine verdorbenen Daten in HTML ohne HTML-Escapezeichen einbetten” angeht, raten Sie mal, Sie sollten nicht einmal unverdorbene Daten ohne Escapezeichen einbetten.

    – Alexej Lebedew

    21. Januar 2014 um 11:06 Uhr

  • Die Frage, was Sie inline können, liegt völlig außerhalb des Bereichs dieser Frage. Sie können natürlich unbefleckte Daten einbetten, wenn diese Daten aus HTML bestehen. In der Tat, wenn Sie HTML haben und es MIT Escapezeichen einbetten, erhalten Sie am Ende eine Ausgabe mit doppeltem Escapezeichen, was zwar kein Sicherheitsfehler, aber immer noch ein Fehler ist. Der Ansatz, den ich als fehlgeleitet bezeichne, ist der Versuch, „die in Regel 3.1 des OWASP XSS Cheat Sheet beschriebene Schwachstelle zu verhindern“, den Sie als Absicht von Burpsuite vorschlagen. Wenn Ihr Vorschlag über Burpsuite wahr ist, dann sind sie fehlgeleitet.

    – Chris Mountford

    22. Januar 2014 um 6:11 Uhr


Benutzer-Avatar
anon

Wenn wir unseren Anwendungsbereich auf IE (alle Versionen) beschränken, davon ausgehen, dass Sie eine Website auf Basis von PHP oder ASP.NET betreiben und den IE-Anti-XSS-Filter ignorieren, dann liegen Sie falsch: Ihre Benutzer sind anfällig. Einstellung 'Content-type: application/json' wird auch nicht helfen.

Dies ist (wie Sie bereits erwähnt haben) auf das Inhaltserkennungsverhalten von IE zurückzuführen, das über das Sniffing nach HTML-Tags im Antworttext hinausgeht und eine URI-Analyse umfasst.

Dieser Blogbeitrag erklärt dies sehr gut:

https://www.adico.me/post/json-based-xss-exploitation

  • OK, aber der URI steht immer noch vollständig unter der Kontrolle des Servers.

    – Chris Mountford

    3. April 2012 um 3:08 Uhr

  • Ich sehe, dass das Sniffing-Verhalten von IE mehrere mögliche Angriffsvektoren schafft, aber das Ändern der Pfadinformationen ist in meiner Anwendung nicht möglich. Außerdem kann ich dieses Sniffing-Problem endlich lösen, da die IE-Version 8+ das MIME-Sniffing wie folgt deaktiviert: X-Content-Type-Options: nosniff Für alle, die dies lesen, ich glaube, ich habe festgestellt, dass JSON sicher Werte übertragen kann mit verdorbenen Benutzereingaben, solange sie JSON-Wert-codiert sind, und natürlich sollte sie niemals ohne clientseitige HTML-Codierung an ein HTML-DOM angehängt werden.

    – Chris Mountford

    3. April 2012 um 3:14 Uhr

  • Zur Verdeutlichung, ich meine, es gibt keine Möglichkeit für Angreifer, ihre eigenen Pfadinformationen zu wählen. Das bedeutet, dass meine App keine Schwachstelle in dieser Kategorie aufweist. Außerdem habe ich in meiner ursprünglichen Frage angegeben, dass ich die Frage nach dem MIME-Sniffing von IE beiseite legen wollte, weil ich mich auf andere Kategorien konzentrieren wollte (ich hatte bereits eine Problemumgehung für das MIME-Sniffing von IE).

    – Chris Mountford

    3. April 2012 um 6:17 Uhr

Für die Aufzeichnung, obwohl ich eine Antwort akzeptiert habe, hatte ich für die genaue wörtliche Frage, die ich stelle, Recht und es gab keine Schwachstelle aufgrund des Vorhandenseins von nicht HTML-escaped, aber korrekt JSON-escaped HTML in JSON-Werten. Es könnte dort einen Fehler geben, wenn dieser Wert ohne clientseitiges Escaping in das DOM eingefügt würde, aber Burpsuite hat kaum eine Chance zu wissen, ob dies passieren würde, indem es sich nur den Netzwerkverkehr ansieht.

Im allgemeinen Fall der Bestimmung, was unter diesen Umständen eine Sicherheitslücke ist, ist es aufschlussreich zu erkennen, dass der Antwortinhalt eines JSON-Werts, obwohl es sich nicht wie ein gutes Design anfühlt, legitimerweise bekannt sein könnte, dass er sicherlich keine Benutzereingaben enthält und dies beabsichtigt ist bereits gerenderter HTML-Code sein, um ohne Escapezeichen sicher in das DOM eingefügt zu werden. Es zu umgehen, wäre ein (nicht sicherheitsrelevanter) Fehler, wie ich in einem anderen Kommentar erwähnt habe.

1245070cookie-checkIst es möglich, JSON-Antworten mit dem richtigen JavaScript-String-Escape durch XSS auszunutzen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy