2009-02-16 8 views
5

Ich weiß, wie man MVCs AntiForgeryToken-Attribut und seinen assoziierten HTML-Helfer benutzt, um XSRF-sicher die Formular-POSTs meiner Anwendung zu unterstützen.Wie sichere ich meine JsonResult GET-Anrufe?

Kann etwas Ähnliches für JsonResults getan werden, die GET implementieren?

Zum Beispiel meiner Ansicht enthält einen onSubmit jQuery Aufruf wie so:

$.getJSON("/allowActivity/YesOrNo/" + someFormValue, "{}", function(data) { 
    if(data.Allow) { 
    //Do something. 
    } 
}); 

ich sicher machen will, dass diese JsonResult von der beabsichtigten Seite nur aufrufbar ist.

EDIT:

fand ich this post über eine ähnliche Frage, ohne konkrete Antwort.

Was ist der einfachste Weg um sicherzustellen, dass meine GET (nicht-destruktive) URL nur von einem AJAX-Aufruf von meiner eigenen Seite konsumiert wird?

Antwort

8

Sie können das AntiForgeryToken in Kombination mit einer benutzerdefinierten Logik verwenden. Die Erstellung des AntiForgen-Tokens auf dem Server ist identisch, aber standardmäßig ist der Wert nicht in Ihrer XmlHttpRequest enthalten.

Der Wert dieses Tokens befindet sich im HTTP-only-Cookie "__RequestVerificationToken" und sollte auch in den Formdaten enthalten sein, die auf dem Server veröffentlicht sind. So sind ein Schlüssel/Wert-Paar in Ihrem XmlHttpRequest und verwenden Sie die ValidateAntiForgeryToken - Attribut auf dem Controller

EDIT:

Heute habe ich versucht, die AntiForgeryToken für Ajax fordert mich und es funktioniert gut. Verwenden Sie einfach das folgende Javascript:

$.post('my_url', $.getAntiForgeryTokenString(), function() { ... }); 

$.getAntiForgeryTokenString = function() { 
    return $(document.getElementsByName("__RequestVerificationToken")).fieldSerialize(); 
}; 

Auf der Serverseite Sie müssen nicht Ihren Code ändern - benutzen Sie einfach die ValidateAntiForgeryToken- Attribut für Ihre Aktion.

this helps

+0

Wie würden Sie die __RequestVerificationToken Wert mit dem $ .getJSON oder $ Schnipsel Aufruf integrieren? Denken Sie daran, dies ist eine GET-Anfrage. –

+0

Lesen Sie "Offenlegung von Token in URL" von http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet "Wenn sensible serverseitige Aktionen garantiert immer nur auf POST-Anfragen reagieren, dann Sie müssen das Token nicht in GET-Requests einschließen. "Der Schlüssel besteht darin, sicherzustellen, dass Ihr GET keine Daten ändert. Andernfalls müssen Sie GET-Anforderungen nicht schützen. –

0

Sie können etwas ähnliches wie die Anti-XSRF-Methoden tun. Erzeugen Sie einfach eine ID, fügen Sie sie in das Javascript ein und wenn der Benutzer Ihre JSON-URL aufruft, lassen Sie diese URL die generierte ID enthalten und prüfen Sie, ob sie dort ist.

Eine Verteidigung gegen XSRF verwendet auch die Sitzungs-ID als Schlüssel, dies hindert den Benutzer jedoch nicht, es von einer anderen Website für seinen eigenen Account auszuführen.

Einige Hash basierend auf der Sitzung und Zeit könnte den Trick tun. Natürlich, wenn der Benutzer den Wert aus dem JS kopiert, kann er es trotzdem von einem anderen Ort aus ausführen, aber Sie können diesen Wert alle x Minuten ablaufen lassen. Eine andere Möglichkeit besteht darin, einen Cookie mit JS zu setzen und ihn serverseitig zu lesen.

Hoffe, das gibt Ihnen einige Ideen, um loszulegen.

1

Zunächst einmal, warum nicht .post $ verwenden (url, Daten, Rückruf, 'json') anstelle von getJSON? Und wie kleolb02 sagte, können Sie Wert aus dem Cookie auf die Post-Daten hinzufügen cookie plugin mit - {__RequestVerificationToken: $ .cookie ('__ RequestVerificationToken')}

+0

Das klingt gut. Ich hatte gehofft, POST für solch einen einfachen Ajax-Anruf zu vermeiden, aber ich werde es sicher tun, wenn es der einzige Weg ist, es zu sichern. –

+0

Sie sollten Post verwenden, um einige Daten auf dem Server zu aktualisieren. Dies ist ein häufiges Szenario. Und soweit ich mich erinnere, arbeiten AntiForgeryToken nur mit Post-Anfragen (sie suchen nur in FormCollection nach einem Wert). – zihotki

+0

Dies ist kein Update, es ist ein einfaches "Get". Ich möchte einfach den Verbrauch der URL auf die AJAX-Aufrufe meiner eigenen Seite beschränken. –

1

ich ähnlichen Code in einem ASP.NET MVC-Projekt verwendet habe, zu verwenden, auf die Unschärfefunktion eines Elements, ohne eine Ajax-Form zu haben. Dieser Code ermöglicht das Füllen eines Textfelds mit Serverdaten, wenn ein bestimmtes HTML-Element Blur-Ereignis auftritt.

Hoffe das hilft auch. Hier ist mein Code:

Javascript:

var mytext = { 'myText': 'example text' }; 
$.post('/MyController/JsonResultMethod', AddAntiForgeryToken(myText), function (resultData) { 
     $('#htmlElement').val(resultData); 
}); 
AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

C-Sharp-Code:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public JsonResult SeoString(string myText) 
    { 
     try 
     { 
      // do something here 
      return this.Json("result text"); 
     } 
     catch (Exception) 
     { return this.Json(string.Empty); } 
    }