Quali "informazioni sensibili" potrebbero essere divulgate quando si imposta JsonRequestBehavior su AllowGet


112

Ho ricevuto lo stesso vecchio errore ogni volta che ne provo uno nuovo URLdalla barra degli indirizzi del mio browser quando sto returning Json(utilizzando il built-in MVC JsonResult helper):

Questa richiesta è stata bloccata perché informazioni sensibili potrebbero essere divulgate a siti Web di terzi quando vengono utilizzate in un file GET request. Per consentire GET requests, impostare JsonRequestBehaviorsu AllowGet.

Piuttosto che grugnire in segno di riconoscimento e accendere Fiddler per fare una richiesta di post, questa volta, mi chiedo esattamente che cosa è che una GETrichiesta espone che una POSTrichiesta non lo fa?

Risposte:


82

Supponiamo che il tuo sito web abbia un GetUsermetodo web:

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

che restituisce una risposta JSON:

{ "Name": "John Doe" }

Se questo metodo accetta solo richieste POST, il contenuto verrà restituito al browser solo se viene effettuata una richiesta AJAX http://www.example.com/User/GetUser/32utilizzando il metodo POST. Nota che a meno che tu non abbia implementato CORS , il browser proteggerà i dati da altri domini che fanno questa richiesta al tuo.

Tuttavia, se hai consentito le richieste GET, oltre a effettuare una richiesta AJAX simile a quella sopra con GET invece di POST, un utente malintenzionato potrebbe includere il tuo JSON nel contesto del proprio sito utilizzando un scripttag nell'HTML. ad esempio su www.evil.com:

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

Questo JavaScript dovrebbe essere inutile www.evil.comperché non dovrebbe esserci modo di leggere l'oggetto restituito dal tuo metodo web. Tuttavia, a causa di bug nelle vecchie versioni dei browser (es. Firefox 3), è possibile ridefinire gli oggetti prototipo JavaScript e rendere possibile la www.evil.comlettura dei dati restituiti dal metodo. Questo è noto come dirottamento JSON.

Vedi questo post per alcuni metodi per prevenirlo. Tuttavia, non è un problema noto con le versioni successive dei browser moderni (Firefox, Chrome, IE).


25
Bel post, ma se includi un tag [Authorize] nel controller non devi preoccuparti della sicurezza. Spero che questo codice aiuterà qualcuno, Json (returnMsg, JsonRequestBehavior.AllowGet)
Dhanuka777

17
@ Dhanuka777: Purtroppo non è vero. Gli attacchi CSRF potrebbero essere possibili se il metodo ha effetti collaterali (ad es. www.example.com/User/DeleteUser/32) Poiché la richiesta includerà i cookie necessari per l'autenticazione in quanto provengono dalla macchina della vittima. [Authorize]non ti salverà dall'attacco descritto qui nemmeno nel caso di un browser molto vecchio - è l'utente stesso che sta visitando, www.evil.comquindi la richiesta fatta www.evil.coma www.example.comconterrà il cookie di autorizzazione.
SilverlightFox

1
E se l'azione ha effetti collaterali, non dovrebbe mai essere invocata utilizzando il metodo GET: la convenzione è di utilizzare GET solo per leggere i dati e tutte le operazioni con effetti collaterali dovrebbero utilizzare POST, PUT, DELETE, ecc. In altre parole, I basti pensare che questo messaggio di errore "informazioni sensibili" è fuorviante. Se lo sviluppatore utilizza il metodo GET nel modo in cui dovrebbe essere utilizzato, allora va tutto bene! :)
ps_ttf

1
Non sono sicuro di quale differenza faccia ancora. Non è come se il post fosse più protetto o crittografato di get. È ancora solo testo normale. Posso inviare una richiesta con la stessa facilità di un post tramite qualsiasi strumento e ottenere comunque le stesse informazioni di testo normale. Un utente malintenzionato potrebbe scrivere altrettanto facilmente qualsiasi codice lato server sul proprio sito per fare un post.
computrius

1
@Castrohenge: No, perché questo richiede l'impostazione di un'intestazione che non verrà inviata con la richiesta GET per lo script src.
SilverlightFox

111

nel tuo reso usa quanto segue:

return this.Json("you result", JsonRequestBehavior.AllowGet);

7
Come risponde questo effettivamente alla domanda del PO? Tutto ciò che questa risposta fa è dire a tutti come aggirare l'eccezione ..
eaglei22

2
Sì, usalo .. È come provare a catturare con una presa vuota. NON usare questo ragazzi (prima di aver compreso i rischi). -1'd
entro il

6
È irresponsabile dire alle persone di ignorare un avviso di sicurezza senza almeno spiegare le conseguenze. -1
Eduardo Wada

58

Per impostazione predefinita, il framework ASP.NET MVC non consente di rispondere a una richiesta GET con un payload JSON poiché esiste la possibilità che un utente malintenzionato possa accedere al payload tramite un processo noto come JSON Hijacking. Non vuoi restituire informazioni sensibili utilizzando JSON in una richiesta GET.

Se devi inviare JSON in risposta a un GET e non stai esponendo dati sensibili, puoi consentire esplicitamente il comportamento passando JsonRequestBehavior.AllowGetcome secondo parametro alJson metodo.

Ad esempio

  [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);
  }

Ecco un interessante articolo di Phil Haack JSON Hijackingsul perché non usare Json con il metodo GET


2
Ottimo post. Un buon motivo per cui dovresti usare HTTPS.
pqsk

6
Non penso che HTTPS aiuti qui.
Sean McMillan

10

Quando vogliamo restituire un oggetto json al client dall'applicazione MVC, dobbiamo specificare esplicitamente JsonRequestBehavior.AllowGet quando restituiamo un oggetto. Di conseguenza, restituisco i dati json come di seguito per superare il problema:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);

7

Devi usare JsonRequestBehavior.AllowGet per la risposta Json in questo modo:

return Json(YourObject, JsonRequestBehavior.AllowGet);

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.