Sicherheit von Webanwendungen
Die Sicherheit von Webanwendungen ist ein unabdingbarer Aspekt der Entwicklung von Webanwendungen. Mit Hilfe des Ebenenmodells erfolgt eine Aufteilung der einzelnen Teilsegmente an die jeweiligen Verantwortlichen.[1]
Ebenenmodell
Ein Ebenenmodell dient dazu, die Zuständigkeiten für die einzelnen Teilaufgaben bei der Sicherheitskonzeption und Realisierung von Webanwendungen zu ordnen. Ausgangspunkt ist eine Unterteilung in fünf Ebenen: Der Semantik, Logik, Implementierung, Technik, des Systems sowie der Ebene „Netzwerk und Host“.
Angriffsmethoden
Es gibt unzählige Möglichkeiten, Schwachstellen in einer Webanwendung zu finden und diese auszunutzen. Im Folgenden findet sich eine Beschreibung allgemein bekannter und oft benutzter Angriffsmöglichkeiten im Zusammenhang mit Webanwendungen.
SQL-Injection
Bei einer SQL-Injection sendet der Angreifer Verbindungsanfragen an den Webserver, wobei die Anfrage-Parameter mit SQL-Steuerzeichen versehen sind. Fängt die Webanwendung diese Steuerzeichen nicht ab, sondern sendet sie als Teil einer SQL-Abfrage an die Datenbank, kann der Angreifer für ihn auf herkömmlichem Weg nicht zugängliche Daten entweder auslesen oder verändern.
Cross-Site-Scripting
Hinter der Bezeichnung Cross-Site-Scripting (XSS) verbergen sich zwei (manchmal wird noch ein dritter Typ unterschieden) grundsätzlich verschiedene Angriffe. Beim clientseitigen XSS schleust der Angreifer HTML-Steuerzeichen und Code einer clientseitigen Skriptsprache, wie z. B. JavaScript, in eine Webseite ein, die in dem Webbrowser des Opfers ausgeführt wird. Dieser Angriff nutzt dabei Sicherheitslücken bei der lokalen Ausführung der Skripte aus oder leitet eine Cross-Site-Request-Forgery ein. Unter serverseitigem XSS versteht man das Einschleusen von manipulierten Informationen in eine auf dem Webserver ausgeführte Scriptsprache, so dass diese beispielsweise bei einem dynamisch generierten include()
eine vom Programmierer nicht vorgesehene Datei (ggf. sogar von einem anderen Server) ausführt.
Session Hijacking
Da HTTP ein verbindungsloses Protokoll ist, muss die Webanwendung selbst die Identifikation eines Benutzers feststellen. Dies geschieht anhand einer Session-ID, die als Basic/Digest Authentication, Cookie, URL-Rewriting oder HTTP-Form-Parameter (GET oder POST) jedem Request mitgegeben wird. Beim Session Hijacking versucht der Angreifer Kenntnis von der Session-ID des Benutzers zu erlangen, um dann die Identität des Opfers vorzutäuschen und mit dessen Rechten auf die Webanwendung zuzugreifen.
Cross-Site-Request-Forgery
Cross-Site-Request-Forgery setzen eine bestehende Session zwischen dem Benutzer und der Webanwendung voraus. Dabei versucht der Angreifer über verschiedene Techniken (ggf. XSS) den Benutzer oder über ein clientseitiges Script auch direkt den Browser zum Aufruf einer manipulierten URL zu bewegen. Anders als beim Session-Hijacking erlangt der Angreifer selbst aber keine Kenntnis von der Session-ID, da der Angriff ausschließlich im Browser des Benutzers stattfindet.
Directory Traversal
Bei einem Directory-Traversal-Angriff nutzt der Angreifer die fehlende Prüfung der Webanwendung auf manipulierte Pfadangaben aus. Erwartet die Webanwendung beispielsweise einen Parameter wie item=datei1.html
, kann dieser ggf. mit item=../../../Config.sys
missbraucht werden.
E-Mail-Injection
Bei einer E-Mail-Injection fügt der Angreifer in ein Kontaktformular manipulierte Daten ein, so dass anstelle der Nachricht an den vom Betreiber der Webanwendung beabsichtigten Empfänger nun beliebige E-Mails an beliebige Empfänger gesendet werden. Diese Möglichkeit wird meist für den Versand von Spam missbraucht.
Man-in-the-Middle-Angriff
Bei einem Man-in-the-Middle-Angriff (MitM) zielt der Angreifer darauf ab, dass der Benutzer anstatt mit dem Webserver vielmehr direkt mit dem Rechner des Angreifers eine Verbindung aufbaut, ohne dies zu bemerken. Der „In-the-middle“-Rechner startet bei jeder Anfrage des Benutzers seinerseits eine Anfrage an den echten Webserver und gibt dessen Antwort an den Benutzer weiter. Der Nutzwert besteht für den Angreifer darin, Anfragen an oder Rückgaben der Webanwendung beliebig manipulieren zu können. Gegen diese Art von Angriff bietet nur die Verschlüsselung der Datenübertragung, beispielsweise mittels SSL, Schutz. Dieser Schutz wird aber unwirksam, wenn sich der Angreifer ein SSL-Zertifikat der betroffenen Webseite verschaffen kann, zu dem ein Root-Zertifikat im Browser des Opfers installiert ist.
Man-in-the-Browser
Man-in-the-Browser ist eine Sonderform des Man-in-the-middle-Angriffs, bei der die Darstellung von Webseiten direkt im Browser verändert wird. Das Programm kann eigenständig Transaktionen durchführen, die vom Nutzer im Normalfall nicht bemerkt werden, da der Nutzer sich auf den echten Seiten der Anbieter bewegt, korrekt angemeldet ist und die unerwünschten Transaktionen für den Nutzer wie normale Vorgänge angezeigt werden.
Denial of Service
Bei einem Denial of Service (DoS) Angriff versucht der Angreifer dem Webserver durch eine Vielzahl von Verbindungsanfragen den jeweiligen Server lahm zu legen. Wird der Angriff gleichzeitig von mehreren (ggf. mehrere tausend) Computern gleichzeitig durchgeführt, spricht man auch von einem Distributed-Denial-of-Service-Angriff (DDoS). Ein DoS ist nicht auf Webanwendungen beschränkt, sondern kann sich gegen jede Art von Server richten.
Mustererkennung
Grundlegendes Problem jeder Maßnahme zur Verhinderung von DoS-Angriffen ist die Unterscheidung eines solchen Angriffs von legitimen Zugriffen, sowie die gezielte Blockierung des Angreifers, ohne legitime Benutzer in Mitleidenschaft zu ziehen. Ein automatisierter DoS-Angriff kann wirksam dadurch verhindert werden, dass der Benutzer nach Erreichen einer festgelegten Toleranzschwelle von erlaubten Wiederholungen aufgefordert wird, eine Eingabe zu tätigen, die ein Programm nicht liefern kann. Wird die Eingabe korrekt gegeben, kann davon ausgegangen werden, dass kein automatisierter Angriff stattfindet. Folgende Verfahren kommen in Frage:
- Captcha (Beim Einsatz von Captchas und der Auswahl einer Captcha-Bibliothek ist zu beachten, dass die Sicherheit dieses Verfahrens mit der maschinellen Nichtlösbarkeit der Aufgabe steht und fällt. Fortschritte in der Mustererkennung oder die Entdeckung von Algorithmen können diese Art von Schutz mit einem Schlag wertlos machen.)
- Rätselfrage (Dem Benutzer wird eine Frage gestellt, die eine Maschine nicht interpretieren und damit nicht beantworten kann.)
Phishing / Identitätsdiebstahl
Beim Phishing handelt es sich nicht um eine Sicherheitslücke einer Webanwendung, es gehört vielmehr in den Bereich des Social Hacking. Hierbei fordert der Angreifer seine potentiellen Opfer meist massenweise per E-Mail auf, Zugangsdaten, wie z. B. PIN und TAN zum Online-Banking, auf einer Webseite einzugeben. Diese sieht in der Regel äußerlich so aus wie die des Betreibers der Webanwendung, unterliegt aber der Kontrolle des Angreifers. Nimmt das Opfer diese Fälschung nicht wahr und gibt seine Zugangsdaten preis, kann der Angreifer diese zu seinen Gunsten verwenden.
Identitätsprinzip
Das Identitätsprinzip ist eine Art, Webanwendungen und Websites so zu gestalten und darzustellen, dass Benutzer bei einem Phishing-Angriff die gefälschte Seite wahrnehmen und sensible Daten nicht angeben. Dazu muss aus dem Umgang mit der Website, aber auch aus der gesamten Kommunikation mit dem Internetauftritt erkennbar sein, dass der Internetdiensteanbieter bestimmte Muster durchgängig einhält.
Generelle schützende Maßnahmen
Data Validation
Die Validierung vor allem von Eingangsdaten ("input"), aber auch Ausgabedaten ("output") ist der wichtigste Bestandteil einer sicheren Webanwendung. Der Datenfluss ist nicht nur vom Benutzer zur Anwendung und umgekehrt, sondern auch zu den verschiedenen Subsystemen und von dort aus in die Ausgabe zu untersuchen. Im Idealfall werden alle Input- bzw. Output-Daten von einem zentralen "Data-Validation-Modul" (d. h. einem Programmteil zur Prüfung der Zulässigkeit von Daten) geprüft. In PHP lässt sich so etwas mit Funktionen lösen. Neben den offensichtlichen Eingabedaten in Formular-Variablen (engl. "form variable" wegen "form" = Formular) gibt es eine Reihe weiterer Quellen. Alternativ lässt sich Filterung einsetzen. Dies ist immer dann angebracht, wenn keine Nebenwirkungen zu befürchten sind oder wenn die Art der Datenverwendung gefährliche Zeichen oder Zeichenketten aufgrund ihrer Natur erlauben muss.
Beispiel: Ein Forum, in dem über JavaScript diskutiert wird, kann nicht die Eingabe von <script>
verbieten, muss dieses aber als HTML-Tag validieren. Bei der Filterung ist mit großer Umsicht vorzugehen, denn man läuft permanent Gefahr, eine Variante zu übersehen.
Whitelisting statt Blacklisting
Sofern der Input klar definierbar ist, ist es meist sinnvoller, nur bestimmte Eingaben zuzulassen, als bestimmte andere Angaben nicht zuzulassen. Beim Blacklisting werden die Muster definiert, die aus der Eingabe herausgefiltert werden, alles andere wird durchgelassen. Beim Whitelisting ist es umgekehrt: Werte, die nicht ausdrücklich erlaubt sind, sind verboten. Blacklisting ist dann problematisch, wenn als „nicht kritisch“ erkannte Zeichen im Verlaufe der weiteren Verarbeitung zu einem ungewollten Systemverhalten oder auch Fehlern führen. Werden allerdings problematische Muster vergessen oder nicht erkannt oder kommen neue problematische Muster hinzu, so werden sie beim Whitelist-Ansatz hingegen automatisch blockiert. Beim Blacklist-Ansatz werden sie solange durchgelassen, bis die Regeln angepasst werden. Blacklist- oder Whitelist-Verfahren können nicht nur mit festen Schlüsselwörtern benutzt werden. Auch ein Einsatz mit regulären Ausdrücken kann sinnvoll sein.
Behandlung von manipulierten Eingaben
Bei der Behandlung von ungültigen Eingaben sollte zwischen nachfolgenden zwei Fällen unterschieden werden: Fehleingaben des Benutzers und bewusste Manipulation. Im ersten Fall ist in benutzerfreundlicher Weise zu reagieren – unter Wahrung des Minimalitätsprinzips. Der Benutzer ist auf den Fehler hinzuweisen. Im zweiten Fall sollte die Reaktion in geeigneter Weise den Manipulationsversuch abwehren. Dann ist zu entscheiden, ob eine Filterung erfolgt oder ob die Weiterverarbeitung abgelehnt wird. Eine erfolgreiche Filterung könnte eine Weiterverarbeitung implizieren. Ein sicheres Kriterium für den Abbruch der Verarbeitung mit einer Fehlermeldung ist immer dann gegeben, wenn die Eingabedaten mit bestimmungsgemäßer Browserbedienung nicht eintreten können, wie z. B.:
- zusätzliche oder fehlende Formular-Variablen
- Das Session-Cookie enthält Zeichen, die von der Anwendung nicht vergeben werden, oder es entspricht nicht dem definierten Format.
- In HIDDEN-, SELECT- oder CHECKBOX-Variablen transportierte Werte wurden verändert oder entsprechen nicht dem Muster, welches die Anwendung gesetzt hat.
- Die Quelle der Variablen (z. B. GET, POST, Cookie) stimmt nicht mit der Vorgabe der Anwendung überein.
Zu den möglichen Reaktionen auf derartige Fehler können je nach Situation zählen:
- Die weitere Verarbeitung ist zu stoppen. Es ist zu erwägen, statt einer Fehlermeldung eine Reaktion in dieser Weise vorzunehmen: Dem Benutzer – dem in diesem Fall ein Angriff unterstellt wird – wird der korrekte Umgang mit der Eingabe vorgetäuscht, um seinen Angriffsversuch zu unterlaufen und weiteres Suchen nach Schwachstellen zu erschweren. So würde die Antwort auf das manipulierte Absenden eines Kontaktformulars beispielsweise genauso wie im korrekten Fall lauten: Vielen Dank für Ihre Anfrage, die wir umgehend bearbeiten werden.
- Es ist zur Hauptseite oder der (neutralen) Seite, die auch bei Zugriffen auf nicht vorhandene Seiten angezeigt wird, zurückzukehren.
- Es ist eine explizite Warnung auszugeben, dass ein Angriffsversuch festgestellt worden ist und dass alle Zugriffsversuche protokolliert werden bzw. anderweitige Maßnahmen ergriffen werden. Ob dies allerdings überhaupt sinnvoll ist, muss bei der jeweiligen Anwendung einzeln entschieden werden.
- Zusätzlich bei bestehender Session: Der Benutzer ist abzumelden und die Session als ungültig zu erklären ("invalidate").
Nicht korrekt sind diese häufig anzutreffenden Reaktionen:
- ungefilterte Ausgabe der Fehlermeldung, insbesondere eine SQL-Fehlermeldung (liefert u. U. für einen Angriff verwertbare Informationen)
- Server Error 500 (daraus lässt sich schließen, dass die Anwendung nicht alle Fälle korrekt abfängt)
• „Die Anwendung ist momentan wegen Wartungsarbeiten nicht verfügbar“ (gibt dem Angreifer u. U. einen Anreiz, die Anwendung weiter zu untersuchen, da er vermutet, dass er die Anwendung tatsächlich kurzzeitig lahmgelegt hat.)
Gänzlich abzuraten ist in solchen Fällen von Versuchen, fehlerhafte Eingaben zu korrigieren. Derartige Versuche weisen das unnötige Risiko auf, doch nicht fehlerfrei zu sein und einen Angriff dadurch überhaupt erst zu ermöglichen.
Prepared Statements
Durch Verwendung von Prepared Statements anstatt dynamisch zusammengebauter SQL-Anweisungen kann dem Problem der SQL-Injection aus dem Weg gegangen werden. Software-Entwickler müssen sich im Rahmen des Designs einer Funktion oder hat bzw. was die Menge aller möglichen Abfragestrukturen ist, die in Abhängigkeit von den Eingabedaten zur Ausführung gelangen können. Diese Abfragen sind in Form von Prepared Statements auszuformulieren. Dabei können mit den Mitteln der Prepared Statements (also in der Regel entsprechenden WENN-Abfragen und dem Zusammensetzen von Abfragen) alle Bedingungen, die durch unterschiedliche Eingabedaten zu prüfen sind, berücksichtigt werden. Es ist meist unnötig, in die Formulierung der SQL-Anweisung zusätzlich eine Dynamik hineinzubringen, die nur mit dem Mittel der "Dynamic Statements" erreichbar wäre.
Stored Procedure
Stored Procedures haben im Hinblick auf ihre Sicherheit gegenüber SQL-Injection ähnliche Eigenschaften wie Prepared Statements. Auch hier ist zu beachten, dass bei Übergabe von ungeprüften ("unvalidierten") Parametern an eine Stored Procedure möglicher problematischer Eingabedaten nicht automatisch abgefangen wird.[2]
Serverseitig validieren
Alle Eingabedaten sind von der Anwendung auf dem Server auf Zulässigkeit zu überprüfen ("zu validieren"). Prüfungen auf dem Client (Browser) z. B. mittels JavaScript können allenfalls zusätzlich aus Gründen der Benutzerfreundlichkeit erfolgen, aber niemals um Annahmen über die Beschaffenheit der Eingabedaten sicherzustellen. Prüfungen im Browser könnten vom Benutzer abgeschaltet und beliebig manipuliert werden.
Namen von Formular-Variablen validieren
Genauso wie der Wert einer Formular-Variablen kann auch ihr Name beliebig manipuliert werden. Daher sind auch die Namen von Formular-Variablen der Filterung zu unterziehen. Da alle Formular-Variablen in der Anwendung bekannt sind, ist hier eine einfache Überprüfung der Zeichenketten effektiv.
Länge bzw. Größe der Eingabedaten begrenzen
Alle Eingabedaten sind auf ihre Größe zu überprüfen, bevor sie verwendet (insbesondere kopiert) werden. Die genaue Realisierung dieser Prüfung ist von der jeweiligen Programmiersprache abhängig. Beispiel in PHP:
if (strlen($parameter) > 42) { return; };
Achtung: die PHP-Funktionen geben in der Zeichenketten enthaltene Null-Bytes direkt als solche weiter. Null-Bytes müssen zuvor entfernt werden.
Abwägung von POST- und GET-Requests
Die Ausnutzung einer XSS-Lücke zum Zwecke des URL-Spoofings ist dann am einfachsten durchführbar, wenn der manipulierende Code einfach an den Aufruf angehängt werden kann. Ein Session-Riding-Angriff lässt sich dann in einem IMG-Tag verstecken und unbemerkt ausführen. Ähnliches gilt für andere Angriffsformen. Möglich ist dies immer dann, wenn die Anforderung ("request") von der Anwendung als GET-Request behandelt wird. Verwendet die Anwendung an dieser Stelle jedoch die POST-Methode, ist ein Einbau in die URL nicht mehr möglich. Es empfiehlt sich daher, HTML-Forms per POST-Methode zu übertragen, so dass im Falle einer vorhandenen XSS-Lücke wenigstens eine kleine zusätzliche Hürde gesetzt wird. Allerdings abstrahieren viele heutige Frameworks und Komfortfunktionen die Request-Methode, d. h., sie liefern die übergebenen Parameter, egal ob diese per GET oder POST geschickt worden sind. Selbst dann, wenn in der Form ein POST als Request-Methode angegeben ist, kann ein Angreifer die Daten an die URL hängen und per GET übertragen, da die Anwendung nicht unterscheidet. Der Ausschluss von GET ist daher von der Anwendung zu erzwingen oder zumindest vorzuziehen.[3]
Escape-Funktionen
Als Anhaltspunkte sind hier Escape-Funktionen verschiedener Programmiersprachen (Ausschnitt) aufgeführt:
ASP
Request.Form() Request.QueryString() Request.Cookies() RangeValidator() RegularExpressionValidator() Server.HTMLEncode() Server.URLEncode()
Java
class java.sql.PreparedStatement java.net.URLEncoder.encode()
Perl
CGI::autoEscape() CGI::escapeHTML()
PHP
addslashes() quote_meta() mysql_real_escape_string() pg_escape_string() strip_tags() htmlentities() utf8_decode()
Minimalitätsprinzip
Beim Minimalitätsprinzip werden so wenige Informationen angegeben wie nötig, so dass sie für einen potenziellen Angreifer oder „Hacker“ nur schwer oder gar nicht zugänglich sind, um die Verwundbarkeit von Sicherheitslücken einzuschränken. Darüber hinausgehende Informationen könnten unnötige Ansatzpunkte für eine Kompromittierung der Webanwendung liefern.
URL-Weiterleitungen kontrollieren und einschränken
Weiterleitungen sind generell durch geeignete Maßnahmen vor Missbrauch zu schützen.
Linkeinschränkung
Sind die Links, auf die weitergeleitet wird, konkret bekannt, so ist die Weiterleitung auch nur für diese zu erlauben. Alle anderen Parameter sind abzulehnen. Das ist am besten dadurch zu erreichen, dass nicht die Ziel-Seite selbst als Parameter übergeben wird, sondern ein Index in einer Datenbank, die serverseitig gehalten wird, und in der alle in Frage kommenden URLs enthalten sind.
Weiterleitungshinweis
Statt die Umlenkung direkt und für den Benutzer transparent durchzuführen, ist sie indirekt über eine Seite zu führen, die dem Benutzer angezeigt wird. Damit kann dieser den Link vor dem aktiven Klick prüfen und selbst entscheiden, ob er diesem vertraut. Beispiel:
Sie werden auf die folgende externe Webseite weitergeleitet: http://www.example.tld/angriff.foo Aus Sicherheitsgründen führen wir die Weiterleitung nicht automatisch durch. Bitte kontrollieren Sie den Link, und setzen Sie die Weiterleitung gegebenenfalls durch einen Klick fort!
Referrer-Test
Der Referrer kann als zusätzliches Merkmal beachtet werden. Diesem Ansatz liegt die Annahme zugrunde, dass eine Anforderung ("request") nur dann legitim ist, wenn sie durch einen Klick auf einer zur Anwendung gehörenden Seite ausgelöst worden ist. Immer dann ist auch der Referrer-Header mit der URL dieser Seite belegt. Die Anwendung muss also prüfen, ob der übergebene Referrer in der Liste der in Frage kommenden URLs vorhanden ist, und kann im Positiv-Fall davon ausgehen, dass es sich um die legitime Verwendung handelt. Dabei ist es wichtig, die gesamte URL zu vergleichen und nicht nur den Host-Anteil, denn der so erreichte Schutz kann durch eine XSS-Schwachstelle auf derselben Seite – ggf. auch außerhalb der Anwendung selbst – wieder zunichtegemacht werden. Zwar lässt sich der Referrer per JavaScript nicht direkt manipulieren, über den Umweg des Cross-Site-Scripting ist es dann aber doch möglich. Außerdem ist der Referrer nicht immer verfügbar, da ihn manche Contentfilter auf der Client-Seite herausfiltern.
Lokale Weiterleitungen einschränken
Erfolgt die Weiterleitung auf eine Seite derselben Website, so ist vor der Ausführung zu prüfen, dass als Parameter keine URL übergeben worden ist, die auf eine externe Seite führt. Am einfachsten werden lokale Weiterleitungen ausschließlich mit relativen Pfaden durchgeführt und der Host-Teil (d. h. der Rechnername bzw. die Domain) statisch hinzugefügt. Statt also die Weiterleitung so zu programmieren, dass ein vollqualifizierter Link übergeben werden muss, sollte der Parameter lediglich den internen Zielpfad enthalten, wobei die Domain statisch hinzugefügt wird.
Session Management
Das Session Management ist eine der problematischsten Stellen für die Sicherheit von Webanwendungen. Für den Schutz der SessionID sollten daher entsprechend wirksame Maßnahmen zur Anwendung kommen.[4]
Anforderung an eine SessionID
Wird die Erzeugung der SessionID nicht einer ausgereiften API überlassen, sondern selbst implementiert, sind bestimmte Anforderungen zu beachten. Für diese Fälle sollten folgende Anforderungen berücksichtigt werden:
- Keine Verknüpfung mit extern bekannten oder erratbaren Daten. Dazu gehören: IP-Adresse des Clients, Uhrzeit, Prozess-ID, Attribute des Benutzers wie Geburtsdatum oder externe Schlüssel wie die E-Mail-Adresse.
- Hohe Zufälligkeit (Randomness): Das Erzeugungsmuster darf nicht aus einer Menge von Proben ableitbar sein.
- Die SessionID muss eine ausreichende Länge haben, um gegenüber Brute-Force-Angriffen – dem Durchprobieren aller Möglichkeiten – zu bestehen.
- Sie sollte ausschließlich über sichere Kanäle übertragen werden, wenn der Schutzbedarf der Anwendung dies erfordert.
- Die SessionID einer Anwendung, deren Schutzbedarf SSL erfordert, darf niemals versehentlich über eine unverschlüsselte Verbindung mit übertragen werden.
- Die Session selbst muss das kürzestmögliche Ablaufdatum haben, das für den jeweiligen Anwendungszweck gerade noch angemessen ist.
Bindung von zusätzlichen Parametern an die Session
Eine Session kann durch Einbeziehung von zusätzlichen Parametern (z. B. der IP-Adresse des Clients) als kennzeichnendes Merkmal zusätzlich geschützt werden, sofern die daraus resultierenden Probleme in Kauf genommen werden können. Als Beispiel hinterlegt die Anwendung bei der Instanziierung der Session die IP-Adresse des Clients und überprüft bei jedem Zugriff, ob diese mit der hinterlegten IP-Adresse weiterhin übereinstimmt. Ist das nicht der Fall, wird die Session invalidiert.
Nachteilig an diesem Lösungsansatz sind deutliche Beschränkungen in Bezug auf mögliche Einsatzumgebungen: Die Bindung der IP-Adresse an die Session funktioniert nicht oder nur eingeschränkt für all jene Benutzer, die sich hinter einem Proxy befinden. Das trifft z. B. auf größere Organisationen oder auch auf Kunden eines Internet-Access-Providers zu, der eine Proxy-Architektur einsetzt. In einer solchen Umgebung kann es vorkommen, dass im Verlaufe einer Applikations-Session der ausgehende Proxy oder Router bzw. die IP dessen wechselt und damit bei der Webanwendung eine andere IP-Adresse registriert wird. Als weitere Hindernisse sind software- und netzwerktechnische Gegebenheiten zu nennen, die dazu führen können, dass bei der Webanwendung die IP-Adresse des zugreifenden Benutzers gar nicht ankommt, sondern nur diejenige eines vorgeschalteten Reverse-Proxy oder einer anderen Komponente im eigenen Netz. Eingesetzt werden kann der vorgeschlagene Lösungsansatz jedoch in jenen Anwendungssituationen, in denen die oben genannten Nachteile nicht eintreten oder toleriert werden können. So z. B. sind die beschriebenen Hindernisse in der Regel in Intranet-Bereichen nicht vorhanden, so dass hier die Bindung der Session an die IP-Adresse bei Anwendungen mit erhöhtem Schutzbedarf als eine zusätzliche Sicherheitsmaßnahme erfolgen kann.
Session Riding
Session Riding ist durch Einführung eines SessionCodes oder durch eine andere Schutzmaßnahme zu verhindern. Die im Folgenden angeführten Maßnahmen sind geeignet, um Session Riding zu verhindern.
Dialogtracking
Die sicherste Form des Session Managements erreicht man durch ein Dialogtracking. Dabei ist der SessionCode nicht statisch, sondern wird bei jedem Zugriff neu vergeben. Wir bezeichnen jenen SessionCode als Token. Die Anwendung baut in jeden Dialogschritt (d. h. jeden Link in einer Seite) das diesen Dialogschritt eindeutig kennzeichnende Token ein. Erhält sie einen Request, prüft sie, ob das Token für diesen Aufruf gültig ist und streicht es aus der Liste der gültigen Token. Ein erneuter Aufruf dieses Links (Replay durch den Angreifer) ist damit nicht mehr möglich. Auch ist es nicht möglich, eine Aktion ohne Token aufzurufen. Die Kenntnis der SessionID und eines auf dem Übertragungsweg ausgespähten Tokens ist damit nicht mehr ausreichend, um in die Session einzudringen. Man muss gleichzeitig auch das Token von mindestens einem „unverbrauchten“ (d. h. noch nicht aufgerufenen) Link besitzen.
Privilege Escalation
Privilege Escalation bezeichnet die unautorisierte Erhöhung der Privilegien, die einem angemeldeten Benutzer zugeordnet sind, der einer bestimmten Rechtegruppe (Benutzergruppe) angehört.
Beispielhaft habe eine Anwendung zur Bestellabwicklung für jede neue Bestellung eine eindeutige ID vergeben. Diese IDs werden in der Reihenfolge der Bestellaufgabe und über alle Benutzer hinweg sequentiell erzeugt. Ein Benutzer kann sich die eigenen Bestellungen über eine Web-Schnittstelle anzeigen lassen. Ausgegeben wird eine Liste von Bestellungen, die durch eine Folge nun nicht mehr zusammenhängender IDs identifiziert werden. Nur auf diese Bestellungen soll der Benutzer zugreifen dürfen. Beim anschließenden weiteren Zugriff auf eine konkrete Bestellung wird die ID als Parameter mit übergeben. Privilege Escalation kann nun dann vorliegen, wenn die Anwendung beim Zugriff auf einen Datensatz nicht mehr prüft, ob der Benutzer rechtmäßiger Eigentümer dieses Datensatzes ist, sondern einfach die als Parameter übermittelte ID zum Zugriff auf die Datenbank heranzieht.
Zur Verhinderung von Privilege Escalation muss beim Bearbeiten oder Einsehen eine Bestellung kontrolliert werden, ob die über die ID identifizierte Bestellung entweder dem anfragenden Benutzer gehört oder ob der Benutzer eventuell der Administrator ist. In einer modernen Anwendung mit einer Model-View-Controller (MVC)-Struktur ist dies relativ einfach zu bewerkstelligen, indem die Kontrollfunktion im Modell (der Business-Logik) verankert wird. Die Praxis zeigt jedoch, dass diese Kontrolle häufig ganz oder teilweise in der Controller-Schicht vorgenommen wird. Nachteile sind duplizierter Code und dass ein Entwickler vergessen könnte, die Kontrolle überhaupt einzubauen. Ein Grund dafür ist, dass an Sicherheit meist zu einem sehr späten Zeitpunkt gedacht wird und Änderungen am Business-Modell dann zu aufwändig sind. Ein anderer Grund sind funktionale Erweiterungen wie z. B. die nachträgliche Einführung des oben genannten Administrators, die eine grundsätzliche Überarbeitung des Sicherheitskonzepts notwendig machen würde.
Hashes
Wenn die Anwendung Werte an den Browser sendet, die dieser nicht verändern darf (was bei einer SessionID der Fall ist), die aber mit einem Form-Request wieder zur Anwendung zurückkommen, dann muss die Anwendung die erhaltenen Werte mit einer Data Validation auf gültige Werte prüfen. Sollen die eigentlichen Werte zusätzlich vor Ausspähen geschützt werden, so empfiehlt sich die Verwendung von signierten Hashes anstatt der „Klartext“-Werte.
URL-Rewriting
Erfordert die Anwendung URL-Rewriting, so sollte ein Benutzer auf die Gefahren des Ausspähens hingewiesen und dazu aufgefordert werden, sich beim Verlassen des PCs aus der Webanwendung auszuloggen oder den Rechner zu sperren. Durch Verwendung sehr langer SessionIDs, die ein Abschreiben erschweren oder die Verwendung langer URLs mit der SessionID am Ende (so dass sie aus dem sichtbaren Bereich am Bildschirm herausgeschoben ist) kann zudem etwas gegen das Über-die-Schulter-schauen (z. B. in öffentlichen Orten) getan werden. Insbesondere ist ein Benutzer darauf hinzuweisen, niemals eine gespeicherte Seite oder einen kopierten Ausschnitt aus einer solchen Seite zu versenden. Es ist außerdem sicherzustellen, dass beim URL-Rewriting nicht versehentlich auch externe Links mit der SessionID versehen werden. Der Referrer, der beim Einsatz des URL-Rewritings auch die SessionID enthält, darf zudem nicht zu fremden Hosts gelangen. Dies ist dadurch sicherzustellen, dass Links auf externe Seiten niemals direkt gesetzt werden, sondern immer über einen Redirect (Weiterleitung) geführt werden.
Logout erzwingen
Jede Anwendung, die eine Login-Funktion hat, sollte auch eine Logout-Funktion besitzen. Das Logout hat das korrekte Invalidieren der Session sicherzustellen. Bei zahlreichen Webanwendungen ist zu beobachten, dass eine Logout-Funktion zwar vorhanden ist und der Benutzer nach Ausführung auch die Bestätigung erhält, nun abgemeldet zu sein, dass die Session aber nicht invalidiert wird. Zu erkennen ist das meist daran, dass die Betätigung des Zurück-Buttons des Browsers bis zu einer Seite innerhalb der Anwendung ein Weiterarbeiten darin nach wie vor ermöglicht. Mit einer gestohlenen SessionID könnte in einem solchen Fall weitergearbeitet werden (zum Beispiel in einem Internet-Café).
Der Benutzer ist darin zu animieren, das Logout auch wirklich auszuführen. Dies kann wie folgt durchgeführt werden:
- einfache und klare Darstellung des Logout-Buttons
- Hinweis nach dem Login
- Hinweis nur dann nach dem Login, falls dies beim letzten Mal nicht geschehen ist.
Schließt der Benutzer das Browser-Fenster in der Annahme, sich dadurch auch automatisch auszuloggen (was aber nicht der Fall ist), so sollte die Anwendung den Benutzer beim nächsten Login darüber informieren, dass ein automatisches Ausloggen erfolgte, und in Zukunft ein explizites Ausloggen stattfinden sollte.
Benutzer
Umgang mit Benutzerkennungen
Um die Sicherheit erheblich zu steigern, sollte die Benutzerkennung als nicht-öffentliche Information behandelt werden. Insbesondere sind E-Mail-Adressen sowie Schemata wie vorname.nachname zu vermeiden. Es wird empfohlen, stattdessen nicht ableitbare Zeichenketten zu verwenden oder eine Kombination aus externen Merkmalen mit einer nicht-erratbaren Komponente zu gestalten. Zudem ist darauf zu achten, dass die Anwendung keine Hinweise über das Vorhandensein von Benutzerkennungen gibt. Häufig anzutreffen ist diese Art der Implementierung einer „Passwort vergessen“-Funktion: Der Benutzer wird aufgefordert, seine eindeutige Identifikationsnummer (UserID) einzugeben. Ist diese korrekt, d. h., existiert die Nummer in der Datenbank, so lautet die Antwort: „Das Passwort wurde an die hinterlegte E-Mail-Adresse verschickt“. Wurde jedoch eine nicht existierende Identifikationsnummer eingegeben, so lautet die Antwort: „Dieser Benutzer existiert nicht, bitte korrigieren Sie Ihre Eingabe“. Auf diese Weise lassen sich Benutzerkennungen durch Aufzählen (Enumeration) ermitteln. Richtig wäre folgende Antwort, die keine Information über das Vorhandensein einer UserID gibt: „Das Passwort wurde an die hinterlegte E-Mail-Adresse verschickt, falls die eingegebene UserID korrekt gewesen ist. Sollten Sie nicht in Kürze eine E-Mail von uns erhalten, so ist dies darauf zurückzuführen, dass Sie eine fehlerhafte UserID eingegeben haben“.
Sichere Passwörter
Die Benutzung von sicheren Passwörtern ist dadurch zu erreichen, dass das System nicht jedes vom Anwender gewünschte Passwort akzeptiert und Regeln vorgibt sowie die Einhaltung dieser prüft. Bisher existieren für das Web keine allgemein anerkannten Verfahren und auch keine Standardbibliotheken zur Passwortprüfung. Auch wird häufig in der jeweiligen Anwendungssituation die Berücksichtigung anwendungsspezifischer Randbedingungen erforderlich sein. Generell sollten Passwörter aus einfachen Wörterbuchwörtern, persönlichen Angaben (Name, Geburtstag etc.) sowie einfachen Zahlenkombinationen vermieden werden. Es empfiehlt sich eine Kombination aus (auch absichtlich falsch geschriebenen) Wörtern, Sonderzeichen, Groß- und Kleinschreibung sowie Zahlen. Dabei ist auch die Länge des Passworts von entscheidender Bedeutung.
Einsatz eines SSL/TLS/HTTPS-Protokolls
Daten, bei denen Ausspähen verhindert werden muss (z. B. Passwörter, Bankdaten etc.) sind durch Einsatz des SSL-Protokolls zu schützen. Das SSL-Protokoll verschlüsselt die zwischen Browser und Server ausgetauschten Daten und sorgt dafür, dass vertrauliche Informationen vor dem Ausspähen auf dem Übertragungsweg geschützt sind. Diesen Schutz führen heutige Browser so weit, dass auch bei einem Wechsel von einer per SSL geschützten Seite (HTTPS) zu einer ungeschützten Seite (HTTP) – etwa dann, wenn der User auf der SSL-geschützten Seite auf einen HTTP-Link klickt – sensitive Protokollinformationen nicht weitergegeben werden. Das SSL-Server-Zertifikat stellt außerdem sicher, dass der Hostname authentisch ist. D. h., es garantiert, dass der im Zertifikat angezeigte Hostname unverfälscht ist. Schließen wir den Fall aus, dass der DNS manipuliert worden ist, so garantiert das Zertifikat auch die Echtheit des Hosts (sofern die Seite keine Frames benutzt).
Hilfsprogramme für die Sicherheit von Web-Anwendungen
Es gibt u. a. folgende Web Application Security Tools:
Web Shields
WebShields (auch: Web Application Firewall) filtern den Datenstrom zwischen Browser und Webanwendung und können mit Firewalls verglichen werden. Tritt ein als unzulässig eingestuftes Eingabemuster auf, wird der Transfer unterbrochen oder auf eine andere, vorher festgelegte Weise reagiert. Ein WebShield arbeitet als Proxy im Datenstrom, kennt somit das Protokoll der Anwendung. Grundsätzlich filtern WebShields die vom Browser an den Webserver übertragenen Daten. Einige WebShield-Produkte können zusätzlich die vom Webserver an den Browser versandten Daten überwachen. Hierbei kann das WebShield „lernen“, wie die Daten beschaffen sind. Dadurch wird ein späterer Vergleich zwischen aktuellen und gelernten Daten ermöglicht. So können Filter in eingeschränktem Maße verhindern, dass der Browser schadhaften Code erhält. WebShields sind nicht fähig, alle Angriffsformen auf Webanwendungen zu erkennen. Generell gilt: Sicherheitsprobleme sollten in der Webanwendung selbst gelöst werden. WebShields sollten nur als zusätzliche Schutzmaßnahme in Betracht gezogen werden.
Web Scanner
Web Scanner (auch: Web Application Scanner) sind Programme für Penetrationstests. Sie untersuchen eine Anwendung auf bekannte Schwachstellen und unterstützen dabei den Webentwickler oder Penetrations-Tester beim Auffinden von Sicherheitslücken. Allerdings kann dies auch von einem Angreifer verwendet werden. Dabei wird auf einem Client-Computer der Web-Scanner installiert, um dann die (auf einem anderen entfernten Server liegende) Webanwendung zu analysieren. Allgemein gilt: Web-Scanner sind sinnvolle Hilfsmittel, um erfahrenen Benutzern bei der Analyse der Sicherheitseigenschaften einer Webanwendung zu unterstützen. Sie sind jedoch weder in der Lage, fehlendes Wissen zu kompensieren, noch können sie Experten ersetzen. Die einer Webanwendung innewohnende Komplexität und die Tatsache, dass manche Schwachstellen von einem Hilfsprogramm ("tool") grundsätzlich nicht erkennbar sind, haben zur Folge, dass weiterhin geübte Personen für den Großteil der Analyse benötigt werden. Eine Interpretation eines Web-Scan-Reports ist ohne Erfahrung im Testen von Webanwendungen nur schwer möglich. Im Zuge einer Analyse können folgende vier Phasen durchlaufen werden:
Crawl/Scan: Der Web-Scanner bewegt sich ähnlich wie eine Suchmaschine durch die gesamte Webanwendung. Dabei werden sämtliche Links besucht und gegebenenfalls Formfelder mit Testwerten ausgefüllt. Der Scanner erhält so ein umfassendes Wissen über den Aufbau der Webanwendung, die Funktionsweise von Dialogschritten und den Inhalt von Formularseiten. Die Webanwendung wird außerdem auf häufig vorhandene Installations-, Konfigurations- oder Testverzeichnisse sowie bekannte problematische oder informative Dateien durchsucht. Unterstützt werden kann die Scan-Phase durch Einbeziehen großer öffentlicher Suchmaschinen. Vorausgesetzt wird hierfür, dass die zu analysierende Website bereits durch diese Suchmaschinen indexiert worden ist. Die Ergebnisse dieses Schrittes wurden dann auf den Suchmaschinen gespeichert (Index oder Cache). Im Rahmen einer Scan-Phase können diese Suchmaschinen nun gezielt nach Informationen über die Website abgefragt werden. Für die Zusammenstellung von Suchmustern, sowie Automatisierung der Abfragen kann die Nutzung spezieller Hilfsprogramme zweckmäßig sein.
Analyse: In einem nächsten Schritt wird die Webanwendung einer eingehenden Sicherheitsanalyse unterzogen. Die gewonnenen Erkenntnisse können in einer Datenbank hinterlegt werden: Typ und Version des Webservers, verwendete Technologien und Tools (CGI, Servlets, JSP, JavaScript, PHP usw.), Verwendung von Cookies oder anderer Mechanismen zum Session-Tracking, Analyse der Formular-Parameter einer Seite, insbesondere auch die Verwendung von versteckten Parametern ("hidden parameter") sowie der Extraktion von Kommentaren.
Audit/Penetrationstest: Unter Einbeziehung des in der vorangegangenen Phase gewonnenen Wissens werden systematisch fehlerhafte oder unzulässige Eingabemuster erzeugt und an die Webanwendung versandt. Einige der existierenden Scanner unterteilen diese Phase in eine schadlose und eine potentiell schadhafte Prüfung.
Reporting: Die Ergebnisse der Scan- und Audit-Phase werden in Berichten ("report") zusammengefasst. Der Umfang reicht dabei von kurzen Zusammenfassungen mit Nennung nur der größten Schwachstellen bis hin zu detaillierten Beschreibungen, in denen auch erste Hinweise für die Behebung des jeweiligen Problems gegeben werden können.
Strafrechtliche Aspekte
Jegliches rechtswidrige Verändern, Löschen, Unterdrücken oder Unbrauchbar-Machen fremder Daten erfüllt den Tatbestand nach § 303a StGB (Datenveränderung). In besonders schweren Fällen ist dies auch nach § 303b I Nr. 1 StGB („Computersabotage“) strafbar und wird mit Haftstrafe von bis zu fünf Jahren oder Geldstrafe bestraft. Die Durchführung von DDOS-Attacken stellt seit 2007 ebenfalls eine Computersabotage dar, gleiches gilt für jegliche Handlungen, die zur Beschädigung eines Informationssystems, das für einen anderen von wesentlicher Bedeutung ist, führen.
Das Ausspähen von Daten (§ 202a StGB), also die Erlangung des Zugangs zu fremden Daten, die hiergegen besonders geschützt sind, wird mit Haftstrafe bis zu drei Jahren oder mit Geldstrafe bestraft. Das Abfangen fremder Daten in Netzen oder aus elektromagnetischen Abstrahlungen ist seit 2007 ebenfalls strafbar, anders als bei § 202a StGB kommt es hier nicht auf eine besondere Zugangssicherung an. Das sich Verschaffen, Erstellen, Verbreiten, Öffentlich-zugänglich-machen etc. von sog. „Hackertools“ steht ebenfalls seit 2007 unter Strafe, wenn damit eine Straftat vorbereitet wird (§ 202c StGB).
Daten sind nach § 202a Abs. 2 in Verbindung mit Abs. 1 aber nur vor dem Ausspähen geschützt, wenn sie „besonders gesichert“ sind, um ein Ausufern des Tatbestandes zu vermeiden. Das heißt, erst wenn der Nutzer seine Daten technisch schützt genießt er auch den strafrechtlichen Schutz. Die frühere Debatte, ob das „Hacken“ ohne Abruf von Daten strafbar sei, ist hinfällig, seit der Wortlaut der Norm 2007 derart geändert wurde, dass Strafbarkeit bereits mit Erlangung des Zugangs zu Daten einsetzt. Weiter ist umstritten, ob die Verschlüsselung zur besonderen Sicherung zählt. Sie ist zwar sehr effektiv, aber es wird argumentiert, die Daten seien ja nicht gesichert, sondern lägen nur in „unverständlicher“ bzw. schlicht „anderer“ Form vor.
Als Computerbetrug wird nach § 263a StGB mit Geldstrafe oder Freiheitsstrafe bis zu fünf Jahren bestraft, wenn Datenverarbeitungsvorgänge zur Erlangung von Vermögensvorteilen manipuliert werden. Schon die Erstellung, Verschaffung, Anbietung, Verwahrung oder Überlassung dafür geeigneter Computerprogramme ist strafbar.
Siehe auch
Literatur
- Joel Scambray, Vincent Liu, Caleb Sima: Hacking Exposed: Web Applications: Web Application Security Secrets and Solutions. 3. Auflage. Verlag Mcgraw-Hill Professional, 2010, ISBN 978-0-07-174064-7.
- Mario Heiderich, Christian Matthies, Johannes Dahse, fukami: Sichere Webanwendungen: Das Praxisbuch. 1 Auflage. Verlag Galileo Computing, 2008, ISBN 978-3-8362-1194-9.