Grundlegendes zu Cross-Site Request Forgery in .NET

Sie können sichere Webanwendungen nur unter Berücksichtigung der Sicherheit von Anfang an erstellen. Dies erfordert das Nachdenken über die möglichen Angriffe auf Ihre Website, wenn Sie jede Seite, jedes Formular und jede Aktion erstellen. Es ist auch erforderlich, die häufigsten Arten von Sicherheitsproblemen zu verstehen und deren Behebung.

Bei der häufigsten Sicherheitslücke auf einer Webseite kann ein Angreifer Befehle für einen Benutzer ausführen, die dem Benutzer jedoch nicht bekannt sind. Bei dem Angriff für fälschungsübergreifende Anfragenfälschungen wird das Vertrauen genutzt, das eine Website mit dem Webbrowser eines Benutzers bereits aufgebaut hat.

In diesem Lernprogramm werden wir erläutern, was ein Angriff für einen fälschungsseitigen Request-Fälschungsangriff ist und wie er ausgeführt wird. Dann erstellen wir eine einfache ASP.NET-MVC-Anwendung, die für diesen Angriff anfällig ist, und beheben die Anwendung, um zu verhindern, dass sie erneut auftritt.


Was ist Cross-Site Request Forgery??

Bei dem Angriff für fälschungsübergreifende Anfragenfälschungen wird zunächst davon ausgegangen, dass sich das Opfer bereits auf einer Zielwebsite authentifiziert hat, z. B. auf einer Bank-Site, Paypal oder einer anderen Site, die angegriffen werden soll. Diese Authentifizierung muss so gespeichert werden, dass der Benutzer, wenn er die Website verlässt und zurückkehrt, immer noch als von der Zielwebsite angemeldet gilt. Der Angreifer muss dann das Opfer dazu bringen, auf eine Seite oder einen Link zuzugreifen, der eine Anfrage oder einen Post an die Zielwebsite ausführt. Wenn der Angriff erfolgreich ist, wird auf der Zielwebsite eine Anfrage des Opfers angezeigt, und die Anfrage wird als dieser Benutzer ausgeführt. Dadurch kann der Angreifer als Opfer jede auf der Zielwebsite gewünschte Aktion ausführen. Das mögliche Ergebnis könnte Geld überweisen, ein Kennwort zurücksetzen oder eine E-Mail-Adresse auf der Zielwebsite ändern.

Wie der Angriff funktioniert

Um das Opfer dazu zu bringen, einen Link zu verwenden, müssen Sie nicht auf einen Link klicken. Ein einfacher Bildlink könnte ausreichen:

Das Einfügen eines solchen Links in einen ansonsten scheinbar harmlosen Forenbeitrag, einen Blogkommentar oder eine Social-Media-Site könnte einen Benutzer nicht wahrnehmen. Komplexere Beispiele verwenden JavaScript, um eine vollständige HTTP-Post-Anfrage zu erstellen und an die Zielwebsite zu senden.


Erstellen einer anfälligen Webanwendung in ASP.NET MVC

Erstellen Sie eine einfache ASP.NET-MVC-Anwendung, die für diesen Angriff anfällig ist. Ich verwende Visual Studio 2012 für diese Beispiele. Dies funktioniert jedoch auch in Visual Studio 2010 oder Visual Web Developer 2010, wenn Sie Unterstützung für MVC 4 installiert haben, das von Microsoft heruntergeladen und installiert werden kann.


Beginnen Sie mit dem Erstellen eines neuen Projekts und wählen Sie die Verwendung der Internetprojekt Vorlage. Die View Engine funktioniert zwar, aber hier verwende ich die ASPX-View-Engine.

Wir fügen ein Feld zur UserProfile-Tabelle hinzu, um eine E-Mail-Adresse zu speichern. Unter Server Explorer erweitern Datenverbindungen. Sie sollten das sehen Standardverbindung erstellt mit den Informationen für die Logins und Mitgliedschaften. Klicken Sie mit der rechten Maustaste auf Benutzerprofil Tabelle und klicken Sie auf Öffnen Sie die Tabellendefinition. In der Leerzeile unter Nutzername In der Tabelle fügen wir eine neue Spalte für die E-Mail hinzu. Benennen Sie die Spalte E-Mail-Addresse, geben Sie den Typ an nvarchar (MAX), und überprüfen Sie die Nullen zulassen Möglichkeit. Klicken Sie jetzt auf Aktualisieren um die neue Version der Tabelle zu speichern.

Dies gibt uns eine grundlegende Vorlage für eine Webanwendung mit Anmeldeunterstützung, die der von vielen Autoren am Anfang der Erstellung einer Anwendung ähnelt. Wenn Sie die App jetzt ausführen, wird sie angezeigt und ist funktionsfähig. Drücken Sie F5 oder verwenden DEBUG -> Starten Sie das Debuggen aus dem Menü, um die Website aufzurufen.


Erstellen wir ein Testkonto, das wir für dieses Beispiel verwenden können. Klicke auf das Registrieren Verknüpfen und erstellen Sie ein Konto mit einem beliebigen Benutzernamen und Passwort, das Sie möchten. Hier benutze ich ein Konto namens Testbenutzer. Nach der Erstellung werden Sie sehen, dass ich jetzt als Testbenutzer angemeldet bin. Wenn Sie dies getan haben, beenden Sie das Programm und fügen Sie dieser Anwendung eine Seite hinzu, damit der Benutzer seine E-Mail ändern kann.


Bevor wir diese Seite erstellen, um die E-Mail-Adresse zu ändern, müssen Sie zunächst eine Änderung an der Anwendung vornehmen, damit der Code die gerade hinzugefügte neue Spalte erkennt. Öffne das AccountModels.cs Datei unter der Modelle Ordner und aktualisieren Sie die Benutzerprofil Klasse, um die folgenden zu finden. Dies informiert die Klasse über unsere neue Spalte, in der wir die E-Mail-Adresse für das Konto speichern.

[Table ("UserProfile")] public Klasse UserProfile [Schlüssel] [DatabaseGeneratedAttribute (DatabaseGeneratedOption.Identity)] public int UserId get; einstellen;  öffentliche Zeichenfolge Benutzername get; einstellen;  public string EmailAddress get; einstellen; 

Öffne das AccountController.cs Datei. Nach dem RemoveExternalLogins Funktion fügen Sie den folgenden Code hinzu, um eine neue Aktion zu erstellen. Dadurch wird die aktuelle E-Mail für den angemeldeten Benutzer abgerufen und an die Ansicht für die Aktion übergeben.

public ActionResult ChangeEmail () // Liefert die angemeldete Benutzerzeichenfolge username = WebSecurity.CurrentUserName; Zeichenfolge currentEmail; using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == Benutzername); currentEmail = user.EmailAddress;  return View (aktuelleEmail); 

Wir müssen auch die entsprechende Ansicht für diese Aktion hinzufügen. Dies sollte eine Datei mit dem Namen sein ChangeEmail.aspx unter dem Ansichten \ Konto Mappe:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  E-Mail Adresse ändern   

E-Mail Adresse ändern

Aktuelle E-Mail-Adresse: <%= Model ?? "Keine aktuelle E-Mail"%>

<% using(Html.BeginForm()) %> <% %>

Dies gibt uns eine neue Seite, auf der wir die E-Mail-Adresse des aktuell angemeldeten Benutzers ändern können.


Wenn wir diese Seite aufrufen und zum gehen / Konto / ChangeEmail Aktion, sehen wir, dass wir derzeit keine E-Mail haben. Wir haben jedoch ein Textfeld und eine Schaltfläche, mit der wir das korrigieren können. Zunächst müssen wir jedoch die Aktion erstellen, die ausgeführt wird, wenn das Formular auf dieser Seite gesendet wird.

[HttpPost] public ActionResult ChangeEmail (ChangeEmailModel-Modell) Zeichenfolge Benutzername = WebSecurity.CurrentUserName; using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == Benutzername); user.EmailAddress = model.NewEmail; db.SaveChanges ();  // Um ​​die Änderung zu bestätigen, rufen Sie die E-Mail aus dem Profil ab. ChangeEmailModel newModel = new ChangeEmailModel (); using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.UserName.ToLower () == Benutzername); newModel.CurrentEmail = user.EmailAddress;  return Ansicht (neuesModel); 

Nachdem Sie diese Änderung vorgenommen haben, rufen Sie die Website auf und gehen Sie erneut zu / Konto / ChangeEmail Aktion, die wir gerade geschaffen haben. Sie können jetzt eine neue E-Mail-Adresse eingeben und auf die Schaltfläche klicken Ändern Sie die E-Mail und stellen Sie sicher, dass die E-Mail-Adresse aktualisiert wird.


Angriff auf die Site

Wie bereits erwähnt, ist unsere Anwendung anfällig für einen Angriff, der Angriffe durch verschiedene Standorte verursacht. Fügen Sie eine Webseite hinzu, um diesen Angriff in Aktion zu sehen. Wir werden auf der Website eine Seite hinzufügen, die die E-Mail in einen anderen Wert ändert. In dem HomeController.cs Datei fügen wir eine neue Aktion mit dem Namen AttackForm.

public ActionResult AttackForm () return View (); 

Wir werden auch eine Ansicht für diesen Namen hinzufügen AttackForm.aspx unter dem / Ansichten / Startseite Mappe. Es sollte so aussehen:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  Angriffsformular   

Angriffsformular

Diese Seite hat ein verstecktes Formular, um Sie anzugreifen, indem Sie Ihre E-Mail-Adresse ändern:

Unsere Seite kündigt hilfreiche Absichten an, die ein echter Angriff natürlich nicht tun würde. Diese Seite enthält ein verstecktes Formular, das für den Benutzer nicht sichtbar ist. Es verwendet dann Javascript, um dieses Formular automatisch zu senden, wenn die Seite geladen wird.


Wenn Sie die Site erneut ausführen, gehen Sie zu / Startseite / AttackForm Seite, Sie werden sehen, dass es gut geladen wird, aber keine Anzeichen dafür, dass etwas passiert ist. Wenn Sie jetzt zum gehen / Konto / ChangeEmail Seite sehen Sie jedoch, dass Ihre E-Mail in geändert wurde [email protected]. Natürlich machen wir dies absichtlich offensichtlich, aber bei einem echten Angriff bemerken Sie möglicherweise nicht, dass Ihre E-Mail geändert wurde.


Schadensbegrenzung für standortübergreifende Anforderungen

Es gibt zwei Hauptmethoden, um diese Art von Angriff abzumildern. Zuerst können wir die Weiterleitung überprüfen, von der die Webanfrage kommt. Dies sollte der Anwendung mitteilen, wenn ein Formular nicht von unserem Server gesendet wird. Dies hat jedoch zwei Probleme. Viele Proxyserver entfernen diese Verweisinformationen entweder absichtlich zum Schutz der Privatsphäre oder als Nebeneffekt, was bedeutet, dass eine legitime Anfrage diese Informationen nicht enthalten könnte. Es ist auch möglich, dass ein Angreifer die Überweisung fälscht, dies erhöht jedoch die Komplexität des Angriffs.

Die effektivste Methode ist, dass für jede Formularübermittlung ein benutzerspezifisches Token vorhanden ist. Der Wert dieses Tokens sollte bei jeder Erstellung des Formulars zufällig generiert werden und das Formular wird nur akzeptiert, wenn das Token enthalten ist. Wenn das Token fehlt oder ein anderer Wert enthalten ist, wird die Formularübermittlung nicht zugelassen. Dieser Wert kann entweder im Sitzungsstatus des Benutzers oder in einem Cookie gespeichert werden, damit wir den Wert überprüfen können, wenn das Formular gesendet wird.

ASP.NET vereinfacht diesen Prozess, da die CSRF-Unterstützung integriert ist. Um ihn zu nutzen, müssen wir nur zwei Änderungen an unserer Website vornehmen.


Problem beheben

Zuerst müssen wir dem Formular das eindeutige Token hinzufügen, um die E-Mail-Adresse des Benutzers bei der Anzeige zu ändern. Aktualisieren Sie das Formular in der ChangeEmail.aspx Ansicht unter / Konto / ChangeForm:

<% using(Html.BeginForm())  %> <%: Html.AntiForgeryToken() %> <%: Html.TextBoxFor(t=>t.NewEmail)%>  <%  %>

Diese neue Linie: <%: Html.AntiForgeryToken() %> weist ASP.NET an, ein Token zu generieren und es als verstecktes Feld im Formular zu platzieren. Außerdem übernimmt das Framework die Platzierung an einem anderen Ort, an dem die Anwendung später darauf zugreifen kann, um sie zu überprüfen.

Wenn wir die Seite jetzt laden und den Quellcode betrachten, wird diese neue Zeile in dem Formular für den Browser gerendert. Dies ist unser Zeichen:

Wir müssen auch eine Änderung an unserer Aktion vornehmen, um sie wissen zu lassen, dass wir dieses Token hinzugefügt haben und das Token überprüft werden muss, bevor das veröffentlichte Formular akzeptiert wird.

Auch dies ist in ASP.NET MVC einfach. Oben in der Aktion, die wir erstellt haben, um das veröffentlichte Formular zu bearbeiten, die mit der [HttpPost] Attribut hinzugefügt, fügen wir ein weiteres Attribut namens hinzu [ValidateAntiForgeryToken]. Dadurch sieht der Beginn unserer Aktion jetzt wie folgt aus:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult ChangeEmail (ChangeEmailModel-Modell) Zeichenfolge Benutzername = WebSecurity.CurrentUserName; * Rest der Funktion entfällt *

Lass uns das testen. Geh zuerst zum / Konto / ChangeEmail und stellen Sie die E-Mail für Ihr Konto auf einen bekannten Wert. Dann können wir zum zurückkehren / Startseite / AttackForm Seite und erneut versucht der Angriffscode, unsere E-Mail zu ändern. Wenn Sie zum zurückkehren / Konto / ChangeEmail wieder, diesmal sehen Sie, dass Ihre zuvor eingegebene E-Mail noch sicher und intakt ist. Die Änderungen, die wir an Form und Aktion vorgenommen haben, haben diese Seite vor dem Angriff geschützt.

Wenn Sie sich das Angriffsformular direkt ansehen möchten (einfach durch Entfernen des