Welche "vertraulichen Informationen" können beim Festlegen von JsonRequestBehavior auf AllowGet angegeben werden?

112

Ich habe jedes Mal den gleichen alten Fehler erhalten, wenn ich einen neuen Fehler in URLder Adressleiste meines Browsers teste, wenn ich returning Json(unter Verwendung der integrierten Funktion MVC JsonResult helper):

Diese Anfrage wurde blockiert, da vertrauliche Informationen an Websites Dritter weitergegeben werden können, wenn diese in einem verwendet werden GET request. Um dies zuzulassen GET requests, setzen Sie JsonRequestBehaviorauf AllowGet.

Anstatt in der Bestätigung zu grunzen und Fiddler zu veranlassen, eine Post-Anfrage zu stellen, frage ich mich diesmal genau, was genau eine GETAnfrage enthüllt, was eine POSTAnfrage nicht tut?

A. Murray
quelle

Antworten:

82

Angenommen, Ihre Website verfügt über eine GetUserWebmethode:

http://www.example.com/User/GetUser/32

Dies gibt eine JSON-Antwort zurück:

{ "Name": "John Doe" }

Wenn diese Methode nur POST-Anforderungen akzeptiert, wird der Inhalt nur an den Browser zurückgegeben, wenn eine AJAX-Anforderung zur http://www.example.com/User/GetUser/32Verwendung der POST-Methode gestellt wird. Beachten Sie , dass der Browser die Daten vor anderen Domänen schützt, die diese Anforderung an Ihre senden , sofern Sie CORS nicht implementiert haben .

Wenn Sie jedoch GET-Anforderungen zugelassen und eine AJAX-Anforderung ähnlich der oben genannten mit GET anstelle von POST gestellt haben, kann ein böswilliger Benutzer Ihren JSON mithilfe eines scriptTags im HTML- Code in den Kontext seiner eigenen Site aufnehmen . zB am www.evil.com:

<script src="http://www.example.com/User/GetUser/32"></script>

Dieses JavaScript sollte unbrauchbar sein, www.evil.comda es keine Möglichkeit geben sollte, das von Ihrer Webmethode zurückgegebene Objekt zu lesen. Aufgrund von Fehlern in alten Browserversionen (z. B. Firefox 3) ist es jedoch möglich, JavaScript-Prototypobjekte neu zu definieren und www.evil.comIhre von Ihrer Methode zurückgegebenen Daten zu lesen. Dies ist als JSON-Hijacking bekannt.

In diesem Beitrag finden Sie einige Methoden, um dies zu verhindern. Es ist jedoch kein bekanntes Problem mit den späteren Versionen moderner Browser (Firefox, Chrome, IE).

SilverlightFox
quelle
25
Netter Beitrag, aber wenn Sie dem Controller ein [Authorize] -Tag hinzufügen, müssen Sie sich keine Sorgen um die Sicherheit machen. Hoffe, dieser Code wird jemandem helfen, Json (returnMsg, JsonRequestBehavior.AllowGet)
Dhanuka777
17
@ Dhanuka777: Leider nicht wahr. CSRF- Angriffe können möglich sein, wenn die Methode Nebenwirkungen hat (z. B. www.example.com/User/DeleteUser/32), da die Anforderung die zur Authentifizierung erforderlichen Cookies enthält, da diese vom Computer des Opfers stammen. [Authorize]hier im Fall eines sehr alten Browser detaillierten Angriff wird nicht sparen Sie von dem entweder - es ist der Benutzer selbst entscheiden , www.evil.comso die Anforderung www.evil.coman macht www.example.comdie Genehmigung Cookie enthält.
SilverlightFox
1
Und wenn die Aktion irgendwelche Nebenwirkungen hat, sollte sie niemals mit der GET-Methode aufgerufen werden - die Konvention besteht darin, GET nur zum Lesen der Daten zu verwenden, und alle Nebenwirkungen sollten POST, PUT, DELETE usw. verwenden. Mit anderen Worten, I. Denken Sie nur, dass diese Fehlermeldung "vertrauliche Informationen" irreführend ist. Wenn der Entwickler die GET-Methode so verwendet, wie sie verwendet werden sollte, ist alles in Ordnung! :)
ps_ttf
1
Ich bin mir nicht sicher, welchen Unterschied es noch macht. Es ist nicht so, dass Post besser geschützt oder verschlüsselt ist als get. Es ist immer noch nur einfacher Text. Ich kann eine Anfrage genauso einfach senden wie eine Post über ein beliebiges Tool und trotzdem die gleichen Klartextinformationen zurückerhalten. Ein böswilliger Benutzer kann genauso gut serverseitigen Code auf seiner eigenen Site schreiben, um auch einen Beitrag zu verfassen.
Computrius
1
@Castrohenge: Nein, da hierfür ein Header festgelegt werden muss, der nicht mit der GET-Anforderung für das Skript src gesendet wird.
SilverlightFox
111

Verwenden Sie bei Ihrer Rücksendung Folgendes:

return this.Json("you result", JsonRequestBehavior.AllowGet);
OldTrain
quelle
7
Wie beantwortet dies tatsächlich die Frage des OP? Diese Antwort sagt nur allen, wie sie die Ausnahme
umgehen sollen
2
Ja, benutze es. Es ist, als würde man versuchen, mit einem leeren Fang zu fangen. Verwenden Sie diese Jungs nicht (bevor Sie die Risiken verstehen). -1'd
sotn
6
Es ist unverantwortlich, den Leuten zu sagen, dass sie eine Sicherheitswarnung ignorieren sollen, ohne zumindest die Konsequenzen zu erklären. -1
Eduardo Wada
58

Standardmäßig können Sie mit dem ASP.NET MVC-Framework nicht auf eine GET-Anforderung mit einer JSON-Nutzlast antworten, da ein böswilliger Benutzer möglicherweise über einen als JSON-Hijacking bezeichneten Prozess auf die Nutzlast zugreifen kann. Sie möchten keine vertraulichen Informationen mit JSON in einer GET-Anforderung zurückgeben.

Wenn Sie JSON als Antwort auf ein GET senden müssen und keine vertraulichen Daten verfügbar machen, können Sie das Verhalten explizit zulassen, indem Sie es JsonRequestBehavior.AllowGetals zweiten Parameter an die Json Methode übergeben.

Sowie

  [HttpGet] //No need to decorate, as by default it will be GET
  public JsonResult GetMyData(){  
    var myResultDataObject = buildMyData(); // build, but keep controller thin
    // delegating buildMyData to builder/Query Builder using CQRS makes easy :)
    return Json(myResultDataObject, JsonRequestBehavior.AllowGet);
  }

Hier ist ein interessanter Artikel von Phil Haack JSON Hijackingdarüber, warum man Json nicht mit der GET-Methode verwenden sollte

Murali Murugesan
quelle
2
Guter Eintrag. Guter Grund, warum Sie HTTPS verwenden sollten.
pqsk
6
Ich denke nicht, dass HTTPS hier hilft.
Sean McMillan
10

Wenn wir ein JSON-Objekt aus einer MVC-Anwendung an den Client zurückgeben möchten, sollten wir bei der Rückgabe eines Objekts explizit JsonRequestBehavior.AllowGet angeben. Infolgedessen gebe ich die folgenden JSON-Daten zurück, um das Problem zu beheben:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);
Loc Huynh
quelle
7

Sie müssen JsonRequestBehavior.AllowGet für Json Response wie folgt verwenden:

return Json(YourObject, JsonRequestBehavior.AllowGet);
Keivan Kashani
quelle
0

return Json ("Erfolg", JsonRequestBehavior.AllowGet)

Pergin Sheni
quelle