Ich habe in meiner App die Abwehr von CSRF-Angriffen implementiert, nachdem ich Informationen in einem Blogbeitrag im Internet gelesen habe. Insbesondere dieser Beitrag war der Treiber meiner Implementierung
- Best Practices für ASP.NET MVC vom ASP.NET- und Web Tools Developer Content Team
- Anatomie eines Cross-Site Request Forgery Attack von Phil Haack Blog
- AntiForgeryToken im ASP.NET MVC Framework - Html.AntiForgeryToken- und ValidateAntiForgeryToken-Attribut aus dem David Hayden-Blog
Grundsätzlich heißt es in diesen Artikeln und Empfehlungen, dass jeder den folgenden Code implementieren sollte, um den CSRF-Angriff zu verhindern:
1) Fügen Sie [ValidateAntiForgeryToken]
bei jeder Aktion, die das POST-HTTP-Verb akzeptiert, das hinzu
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}
2) Fügen Sie den <%= Html.AntiForgeryToken() %>
Helfer in Formulare ein, die Daten an den Server senden
<div style="text-align:right; padding: 8px;">
<%= Html.AntiForgeryToken() %>
<input type="submit" id="btnSave" value="Save" />
</div>
Wie auch immer, in einigen Teilen meiner App mache ich Ajax-POSTs mit jQuery auf dem Server, ohne überhaupt ein Formular zu haben. Dies geschieht zum Beispiel, wenn ich den Benutzer auf ein Bild klicken lasse, um eine bestimmte Aktion auszuführen.
Angenommen, ich habe eine Tabelle mit einer Liste von Aktivitäten. Ich habe ein Bild in einer Spalte der Tabelle mit der Aufschrift "Aktivität als abgeschlossen markieren". Wenn der Benutzer auf diese Aktivität klickt, führe ich den Ajax-POST wie im folgenden Beispiel aus:
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {},
success: function (response) {
// ....
}
});
});
Wie kann ich das <%= Html.AntiForgeryToken() %>
in diesen Fällen verwenden? Sollte ich den Hilfsaufruf in den Datenparameter des Ajax-Aufrufs aufnehmen?
Entschuldigung für den langen Beitrag und vielen Dank für Ihre Hilfe
EDIT :
Wie pro jayrdub Antwort habe ich in der folgenden Art und Weise verwendet ,
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {
AddAntiForgeryToken({}),
id: parseInt($(this).attr("title"))
},
success: function (response) {
// ....
}
});
});
Antworten:
Ich benutze eine einfache js-Funktion wie diese
Da jedes Formular auf einer Seite den gleichen Wert für das Token hat, fügen Sie einfach so etwas in Ihre oberste Masterseite ein
Dann in Ihrem Ajax-Aufruf tun (bearbeitet, um Ihrem zweiten Beispiel zu entsprechen)
quelle
AddAntiForgeryToken
, wiedata: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
ajaxSend
oder zu überschreiben,ajax
um immerdata
mit dem Anti-Fälschungs-Token zu ergänzen ? Fügen Sie möglicherweise eine Überprüfung hinzu, um sicherzustellen, dass dieurl
für Ihren Server bestimmt ist.Ich mag die von 360Airwalk bereitgestellte Lösung, aber sie kann etwas verbessert werden.
Das erste Problem besteht darin, dass
$.post()
jQuery keinenContent-Type
Header hinzufügt , wenn Sie mit leeren Daten arbeiten. In diesem Fall kann ASP.NET MVC das Token nicht empfangen und überprüfen. Sie müssen also sicherstellen, dass der Header immer vorhanden ist.Eine weitere Verbesserung ist die Unterstützung aller HTTP-Verben mit Inhalten : POST, PUT, DELETE usw. Obwohl Sie in Ihrer Anwendung möglicherweise nur POSTs verwenden, ist es besser, eine generische Lösung zu haben und zu überprüfen, ob alle Daten, die Sie mit einem Verb erhalten, eine Fälschungsbekämpfung aufweisen Zeichen.
quelle
.ajaxSend()
"Ab jQuery 1.8 sollte die .ajaxSend () -Methode nur an das Dokument angehängt werden." api.jquery.com/ajaxsendoptions
, was in der Schlusserklärung aufgeführt istif
? Vielen Dank.Ich weiß, dass es viele andere Antworten gibt, aber dieser Artikel ist nett und prägnant und zwingt Sie, alle Ihre HttpPosts zu überprüfen, nicht nur einige davon:
http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/
Es werden HTTP-Header verwendet, anstatt zu versuchen, die Formularsammlung zu ändern.
Server
Klient
quelle
Ich fühle mich hier wie ein fortgeschrittener Nekromant, aber dies ist 4 Jahre später in MVC5 immer noch ein Problem.
Um Ajax-Anforderungen ordnungsgemäß zu verarbeiten, muss das Anti-Fälschungs-Token bei Ajax-Aufrufen an den Server übergeben werden. Die Integration in Ihre Post-Daten und -Modelle ist chaotisch und unnötig. Das Hinzufügen des Tokens als benutzerdefinierten Header ist sauber und wiederverwendbar - und Sie können es so konfigurieren, dass Sie nicht jedes Mal daran denken müssen, es zu tun.
Es gibt eine Ausnahme: Unauffälliger Ajax benötigt keine spezielle Behandlung für Ajax-Anrufe. Das Token wird wie gewohnt im regulären ausgeblendeten Eingabefeld übergeben. Genau das gleiche wie bei einem normalen POST.
_Layout.cshtml
In _layout.cshtml habe ich diesen JavaScript-Block. Das Token wird nicht in das DOM geschrieben, sondern mithilfe von jQuery aus dem vom MVC-Helper generierten verborgenen Eingabeliteral extrahiert. Die Magic-Zeichenfolge, die der Headername ist, wird in der Attributklasse als Konstante definiert.
Beachten Sie die Verwendung von einfachen Anführungszeichen in der Funktion beforeSend. Das gerenderte Eingabeelement verwendet doppelte Anführungszeichen, die das JavaScript-Literal beschädigen würden.
Client JavaScript
Wenn dies ausgeführt wird, wird die oben genannte Funktion beforeSend aufgerufen und das AntiForgeryToken wird automatisch zu den Anforderungsheadern hinzugefügt.
Serverbibliothek
Ein benutzerdefiniertes Attribut ist erforderlich, um das nicht standardmäßige Token zu verarbeiten. Dies baut auf der Lösung von @ viggity auf, behandelt jedoch unauffälligen Ajax korrekt. Dieser Code kann in Ihrer gemeinsamen Bibliothek versteckt werden
Server / Controller
Jetzt wenden Sie das Attribut einfach auf Ihre Aktion an. Noch besser können Sie das Attribut auf Ihren Controller anwenden und alle Anforderungen werden validiert.
quelle
$.ajaxSetup
einen allgemeinenbeforesend
Eventhandler definieren , kann es vorkommen, dass Sie ihn überschreiben. Ich habe eine andere Lösung gefunden, bei der Sie einen zweiten Handler hinzufügen können, der auch aufgerufen wird. Funktioniert gut und unterbricht Ihre Implementierung nicht.Verwenden Sie nicht Html.AntiForgeryToken . Verwenden Sie stattdessen AntiForgery.GetTokens und AntiForgery.Validate über die Web-API, wie unter Verhindern von CSRF-Angriffen (Cross-Site Request Forgery) in der ASP.NET MVC-Anwendung beschrieben .
quelle
Ich habe gerade dieses eigentliche Problem in meinem aktuellen Projekt implementiert. Ich habe es für alle Ajax-POSTs gemacht, die einen authentifizierten Benutzer brauchten.
Zuerst habe ich mich entschlossen, meine jquery ajax-Anrufe einzuhaken, damit ich mich nicht zu oft wiederhole. Dieses Javascript-Snippet stellt sicher, dass alle Ajax- (Post-) Aufrufe mein Anforderungsvalidierungstoken zur Anforderung hinzufügen. Hinweis: Der Name __RequestVerificationToken wird vom .Net-Framework verwendet, damit ich die unten gezeigten Standard-Anti-CSRF-Funktionen verwenden kann.
Verwenden Sie in Ihren Ansichten, in denen das Token für das oben genannte Javascript verfügbar sein soll, einfach den allgemeinen HTML-Helper. Sie können diesen Code grundsätzlich hinzufügen, wo immer Sie möchten. Ich habe es in eine if-Anweisung (Request.IsAuthenticated) eingefügt:
Verwenden Sie in Ihrem Controller einfach den Standard-ASP.Net MVC Anti-CSRF-Mechanismus. Ich habe es so gemacht (obwohl ich tatsächlich Salt verwendet habe).
Mit Firebug oder einem ähnlichen Tool können Sie leicht sehen, wie an Ihre POST-Anforderungen jetzt ein __RequestVerificationToken-Parameter angehängt ist.
quelle
Ich denke, alles, was Sie tun müssen, ist sicherzustellen, dass die Eingabe "__RequestVerificationToken" in der POST-Anforderung enthalten ist. Die andere Hälfte der Informationen (dh das Token im Cookie des Benutzers) wird bereits automatisch mit einer AJAX POST-Anforderung gesendet.
Z.B,
quelle
AntiForgeryToken
, ist sowieso alles umstritten. Wenn dies der Fall ist (nicht sicher, wie Sie in diesem Fall einen bekommen, aber vorausgesetzt, Sie sind es), würde das oben genannte gut funktionieren. Wenn Sie versuchen, eine einfache Webseite zu erstellen, die eine Anfrage an einen Server sendet, der das Token erwartet, und der Server diese Seite nicht generiert hat, haben Sie kein Glück. Das ist im Wesentlichen der Punkt des AntiForgeryToken ...Sie können dies auch tun:
Dies wird verwendet
Razor
, aber wenn SieWebForms
Syntax verwenden, können Sie genauso gut<%= %>
Tags verwendenquelle
Nach meinem Kommentar gegen die Antwort von @ JBall, der mir dabei geholfen hat, ist dies die endgültige Antwort, die für mich funktioniert. Ich verwende MVC und Razor und sende ein Formular mit jQuery AJAX, damit ich eine Teilansicht mit einigen neuen Ergebnissen aktualisieren kann und kein vollständiges Postback (und Seitenflimmern) durchführen möchte.
Fügen Sie das
@Html.AntiForgeryToken()
Formular wie gewohnt hinzu.Mein AJAX-Übermittlungsschaltflächencode (dh ein Onclick-Ereignis) lautet:
Ich habe die Aktion "Erfolg" beibehalten, da sie zeigt, wie die Teilansicht aktualisiert wird, die ein MvcJqGrid enthält, und wie sie aktualisiert wird (sehr leistungsfähiges jqGrid-Raster und dies ist ein brillanter MVC-Wrapper dafür).
Meine Controller-Methode sieht folgendermaßen aus:
Ich muss zugeben, dass ich kein Fan davon bin, die Daten eines gesamten Formulars als Modell zu veröffentlichen, aber wenn Sie dies tun müssen, ist dies eine Möglichkeit, die funktioniert. MVC macht die Datenbindung einfach zu einfach. Anstatt 16 einzelne Werte (oder eine schwach typisierte FormCollection) einzugeben, ist dies in Ordnung, denke ich. Wenn Sie es besser wissen, lassen Sie es mich bitte wissen, da ich robusten MVC C # -Code erstellen möchte.
quelle
fand diese sehr clevere Idee von https://gist.github.com/scottrippey/3428114 für jeden $ .ajax-Aufruf, der die Anfrage ändert und das Token hinzufügt.
quelle
if (options.contentType != false && options.contentType.indexOf('application/json') === 0) {
, um Ajax-Anrufe1.Definieren Sie die Funktion, um das Token vom Server abzurufen
2. Holen Sie sich das Token und setzen Sie den Header, bevor Sie es an den Server senden
3. Onserver-Validierung in HttpRequestBase für die Methode, die Sie für Post / get verwenden
quelle
Ich bin mir bewusst, dass es einige Zeit her ist, seit diese Frage veröffentlicht wurde, aber ich habe eine wirklich nützliche Ressource gefunden, die die Verwendung von AntiForgeryToken beschreibt und die Verwendung weniger problematisch macht. Es bietet auch ein JQuery-Plugin, mit dem Antiforgery-Token einfach in AJAX-Aufrufe aufgenommen werden können:
Anti-Fälschungs-Anforderungsrezepte für ASP.NET MVC und AJAX
Ich trage nicht viel bei, aber vielleicht findet es jemand nützlich.
quelle
quelle
Hier ist der einfachste Weg, den ich gesehen habe. Hinweis: Stellen Sie sicher, dass Sie "@ Html.AntiForgeryToken ()" in Ihrer Ansicht haben
quelle
Leichte Verbesserung der 360Airwalk-Lösung. Dadurch wird das Anti-Fälschungs-Token in die Javascript-Funktion eingebettet, sodass @ Html.AntiForgeryToken () nicht mehr in jeder Ansicht enthalten sein muss.
quelle
quelle
Ich verwende einen Ajax-Beitrag, um eine Löschmethode auszuführen (stammt zufällig aus einer visjs-Zeitleiste, ist aber nicht relevant). Das ist was ich sis:
Dies ist meine Index.cshtml
Alles, was ich hier hinzugefügt habe, war
@Html.AntiForgeryToken()
, das Token auf der Seite erscheinen zu lassenDann habe ich in meinem Ajax-Post verwendet:
Dadurch wird der von der Seite abgekratzte Token-Wert zu den veröffentlichten Feldern hinzugefügt
Vorher habe ich versucht, den Wert in die Header einzufügen, aber ich habe den gleichen Fehler erhalten
Fühlen Sie sich frei, Verbesserungen zu posten. Dies scheint sicherlich ein einfacher Ansatz zu sein, den ich verstehen kann
quelle
Okay, viele Beiträge hier, keiner von ihnen hat mir geholfen, Tage und Tage von Google, und immer noch nicht weiter, dass ich die ganze App von Grund auf neu geschrieben habe, und dann habe ich dieses kleine Nugget in meiner Web.confg bemerkt
Jetzt weiß ich nicht, warum ich es hinzugefügt habe, aber ich habe seitdem bemerkt, dass es im Debug-Modus und nicht im Produktionsmodus ignoriert wird (IE wird irgendwo auf IIS installiert).
Für mich war die Lösung eine von zwei Optionen, da ich mich nicht erinnere, warum ich sie hinzugefügt habe. Ich kann nicht sicher sein, dass andere Dinge nicht davon abhängen, und zweitens muss der Domain-Name nur in Kleinbuchstaben geschrieben sein und eine TLD muss nicht so sein wie ich in * .localLookup.net
Vielleicht hilft es vielleicht nicht. Ich hoffe es hilft jemandem
quelle
Die Lösung, die ich gefunden habe, ist nicht für ASPX, sondern für Razor, aber ein ziemlich kompromittierbares Problem.
Ich habe es behoben, indem ich der Anfrage die AntiForgery hinzugefügt habe. Der HTML-Helfer erstellt mit dem Aufruf keine HTML-ID
Um das Token zur Nachanforderung hinzuzufügen, habe ich gerade die AntiForgery-ID mit jquery zum ausgeblendeten Feld hinzugefügt:
Dies führte dazu, dass der Controller die Anforderung mit dem Attribut [ValidateAntiForgeryToken] akzeptierte
quelle
AntiforgeryToken ist immer noch ein Schmerz, keines der obigen Beispiele hat Wort für Wort für mich funktioniert. Zu viele dafür sind da. Also habe ich sie alle kombiniert. Benötigen Sie ein @ Html.AntiforgeryToken in einer Form, die um iirc herum hängt
So gelöst:
Fügen Sie im Zweifelsfall weitere $ -Zeichen hinzu
quelle