Freigeben über


Verhindern von Angriffen durch Einschleusung von JavaScript-Codes (C#)

von Stephen Walther

Verhindern Sie JavaScript-Einschleusungsangriffe und Siteübergreifende Skriptangriffe. In diesem Tutorial erläutert Stephen Walther, wie Sie diese Arten von Angriffen einfach besiegen können, indem Sie Ihre Inhalte html codieren.

In diesem Tutorial wird erläutert, wie Sie JavaScript-Einschleusungsangriffe in Ihren ASP.NET MVC-Anwendungen verhindern können. In diesem Tutorial werden zwei Ansätze zum Schutz Ihrer Website gegen einen JavaScript-Einschleusungsangriff erläutert. Sie erfahren, wie Sie JavaScript-Einschleusungsangriffe verhindern, indem Sie die angezeigten Daten codieren. Außerdem erfahren Sie, wie Sie JavaScript-Einschleusungsangriffe verhindern, indem Sie die von Ihnen akzeptierten Daten codieren.

Was ist ein JavaScript-Einschleusungsangriff?

Wenn Sie Benutzereingaben akzeptieren und die Benutzereingabe erneut anzeigen, öffnen Sie Ihre Website für JavaScript-Einschleusungsangriffe. Untersuchen wir eine konkrete Anwendung, die für JavaScript-Einschleusungsangriffe offen ist.

Stellen Sie sich vor, Sie haben eine Kundenfeedback-Website erstellt (siehe Abbildung 1). Kunden können die Website besuchen und Feedback zu ihrer Erfahrung mit Ihren Produkten eingeben. Wenn ein Kunde sein Feedback übermittelt, wird das Feedback auf der Feedbackseite erneut angezeigt.

Kundenfeedback-Website

Abbildung 01: Kundenfeedback-Website (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Die Kundenfeedback-Website verwendet die controller in Eintrag 1. Dies controller enthält zwei Aktionen mit dem Namen Index() und Create().

Eintrag 1 – HomeController.cs

using System;
using System.Web.Mvc;
using CustomerFeedback.Models;

namespace CustomerFeedback.Controllers
{
     [HandleError]
     public class HomeController : Controller
     {
          private FeedbackDataContext db = new FeedbackDataContext();

          public ActionResult Index()
          {
               return View(db.Feedbacks);
          }

          public ActionResult Create(string message)

          {
               // Add feedback
               var newFeedback = new Feedback();
               newFeedback.Message = message;
               newFeedback.EntryDate = DateTime.Now;
               db.Feedbacks.InsertOnSubmit(newFeedback);
               db.SubmitChanges();

               // Redirect
               return RedirectToAction("Index");
          }
     }
}

Die Index() -Methode zeigt die Index Ansicht an. Diese Methode übergibt das gesamte vorherige Kundenfeedback an die Index Ansicht, indem das Feedback aus der Datenbank abgerufen wird (mithilfe einer LINQ to SQL Abfrage).

Die Create() Methode erstellt ein neues Feedbackelement und fügt es der Datenbank hinzu. Die Nachricht, die der Kunde in das Formular eingibt, wird an die Create() -Methode im Nachrichtenparameter übergeben. Es wird ein Feedbackelement erstellt, und die Nachricht wird der Eigenschaft des Feedbackelements Message zugewiesen. Das Feedbackelement wird mit dem Methodenaufruf an die DataContext.SubmitChanges() Datenbank übermittelt. Schließlich wird der Besucher zurück zur Index Ansicht weitergeleitet, in der das gesamte Feedback angezeigt wird.

Die Index Ansicht ist in Listing 2 enthalten.

Eintrag 2 – Index.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>

<%@ Import Namespace="CustomerFeedback.Models" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
     <h1>Customer Feedback</h1>
     <p>
          Please use the following form to enter feedback about our product.
     </p>

     <form method="post" action="/Home/Create">

          <label for="message">Message:</label>
          <br />
          <textarea name="message" cols="50" rows="2"></textarea>
          <br /><br />
          <input type="submit" value="Submit Feedback" />
     </form>

     <% foreach (Feedback feedback in ViewData.Model)
     {%>
          <p>
          <%=feedback.EntryDate.ToShortTimeString()%>
          --
          <%=feedback.Message%>
          </p>
     <% }%>

</asp:Content>

Die Index Ansicht verfügt über zwei Abschnitte. Der obere Abschnitt enthält das tatsächliche Kundenfeedbackformular. Der untere Abschnitt enthält ein For.. Jede Schleife, die alle vorherigen Kundenfeedbackelemente durchläuft und die Eigenschaften EntryDate und Message für jedes Feedbackelement anzeigt.

Die Kundenfeedback-Website ist eine einfache Website. Leider ist die Website offen für JavaScript-Einschleusungsangriffe.

Stellen Sie sich vor, Sie geben den folgenden Text in das Kundenfeedbackformular ein:

<script>alert("Boo!")</script>

Dieser Text stellt ein JavaScript-Skript dar, das ein Meldungsfeld für Warnungen anzeigt. Nachdem jemand dieses Skript in das Feedbackformular übermittelt hat, wird die Nachricht Boo!wird angezeigt, wenn in Zukunft jemand die Kundenfeedback-Website besucht (siehe Abbildung 2).

JavaScript-Einschleusung

Abbildung 02: JavaScript-Einschleusung (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Nun könnte Ihre erste Antwort auf JavaScript-Einschleusungsangriffe Apathie sein. Sie könnten denken, dass JavaScript-Einschleusungsangriffe einfach eine Art von Verunstaltungsangriff sind. Sie könnten glauben, dass niemand etwas wirklich Böses tun kann, indem er einen JavaScript-Einschleusungsangriff begeht.

Leider kann ein Hacker einige wirklich, wirklich böse Dinge tun, indem er JavaScript in eine Website einschleust. Sie können einen JavaScript-Einschleusungsangriff verwenden, um einen XSS-Angriff (Cross-Site Scripting) auszuführen. Bei einem Cross-Site Scripting-Angriff stehlen Sie vertrauliche Benutzerinformationen und senden die Informationen an eine andere Website.

Ein Hacker kann beispielsweise einen JavaScript-Einschleusungsangriff verwenden, um die Werte von Browsercookies von anderen Benutzern zu stehlen. Wenn vertrauliche Informationen - wie Kennwörter, Guthaben Karte Zahlen oder Sozialversicherungsnummern - in den Browsercookies gespeichert werden, kann ein Hacker einen JavaScript-Einschleusungsangriff verwenden, um diese Informationen zu stehlen. Wenn ein Benutzer vertrauliche Informationen in ein Formularfeld eingibt, das auf einer Seite enthalten ist, die durch einen JavaScript-Angriff kompromittiert wurde, kann der Hacker das eingefügte JavaScript verwenden, um die Formulardaten zu erfassen und an eine andere Website zu senden.

Bitte haben Sie Angst. Nehmen Sie JavaScript-Einschleusungsangriffe ernst und schützen Sie die vertraulichen Informationen Ihres Benutzers. In den nächsten beiden Abschnitten werden zwei Techniken erläutert, mit denen Sie Ihre ASP.NET MVC-Anwendungen vor JavaScript-Einschleusungsangriffen schützen können.

Ansatz #1: HTML-Codierung in der Ansicht

Eine einfache Methode zum Verhindern von JavaScript-Einschleusungsangriffen ist das HTML-Codieren von Daten, die von Websitebenutzern eingegeben werden, wenn Sie die Daten in einer Ansicht erneut anzeigen. Die aktualisierte Index Ansicht in Listing 3 folgt diesem Ansatz.

Eintrag 3 – Index.aspx (HTML-codiert)

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>

<%@ Import Namespace="CustomerFeedback.Models" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
     <h1>Customer Feedback</h1>
     <p>
          Please use the following form to enter feedback about our product.
     </p>

     <form method="post" action="/Home/Create">
          <label for="message">Message:</label>
          <br />
          <textarea name="message" cols="50" rows="2"></textarea>
          <br /><br />
          <input type="submit" value="Submit Feedback" />

     </form>

     <% foreach (Feedback feedback in ViewData.Model)
     {%>
          <p>
          <%=feedback.EntryDate.ToShortTimeString()%>
          --
          <%=Html.Encode(feedback.Message)%>
          </p>
     <% }%>

</asp:Content>

Beachten Sie, dass der Wert von feedback.Message HTML-codiert ist, bevor der Wert mit dem folgenden Code angezeigt wird:

<%=Html.Encode(feedback.Message)%>

Was bedeutet es, eine Zeichenfolge in HTML zu codieren? Beim HTML-Codieren einer Zeichenfolge werden gefährliche Zeichen wie < und > durch HTML-Entitätsverweise wie &lt; und &gt;ersetzt. Wenn die Zeichenfolge <script>alert("Boo!")</script> also HTML-codiert ist, wird sie in &lt;script&gt;alert(&quot;Boo!&quot;)&lt;/script&gt;konvertiert. Die codierte Zeichenfolge wird nicht mehr als JavaScript-Skript ausgeführt, wenn sie von einem Browser interpretiert wird. Stattdessen erhalten Sie die harmlose Seite in Abbildung 3.

Besiegter JavaScript-Angriff

Abbildung 03: Besiegter JavaScript-Angriff (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Beachten Sie, dass in der Index Ansicht in Listing 3 nur der Wert von feedback.Message codiert ist. Der Wert von feedback.EntryDate ist nicht codiert. Sie müssen nur die von einem Benutzer eingegebenen Daten codieren. Da der Wert von EntryDate im Controller generiert wurde, müssen Sie diesen Wert nicht HTML codieren.

Ansatz #2: HTML-Codierung im Controller

Anstelle von HTML-Codierungsdaten, wenn Sie die Daten in einer Ansicht anzeigen, können Sie die Daten html codieren, bevor Sie die Daten an die Datenbank übermitteln. Dieser zweite Ansatz wird im Fall von controller in Listing 4 verfolgt.

Eintrag 4 – HomeController.cs (HTML-codiert)

using System;
using System.Web.Mvc;
using CustomerFeedback.Models;
namespace CustomerFeedback.Controllers
{
     [HandleError]
     public class HomeController : Controller
     {
          private FeedbackDataContext db = new FeedbackDataContext();

          public ActionResult Index()
          {
               return View(db.Feedbacks);
          }

          public ActionResult Create(string message)
          {
               // Add feedback
               var newFeedback = new Feedback();
               newFeedback.Message = Server.HtmlEncode(message);
               newFeedback.EntryDate = DateTime.Now;
               db.Feedbacks.InsertOnSubmit(newFeedback);

               db.SubmitChanges();

               // Redirect
               return RedirectToAction("Index");
          }
     }
}

Beachten Sie, dass der Wert von Message HTML-codiert ist, bevor der Wert innerhalb der Aktion an die Create() Datenbank übermittelt wird. Wenn die Nachricht in der Ansicht erneut angezeigt wird, wird die Nachricht HTML-codiert, und alle in die Nachricht eingefügten JavaScript-Elemente werden nicht ausgeführt.

In der Regel sollten Sie den ersten Ansatz, der in diesem Tutorial erläutert wird, gegenüber diesem zweiten Ansatz bevorzugen. Das Problem bei diesem zweiten Ansatz besteht darin, dass Sie am Ende HTML-codierte Daten in Ihrer Datenbank haben. Mit anderen Worten, Ihre Datenbankdaten sind mit lustig aussehenden Zeichen versehen.

Warum ist das schlecht? Wenn Sie die Datenbankdaten jemals auf einer anderen Seite als auf einer Webseite anzeigen müssen, treten Probleme auf. Beispielsweise können Sie die Daten nicht mehr einfach in einer Windows Forms-Anwendung anzeigen.

Zusammenfassung

Der Zweck dieses Tutorials bestand darin, Sie über die Aussicht auf einen JavaScript-Einschleusungsangriff zu erschrecken. In diesem Tutorial wurden zwei Ansätze zum Schutz Ihrer ASP.NET MVC-Anwendungen gegen JavaScript-Einschleusungsangriffe erläutert: Sie können entweder Benutzerdaten in html codieren, die in der Ansicht übermittelt wurden, oder Sie können die vom Benutzer übermittelten Daten im Controller html codieren.