Sicherheit von Webanwendungen

Seite 3: Weiße Weste

Inhaltsverzeichnis

Beim Erstellen von Filterfunktionen ist das Whitelisting bestimmter Zeichen, also das explizite Zulassen, stets sicherer als das Blacklisting, also das explizite Verbieten, weil es nur selten gelingt, wirklich alle potenziell problematischen Werte zu erfassen. White- und Blacklisting ist aber nicht nur für den Zeichenvorrat sinnvoll. Bei der Angabe eines Herkunftlandes etwa kann man ebenso gut auf eine Länderliste zurückgreifen.

Wenn sich die Eingabedaten nicht ohne Weiteres auf eine überschaubare Menge erlaubter Werte beschränken lassen, ist zumindest das sogenannte Escaping ratsam, mit dem Sonder- und Steuerzeichen ihrer Spezialfunktion beraubt werden. Es muss allerdings immer unter Berücksichtigung des vorgesehenen Einsatzzweckes der Daten erfolgen. Die meisten Skriptsprachen bieten dafür besondere Funktionen.

PHP stellt gleich einen ganzen Fundus an Filterfunktionen bereit. htmlentities() ersetzt alle HTML-Sonderzeichen durch ihre HTML-Codes, beispielsweise < durch <. addslashes() entschärft sämtliche Hochkommata durch Voranstellen eines Backslashes. mysql_real_escape_string() filtert Zeichenketten unter Berücksichtigung der Besonderheiten von MySQL-Statements, escapeshellcmd() leistet dasselbe für Shell-Befehle und ihre Parameter. Zur Vertiefung der Aspekte sicherer PHP-Programmierung ist der Abschnitt "Sicherheit" des PHP-Handbuches sehr empfehlenswert [7].

Häufig entstehen auch Sicherheitsprobleme, wenn sich in einer modularen Webapplikation Skripte, die regulär nur von anderen Applikationsskripten aufgerufen werden sollten, direkt durch den Anwender starten lassen, wie etwa die zuvor erwähnten phpBB-Plug-ins. Modulskripte, die nicht zur selbstständigen Ausführung vorgesehen sind, sollten daher gegen direkten Aufruf geschützt werden, in PHP beispielsweise durch Voranstellen einer Zeile wie

defined ('_GLOBALER_WERT') or die ('Direkter Aufruf verboten.');

Ein so geschütztes PHP-Skript lässt sich nur durch andere Skripte starten, die vor dem Modulaufruf beispielsweise ein

define ('_GLOBALER_WERT', null);

vorgenommen haben.

Für SQL-Anfragen ist es ratsam, auf sogenannte Prepared Statements umzusteigen [6]. Darunter versteht man vorgefertigte SQL-Ausdrücke, die mit Platzhaltern versehen sind. Dies führt dazu, dass Skripte SQL-Befehle sowie die für die Platzhalter einzutragenden Werte fein säuberlich getrennt an das API übergeben. Die für SQL-Injektionen nötige Durchmischung ist bei Prepared Statements nicht mehr ohne Weiteres möglich. PHP unterstützt sie seit Version 5 über die mysqli-Erweiterung, unter Perl sind sie mit dem DBI-Modul möglich.

Schon mit der Konfiguration der Skripting-Umgebung ist es möglich, einen guten Teil der denkbaren Angriffsszenarien auf einen Schlag zu vereiteln oder mindestens zu erschweren. Durch Setzen einer Handvoll Optionen und Parameter lassen sich gefährliche Funktionen abstellen oder der mögliche Schaden im Ernstfall begrenzen. Daher ist es sinnvoll, eine Webapplikation gezielt auf einer möglichst streng abgesicherten Skripting-Umgebung zu entwickeln. Dabei gilt das Prinzip der wenigsten Privilegien: Je weniger Rechte und Funktionen eine Applikation voraussetzt und erhält, desto weniger kann schiefgehen.

Dieses verlockende E-Plus-Angebot sieht täuschend echt aus, war aber das Ergebnis eines erfolgreichen XSS-Angriffes.

Der Kasten zur php.ini zeigt die wichtigsten Sicherheitsoptionen, die PHP von Haus aus mitbringt. Sie lassen sich über die zentrale Konfigurationsdatei php.ini einstellen. Doch nicht alle Webanwendungen kommen mit jeder Option zurecht. Sofern der Server mehrere Applikationen bereitstellt, sind die Optionen einzeln auf ihre Kompatibilität zu prüfen. Leider ist es oft unumgänglich, sich auf den kleinsten gemeinsamen Nenner zu einigen oder Problemapplikationen auf weniger restriktive Server auszulagern.

Shared-Webhosting ist für den sicheren Einsatz einer PHP-Applikation kaum empfehlenswert. Die vielen Inkompatibilitäten fertiger PHP-Software zu verschärften Sicherheitseinstellungen, die sich bei PHP nur global setzen lassen, zwingen die meisten Shared-Hosting-Betreiber zu einer unsicheren Konfiguration.

Ein besonderer Betriebsmodus von PHP5, der während der Skriptentwicklung teilweise zur sauberen Programmierung nötigt, lässt sich jedoch auch pro Skript erzwingen. Nach dem Aufruf error_reporting (E_STRICT); gibt der Interpreter Warnhinweise beispielsweise bei Verwendung uninitialisierter Variablen aus.

Die Skriptsprache Perl geht mit dem sogenannten Taint-Modus noch weiter. Um ihn für ein Skript zu aktivieren, gibt man in der ersten Zeile die Option -T an:

#!/usr/bin/perl -T

In dieser Betriebsart dürfen vereinfacht gesagt keine Daten, die von außerhalb des Skriptes stammen, ohne Weiteres an Unterprozesse des Skriptes weitergegeben werden. Der Perl-Interpreter betrachtet unter anderem auch sämtliche GET- und POST-Variablen als "tainted" (unsauber). Wenn etwa die Variable $formular{"eMail"} aus Formulardaten des Nutzers stammt, kommt es zu einem Programmabbruch, sobald ein aus ihr zusammengesetzter Wert beispielsweise an einen Shell-Befehlaufruf mittels system() übergeben wird.

Der Taint-Modus zwingt den Entwickler gewissermaßen zum ordentlichen Umgang mit Daten von außerhalb der Applikation, denn es gibt nur zwei Möglichkeiten, aus unsauberen Variablen saubere Daten zu gewinnen: sie als Schlüssel in einem Hash zu verwenden oder sie mit einem regulären Ausdruck zu filtern. Ob der Interpreter eine Variable als unsauber ansieht, lässt sich seit Perl 5.8 mit der Funktion tainted() aus dem Modul Scalar::Util feststellen. Die weiteren Funktionen des Taint-Mode sind in der Manpage "perlsec" umfassend dokumentiert.

Wesentlicher Bestandteil der Sicherheit einer Webanwendung ist die Sicherheit des Servers und und des Netzwerks, auf dem sie läuft. Gelangt ein Angreifer beispielsweise an Login-Daten eines Datenbankservers, sind diese für ihn praktisch wertlos, solange er keinen Zugriff auf den Server erlangt. Der Zugang zu derartigen Backend-Systemen sollte nur für Rechner erlaubt sein, die wie beispielsweise die Webserver auch tatsächlich Zugriff benötigen. Auch hier gilt das Prinzip der geringsten Privilegien.

Bei der Hamburger Sparkasse konnte durch Cross Site Scripting statt des schwarzen Kastens ohne Weiteres auch ein gefälschtes Überweisungsformular oder unsichtbarer Schadcode stehen.

Mit Applikations-Firewalls wie mod_security für den Webserver Apache [10] lässt sich bereits auf Serverebene steuern, welche Daten an die Applikation gelangen dürfen und welche nicht. Dies kann allerdings nur als ergänzende Maßnahme gelten und eine saubere Programmierung der Webanwendung keinesfalls ersetzen. Bewusstsein schaffen

Perfekte Sicherheit gibt es nicht. Softwareentwickler arbeiten oft unter hohem Zeit- und Kostendruck und der Wert ihrer Arbeit wird in der Regel an zügiger Entwicklung, Bedienbarkeit und Layout gemessen. Daher ist es erforderlich, dass Sicherheitskriterien schon in die Planungsphase einer Webapplikation einfließen. Sicherheitsvorgaben sollten bereits Teil des Anforderungskataloges sein, damit sie nicht aus Kostengründen unter den Tisch fallen.

Darüber hinaus empfiehlt es sich, ein umfassendes Sicherheitskonzept zu entwickeln, insbesondere wenn personenbezogene Daten verarbeitet werden. Keinesfalls sollten die Planungen zur Behebung von Schwachstellen erst nach ihrem Bekanntwerden beginnen. Entscheidend für die Sicherheit einer Webanwendung ist schließlich auch der Zeitraum zwischen Entdeckung und Behebung eines Sicherheitsproblems. Sicherheit ist kein Zustand, sondern ein andauernder Prozess.

siehe auch:

Unterthema: Das PHP-Dilemma
Unterthema: Die wichtigsten Sicherheitsoptionen in der php.ini

[1] Daniel Naber, Schotten dicht, Typische Programmierfehler bei CGI-Skripten und Web-Anwendungen vermeiden, c't 24/02, S. 220

[2] Tobias Glemser, Reto Lorenz, Offen wie Scheunentore, Webhoster-Sicherheitslücken durch Skriptsprachen, c't 14/02, S. 72

[3] Holger Bleich, Jürgen Schmidt, Auf Phishzug, Passwort-Diebstahl im Web wird raffinierter, c't 17/04, S. 178

[4] Phishmarkt: Online-Demonstration bekannter XSS-Lücken

[5] Details zur Lücke im T-Online-Karriereforum

[6] Fortgeschrittene SQL-Injektion und Schutz durch Prepared Statements

[7] Das PHP-Handbuch

[8] Sicherheitserweiterung suEXEC für Apache

[9] Dokumentation zum PHP-Safe-Mode

[10] Christiane Rütten, Die Apache-Firewall, Web-Server mit mod_security absichern