Security Briefs

Noch einmal: Sicherheit von Webanwendungskonfigurationen

Bryan Sullivan

Bryan SullivanVor einigen Jahren, bevor ich bei Microsoft und im Security Development Lifecycle (SDL)-Team tätig war, schrieb ich einen Artikel über die Gefahren unsicherer web.config-Einstellungen und benannte die 10 schlimmsten Bedrohungen. Dieser Artikel ist heute noch zu finden – suchen Sie einfach mit einer Suchmaschine nach „Top 10 Application Security Vulnerabilities in Web.Config Files”. Die Konfigurationsprobleme, von denen ich damals sprach, sind auch heute noch relevant und aktuelle, obwohl regelmäßige Leser des MSDN Magazin darüber kaum überrascht sein dürften. Es ist immer noch wichtig, benutzerdefinierte Fehler zu aktivieren, es ist immer noch wichtig, Tracing und Debugging zu deaktivieren, bevor Ihre Anwendung in die Produktion geht, und es ist immer noch wichtig, SSL für Authentifizierungscookies zu erfordern.

In diesem Monat möchte ich den Faden meines damaligen Artikels aufnehmen und einige der eher obskuren, dennoch aber höchst bedeutsamen, Fehler bei Sicherheitskonfigurationen besprechen. Dabei werde ich ein neues kostenloses Tool vom Microsoft Information Security Tools-Team, „Web Application Configuration Analyzer“ betrachten, das beim Finden dieser Probleme behilflich sein kann. Denken Sie daran: Selbst eine äußerst sicher codierte ASP.Net-Anwendung kann gehackt werden, wenn sie nicht korrekt konfiguriert wurde.

EnableEventValidation

Einer der häufigsten Fehler von Entwicklern besteht darin, dass Sie Benutzern eine Liste mit Auswahlmöglichkeiten geben und dann annehmen, dass diese auch tatsächlich eine Auswahl daraus treffen. Und das sieht ja auch ganz logisch aus: Wenn Sie einer Seite ein ListBox-Steuerelement hinzufügen und dieses dann mit einer Liste aller US-Bundesstaaten ausfüllen, erwarten Sie, „Washington“, „Georgia“ oder „Texas“ zurückzuerhalten, und nicht „Foo“ oder „!@#$%” oder “<script>alert(document.cookie);</script>”. Man kann zwar solche Werte nicht auf normalem Wege, mit einem Browser, angeben, es gibt jedoch viele Möglichkeiten, auf Webanwendungen auch ganz ohne Browser zuzugreifen! Mit einem Web-Proxy-Tool wie Fiddler von Eric Lawrence (das immer noch eines meiner Lieblingstools zum Finden von Sicherheitsanfälligkeiten in Webanwendungen ist; Sie finden es zum Download unter fiddler2.com) können Sie jeden beliebigen Wert aus jedem Formularfeld senden. Wenn Ihre Anwendung darauf nicht vorbereitet ist, können potenziell gefährliche Fehler die Folge sein.

Die Konfigurationseinstellung EnableEventValidation ist ein tiefgreifender Verteidigungsmechanismus gegen Angriffe dieser Art. Wenn ein Benutzer mit destruktiven Absichten einen unerwarteten Wert für ein Steuerelement sendet, das nur eine endliche Liste von Werten akzeptiert (wie etwa eine ListBox – nicht eine TextBox, in der jeder Wert möglich ist), erkennt die Anwendung den Versuch und gibt einen Ausnahmefehler aus.

Schlecht:

<configuration>

  <system.web>

    <pages enableEventValidation="false"/>

Gut:

<configuration>

  <system.web>

    <pages enableEventValidation="true"/>

PasswordFormat

Das Mitgliedschaftsanbieter-Framework, das (seit ASP.NET 2.0) Teil von ASP.NET ist, ist eine großartige Funktion, die es Entwicklern erspart, das Rad der Mitgliedschaftsfunktion immer wieder neu erfinden zu müssen. Allgemein sind eingebaute Provider unter Sicherheitsaspekten ganz in Ordnung, wenn ihre Standardeinstellungen beibehalten werden. Wenn die Mitgliedschaftskonfiguration jedoch geändert wird, nehmen die Sicherheitsrisiken oft deutlich zu.

Ein gutes Beispiel dafür ist die Einstellung PasswordFormat, die festlegt, wie Kennwörter gespeichert werden. Sie haben drei Möglichkeiten: „Clear“, wobei das Kennwort als Klartext gespeichert wird, „Encrypted“, wobei das Kennwort vor der Speicherung verschlüsselt wird, und „Hashed“, wobei lediglich Hashes des Kennworts gespeichert werden. „Clear“ ist hier ganz offensichtlich die schlechteste Wahl. Es ist niemals empfehlenswert, Kennwörter als Klartext abzuspeichern. „Encrypted“ ist schon viel besser, und „Hashed“ ist eindeutig die beste Wahl, da die beste Methode, ein Geheimnis zu speichern, darin besteht, es überhaupt nicht zu speichern. Andererseits kann das ursprüngliche Kennwort aus dem Hash nicht wiederhergestellt werden, Sie können es einem Benutzer, der es vergessen hat, daher nicht erneut mitteilen.

Schlecht:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Clear"

             ...

 />

Besser:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Encrypted"

             ...

 />

Am besten:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Hashed"

             ...

 />

MinRequiredPasswordLength und MinRequiredNonalphanumericCharacters

Es gibt zwei Werte der Mitgliedschaftseinstellungen, bei denen Sie die Standardeinstellungen ändern sollten: die Eigenschaften MinRequiredPasswordLength und MinRequiredNonalphanumericCharacters. Für AspNetSqlMembershipProvider-Objekte ist die minimale Kennwortlänge standardmäßig sechs Zeichen, ohne dass nicht-alphanumerische Zeichen erforderlich sind. Für mehr Sicherheit sollten diese Werte viel höher eingestellt werden. Sie sollten eine Kennwortlänge von mindestens 10 Zeichen verlangen, mit mindestens zwei nicht-alphanumerischen Zeichen. Noch besser wären 14 Zeichen mit mindestens vier nicht-alphanumerischen Zeichen.

Natürlich bilden Kennwortlänge und Komplexität ein zweischneidiges Schwert: Wenn Sie von Ihren Benutzern verlangen, längere und komplexere Kennwörter einzurichten, sind diese weniger anfällig gegen gewaltsame Angriffe, andererseits steigt natürlich die Gefahr, dass die Benutzer diese vergessen oder sich gezwungen sehen, sie aufzuschreiben. Dies klingt zwar wie eine wirklich gefährliche Sicherheitslücke, viele Fachleute sind jedoch der Auffassung, dass die Vorteile gegenüber den Risiken überwiegen. Der bekannte Sicherheits-„Guru“ Bruce Schneier empfiehlt Benutzern, lange und komplexe Kennwörter zu erstellen und diese in ihre Brieftasche tun, oder eben dorthin, wo sie gewöhnlich kleine Zettel aufbewahren.

Schlecht:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             minRequiredPasswordLength="6"

             minRequiredNonalphanumericCharacters="0"

             ...

 />

Gut:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             minRequiredPasswordLength="14"

             minRequiredNonalphanumericCharacters="4"

             ...

 />

Die Microsoft Online Safety-Website (microsoft.com/protect/fraud/passwords/create.aspx) empfiehlt ebenfalls, dass Benutzer ihre Kennwörter aufschreiben; dort finden Sie auch weitere Informationen zum Erstellen und Sichern robuster Kennwörter.

ValidateRequest

51+5% 56%> MSDN_Review Lionbridge 23.10.2006 14:45:06 Lionbridge 23.10.2006 14:45:06 Vulnerability in Indexing Service Could Allow Cross-Site Scripting (920685) Cross-site scripting (XSS) continues to be the most common Web vulnerability. Cross-Site-Scripting (XSS) ist nach wie vor die am weitesten verbreitete Web-Gefahr. Ein Bericht von Cenzic Inc. vom Juli erwähnt, dass im ersten Halbjahr 28 % aller Web-Angriffe auf XSS-Anfälligkeiten basierten. Vor dem Hintergrund der potenziell schweren Folgen einer XSS-Anfälligkeit – ich habe XSS oft den „Pufferüberlauf des Web“ genannt – ist es nur konsequent, dass Entwickler alles tun sollten, was sie können, um ihre Anwendungen gegen solche Angriffe zu schützen. Besonders angenehm ist es, eine Verteidigungswaffe zu haben, die nichts kostet, und ValidateRequest ist genau das.

Schlecht:

<configuration>

  <system.web>

    <pages validateRequest="false" />

Gut:

<configuration>

  <system.web>

    <pages validateRequest="true" />

ValidateRequest überprüft Benutzereingaben auf verbreitete Angriffsmuster, wie etwa darauf, ob der Eingabestring spitze Klammern (<) enthält. Wenn dies der Fall ist, gibt die Anwendung einen Ausnahmefehler aus und hält die Verarbeitung der Anfrage an. Dies ist zwar durchaus noch keine vollständige Lösung – Sie sollten immer Output-Codierungs- und Input-Validierungs-/Bereinigungslogik verwenden, etwa die Lösungen aus der Microsoft Web Protection Library –ValidateRequest blockiert jedoch viele weit verbreitete XSS-Angriffe. Lassen Sie ValidateRequest am besten immer aktiviert, wenn dies möglich ist.

MaxRequestLength

Es ist selten eine gute Idee, Benutzern zu erlauben, unbegrenzt lange HTTP-Anfragen an Ihre Anwendung zu richten. Dadurch machen Sie die Anwendung anfällig für DoS- (Denial-of-Service) Angriffe, bei denen ein einzelner Angreifer Ihre gesamte Bandbreite, alle Prozessorzyklen oder Ihren gesamten Speicherplatz beanspruchen kann und es so verhindert, dass Ihre Anwendung den berechtigten Benutzern, die Sie erreichen möchten, zur Verfügung steht.

Um dies zu vermeiden, können Sie die Eigenschaft MaxRequestLength auf einen angemessen kleinen Wert setzen. Der Standardwert ist 4096 KB (4 MB). Da verschiedene Anwendungen unterschiedliche Anforderungen bei gewöhnlichen und ungewöhnlichen Anfragegrößen haben, ist es nicht einfach, eine allgemeine Faustregel für den MaxRequestLength-Wert zu geben. Ich gebe daher hier keine Beispiele für „schlechte“ und „gute“ Einstellungen, sondern empfehle lediglich, daran zu denken, dass höhere Werte ganz allgemein die Gefahr von DoS-Angriffen erhöhen:

<configuration>

  <system.web>

    <httpRuntime maxRequestLength="4096"/>

EnableViewStateMac

Ich habe schon in meiner Security Briefs-Kolumne vom Juli 2010 über die Einstellung EnableViewStateMac geschrieben (msdn.microsoft.com/magazine/ff797918). Wenn Sie diese Kolumne nicht gelesen haben: EnableViewStateMac ist ein Verteidigungsmittel, das Angreifer daran hindern soll, den clientseitigen Anzeigezustand zu manipulieren. Wenn EnableViewStateMac aktiviert ist, fügt die ASP.NET-Anwendung dem verborgenen __VIEWSTATE-Formularwert einen kryptographischen Message Authentication Code (MAC) hinzu. Ein Angreifer kann keinen gültigen MAC für einen beliebigen Angriff bestimmen – etwa, um zu versuchen, den Anzeigezustand des Opfers mit böswilligem JavaCode zu „vergiften“. Wenn ein Angreifer versucht, den Anzeigezustand auf diese Weise zu manipulieren, wird der MAC ungültig, und die ASP.NET-Anwendung blockiert die Anfrage.

Schlecht:

<configuration>

  <system.web>

    <pages enableViewStateMac="false"/>

Gut:

<configuration>

  <system.web>

    <pages enableViewStateMac="true"/>

Wenn Sie Ihre Anwendung in einer Serverfarmumgebung bereitstellen, sollten Sie auch daran denken, manuell einen Schlüssel für den MAC anzugeben und nicht die Anwendung zufällige Schlüssel automatisch erstellen zu lassen. (Wenn Sie dies nicht tun, generiert jeder Server in der Farm automatisch andere Schlüssel, und der von irgendeiner dieser Maschinen erstellte Anzeigezustands-MAC wird als ungültig betrachtet und von allen anderen Rechnern blockiert.)

Es gibt noch einige weitere Empfehlungen, die Sie beim manuellen Erstellen von Schlüsseln beachten sollten, um eine maximale Sicherheit für Ihren Anzeigezustand zu erreichen. Achten Sie zunächst darauf, dass Sie einen der SDL-genehmigten kryptographischen Algorithmen verwenden. Für Anwendungen, die Microsoft .NET Framework 3.5 (oder früher) verwenden, bedeutet dies die Verwendung von SHA1 (dies ist der Standardalgorithmus) oder AES. Für Anwendungen, die .NET Framework 4 verwenden, können Sie auch HMACSHA256, HMACSHA384 or HMACSHA512 verwenden. Meiden Sie schwache Algorithmen, wie etwa MD5.

Schlecht:

<configuration>

  <system.web>

    <machineKey validation="MD5" validationKey="..."/>

Gut:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="..."/>

Die Wahl eines starken Schlüssels ist ebenso wichtig wie die Wahl eines starken Algorithmus. Verwenden Sie einen kryptographisch starken Zufallszahlengenerator, um einen 64-Byte-Schlüssen zu erstellen (128-Byte, wenn Sie HMACSHA384 oder HMACSHA512 als Schlüsselalgorithmus verwenden). Referenzbeispielcodes zur Erstellung geeigneter Schlüssel finden Sie in der Kolumne vom Juli 2010, die ich bereits erwähnt habe.

Schlecht:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="12345"/>

Gut:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="143a907bb73069a2fe7c..."/>

ViewStateEncryptionMode

So wie Sie einen MAC für den Anzeigestatus Ihrer Anwendung verwenden sollten, um Angreifer daran zu hindern, diesen zu manipulieren, sollten Sie auch den Anzeigestatus selbst verschlüsseln, damit Angreifer ihn nicht lesen können. Sofern Sie nicht absolut sicher sind, dass keiner Ihrer Anzeigestatus sensitive Informationen enthält, sollten Sie die Eigenschaft ViewStateEncryptionMode so einstellen, dass er verschlüsselt und geschützt wird.

Schlecht:

<configuration>

  <system.web>

    <pages viewStateEncryptionMode="Never"/>

Gut:

<configuration>

  <system.web>

    <pages viewStateEncryptionMode="Auto"/>

Auch gilt wie bei EnableViewStateMac: Sie haben die Wahl zwischen verschiedenen kryptographischen Algorithmen, mit denen die Anwendung den Anzeigestatus verschlüsselt. Die beste Wahl ist jedoch AES – der einzige verfügbare Algorithmus, der derzeit von den SDL Cryptographic Standards anerkannt wird.

Schlecht:

<configuration>

  <system.web>

    <machineKey decryption="DES" decryptionKey=""/>

Gut:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey=""/>

Und denken Sie abschließend daran, dass Sie dann, wenn Sie Ihre Anwendung in einer Serverfarm entwickeln, einen Schlüssel manuell angeben müssen. Setzen Sie den Schlüsselwert auf einen kryptographischen 24-Byte-Zufallswert.

Schlecht:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey="12345"/>

Gut:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey="143a907bb73069a2fe7c..."/>

UseUnsafeHeaderParsing

Wenn Entwickler durch einen hartnäckigen Bug wirklich frustriert sind, implementieren sie oft jede Änderung, von der sie gelesen haben, dass sie das Problem löst, ohne aber wirklich zu verstehen, was diese mit ihrer Anwendung macht. Die Einstellung UseUnsafeHeaderParsing ist ein hervorragendes Beispiel dafür. Obwohl das Wort „unsafe (unsicher)“ im Namen der Eigenschaft allein schon alle Alarmglocken schrillen lassen sollte, zeigt eine kurze Internetsuche, dass buchstäblich tausende Fundstellen Entwicklern empfehlen, diese Funktion zu aktivieren. Wenn Sie UseUnsafeHeaderParsing aktivieren, ignoriert Ihre Anwendung viele der HTTP RFC-Spezifikationen und versucht das Parsing nicht wohlgeformter Anfragen. Dies kann Ihrer Anwendung ermöglichen, mit HTTP-Clients zu arbeiten, die HTTP-Standards nicht beachten (deshalb wird dies so oft als Problemlösung empfohlen), es kann Ihre Anwendung aber auch anfällig gegenüber Malformed-Header-Angriffen machen. Bleiben Sie auf der sicheren Seite, und lassen Sie diese Einstellung deaktiviert.

Schlecht:

<configuration>

  <system.net>

    <settings>

      <httpWebRequest 

       useUnsafeHeaderParsing=

       "true"/>

Gut:

<configuration>

  <system.net>

    <settings>

      <httpWebRequest 

       useUnsafeHeaderParsing=

       "false"/>

Web Application Configuration Analyzer (WACA)

Nachdem wir einige gefährliche Konfigurationseinstellungen betrachtet haben, wenden wir uns jetzt einem Tool zu, das das Finden dieser Einstellungen in Ihrem Code automatisieren kann. Eine manuelle Codeprüfung ist zweifellos nützlich, eine automatisierte Analyse kann aber gründlicher und konsistenter sein. Und Sie ersparen sich die manuelle Durchsicht von XML-Dateien und haben mehr Zeit, interessantere Probleme zu lösen!

Das Microsoft Information Security Tools-Team hat einige hervorragende Sicherheitstools entwickelt; zwei davon – AntiXSS/Web Protection Library und CAT.NET – haben wir für alle internen .NET Framework Microsoft-Produkte und Services als Teil von Microsoft SDL obligatorisch gemacht. Die neueste Entwicklung, WACA, dient dazu, potenziell gefährliche Fehlkonfigurationen, wie diejenigen, über die ich hier und in meinem früheren Artikel über die 10 wichtigsten web.config-Anfälligkeiten gesprochen habe, zu erkennen. Einige Beispiel für WACA-Funktionen:

  • Ist die Ablaufverfolgung aktiviert?
  • Ist die MaxRequestLength zu groß?
  • Sind HttpOnly-Cookies deaktiviert?
  • Ist SSL für die Formularauthentifizierungsanmeldung erforderlich?
  • Ist das Attribut EnableViewStateMac auf „False“ gesetzt?

Darüber hinaus kann WACA auch auf Fehlkonfigurationen in IIS selbst prüfen, wie auch auf SQL-Datenbank-Fehlkonfigurationen und sogar auf Probleme auf Systemebene. Einige Beispiele:

  • Ist der Windows Firewall-Service deaktiviert?
  • Hat der lokale Administrator den Namen „Administrator“?
  • Befindet sich die IIS-Protokolldatei auf dem Systemlaufwerk?
  • Ist die Ausführung im virtuellen Verzeichnis der Anwendung aktiviert?
  • Befinden sich auf dem SQL-Server Beispieldatenbanken?
  • Ist xp_cmdshell auf dem SQL-Server aktiviert?

Entwickler und tester werden WACA hauptsächlich für die Überprüfung der Konfigurationseinstellungen ihrer Anwendungen verwenden, Systemadministratoren und Datenbankadministratoren können mit diesem Tool aber auch IIS-, SQL- und Systemeinstellungen prüfen (vgl. Abbildung 1). Insgesamt enthält 140 Prüfungen auf der Grundlage von SQL-Anforderungen und Vorlagen und Praktiken für die Codierung.

image: Web Application Configuration Analyzer Rules

Abbildung 1 Web Application Configuration Analyzer-Regeln

Ein weiteres, wirklich nützliches Feature von WACA besteht darin, dass Sie Arbeitselemente oder Bugs in Team Foundation Server (TFS)-Teamprojekten aus WACA-Prüfergebnissen automatisch erstellen können. Dies ist besonders nützlich, wenn Sie das Tool mit einem Teamprojekt verwenden, das entweder auf der SDL-Prozessvorlage oder der MSF-Agile+SDL-Prozessvorlage beruht. Ordnen Sie auf der WACA TFS-Einrichtungsseite das Vorlagenfeld „Origin“ dem Wert “Web Application Configuration Analyzer” zu. Wenn Sie jetzt Ihre Bugreports und Trenddiagramme anzeigen, können Sie zu den WACA-Ergebnissen filtern, um zu sehen, wie effektiv dieses Tool potenzielle Gefahren erkannt hat (vgl. Abbildung 2).

image: WACA Team Foundation Server Integration

Abbildung 2 WACA Team Foundation Server Integration

Weitere Informationen zu WACA finden Sie auf der Microsoft IT InfoSec Group-Seite (msdn.microsoft.com/security/dd547422); sehen Sie eine Videodemonstration des Tools von Anil Revuru, Programm-Manager für das WACA-Projekt (msdn.microsoft.com/security/ee909463); oder, am besten, laden Sie das Tool herunter, und probieren Sie es selbst aus (tinyurl.com/3x7bgfd).

Überprüfen Sie immer Ihre Einstellungen

Es ist frustrierend, daran zu denken, dass Sie Ihre Anwendung unter Beachtung aller denkbaren Sicherheitsempfehlungen entwickeln, und dann dennoch gehackt werden, weil in einer web.config-Konfigurationsdatei noch ein Fehler steckt. Noch frustrierender ist es, wenn Sie sich klar machen, dass die web.config-Dateien jederzeit geändert werden können, und dass ein Fehler noch Jahre nach Abschluss der Codierung und der Übergabe an die Produktion auftreten kann. Es ist sehr wichtig, dass Sie Ihre Konfigurationseinstellungen immer überprüfen – nicht nur manuell, sondern auch mithilfe automatisierter Tools, und nicht nur während des Entwicklungszyklus, sondern auch in der Produktionsphase.

Denial-Of-Service-Angriffe mit regulären Ausdrücken - Nachtrag

Zu einem ganz anderen Thema: In der Security Briefs-Kolumne im Mai 2010 (msdn.microsoft.com/magazine/ff646973) schrieb ich über DoS-Angriffe mit regulären Ausdrücken, wie etwa Checkmarx auf der OWASP Israel-Konferenz im September 2009. In dieser Kolumne gab ich auch Code für einen Regex DoS Fuzzer auf der Basis der Data Generation Plan-Funktionalität von Visual Studio Database Projects. Obwohl dieses Konzept technisch solide war und Regex-Anfälligkeiten gut erkannte, war die Generierung von Testdaten zugegebenermaßen etwas umständlich, zudem benötigten Sie dazu eine Lizenz von Visual Studio Database Projects. Ich freue mich daher, ihnen mitteilen zu können, dass das SDL-Team ein neues Regex-Fuzz-Tool zum kostenlosen Download freigegeben hat, das die Details der Datengenerierung für Sie übernimmt. Das Tool hat keine externen Dependenzen (ausgenommen .NET Framework 3.5). Es wird in Abbildung 3 dargestellt.

image: SDL Regex Fuzzer

Abbildung 3 SDL Regex Fuzzer

Sie können SDL Regex Fuzzer von microsoft.com/sdl herunterladen. Probieren Sie es aus, und lassen Sie uns Ihre Meinung wissen.      

Bryan Sullivan ist Sicherheitsprogramm-Manager beim Microsoft Security Development Lifecycle-Team und hat sich auf Webanwendungen und Microsoft .NET Framework-Sicherheitsaspekte spezialisiert. Er ist auch der Autor von „Ajax Security“ (Addison-Wesley, 2007).

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Anil Revuru