Wer einschlägige Mailinglisten verfolgt, findet den schlechten Ruf von Webanwendungen als Security-Albtraum bestätigt. Woran das liegt, darüber streiten die Experten. Bringt die verteilte Struktur von Webanwendungen mit zustandslosem Protokoll und allerhand Klimmzügen die Sicherheitsprobleme schon mit sich, liegt es an Programmiersprachen wie PHP oder sind Webprogrammierer einfach nur schlecht ausgebildet? Was auch immer die Ursache ist, fest steht, dass es so nicht bleiben kann.
Ein ganzheitlicher Ansatz, der von Grund auf alle Komponenten vom Betriebssystem über den Webserver bis zur Programmiersprache neu entwirft, ist nicht zu erwarten. Stattdessen arbeiten die Protagonisten der Web-Evolution an der Verbesserung einzelner Komponenten, was nach allgemein verbreiteter Meinung zwar nicht die beste Lösung ist, aber immer noch besser als nichts.
Nicht gut: Jeder darf alles
Wer fertige Pakete für Onlineforen oder Ähnliches installiert, findet in der Installationsanleitung häufig einen Absatz, der zur Einrichtung eines für alle beschreibbaren (world-writable) Verzeichnisses auffordert - nicht unbedingt das, was man sich unter einer sicheren Konfiguration vorstellt. Der Grund dafür ist unter anderem, dass der Webserver mit einer anderen Benutzer-ID läuft als jener, der die entsprechenden Verzeichnisse gehören. Umso schlimmer, wenn sich mehrere User einen Server teilen. Ob sie nun Verzeichnisse für alle oder nur die Webserver-UID beschreibbar machen, das Ergebnis bleibt gleich: Jeder kann in die Verzeichnisse jedes anderen schreiben. Da ist er wieder, der Albtraum.
Einen Auswege aus dem Dilemma bietet das Apache-Modul Suexec. Gemäß recht restriktiven Vorgaben führt es CGI-Skripte unter konfigurierbaren Benutzer-IDs aus. Im Gegensatz zu früheren Zeiten lässt sich das Suexec-Modul mit Apache 2 relativ leicht verwenden [1]. Die meisten Linux-Distributionen liefern es mit dem Apache-Paket aus.
Bei Fedora beispielsweise enthält das Paket »httpd« die Moduldatei »mod_suexec.so« und den Wrapper »/usr/sbin/suexec«. In Debian Etch heißt das entsprechende Paket »apache2«. Der Apache-Server verrät, aufgerufen mit der Option »-V«, ob er Suexec unterstützt:
$ /usr/sbin/httpd -V | grep -i suexec -D SUEXEC_BIN="/usr/sbin/suexec"
Um die gewünschte Sicherheit zu gewährleisten, hat das Suexec-Programm einige relevante Werte fest einkompiliert, unter anderem die Logdatei, Pfade für ausführbare Dateien, das Web-Wurzelverzeichnis (Document Root) und eben Benutzer- und Gruppen-ID. Auch Suexec verrät seine Konfiguration über eine Kommandozeilenoption, analog zu Apache. Listing 1 zeigt die Einstellungen unter Debian Etch.
01 # /usr/lib/apache2/suexec -V
02 -D AP_DOC_ROOT="/var/www"
03 -D AP_GID_MIN=100
04 -D AP_HTTPD_USER="www-data"
05 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
06 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
07 -D AP_UID_MIN=100
08 -D AP_USERDIR_SUFFIX="public_html"
|
Die Variable »AP_DOC_ROOT« legt das Verzeichnis fest, unterhalb dessen sich die Skripte der Benutzer befinden müssen. »AP_SAFE_PATH« bestimmt den Pfad der ausführbaren Programme, den die Skripte übergeben bekommen. Entsprechend muss die Apache-Konfiguration aussehen. Hier soll »/var/www« mehrere Unterverzeichnisse enthalten, die jeweils einem Benutzer gehören.
Die Zeilen 6 bis 8 von Listing 2 setzen in der Apache-Konfiguration die nötigen Ausführungsrechte für das Verzeichnis des Benutzers »beispiel«, das von Zeile 3 als sein Wurzelverzeichnis festgelegt wird. Zeile 10 weist Dateien mit der Endung ».cgi« als CGI-Skripte aus. Sind das Suexec-Modul geladen und der Wrapper verfügbar, genügt Zeile 4 mit der Direktive »SuexecUserGroup«.
01 <VirtualHost *>
02 ServerName beispiel.example.com
03 DocumentRoot /var/www/beispiel/
04 SuexecUserGroup beispiel beispiel
05
06 <Directory /var/www/beispiel>
07 Options +ExecCGI
08 </Directory>
09
10 AddHandler cgi-script .cgi
11 </VirtualHost>
|
Wer nun im Verzeichnis »/var/www/beispiel« ein CGI-Skript ablegt, wird vermutlich eine böse Überraschung erleben, nämlich einen Internal Server Error oder auch einfach eine leere Seite. Ein Blick in die Suexec-Logdatei (bei Fedora »/var/log/httpd/suexec.log«) verrät Näheres:
target uid/gid (501/501) mismatch with directory (501/501) or program (500/501)
Aus Sicherheitsgründen besteht Suexec darauf, dass die Verzeichnisse und die ausführbaren Dateien auch dem Benutzer gehören, der in der Apache-Konfiguration aufgeführt ist. Stimmen die Eigentumsverhältnisse und Rechte, zeigt das folgende kleine CGI-Shellskript das gewünschte Ergebnis (Abbildung 1).
#!/bin/sh
echo "Content-type: text/html"
echo
echo "UID/GID:" `id`
Nun will vermutlich nicht jeder Webseiten-Betreiber sich aus Sicherheitsgründen wieder der CGI-Technologie aus dem letzten Jahrhundert verschreiben, die verglichen mit der modernen In-Process-Verarbeitung recht langsam ist.
Abbildung 1: Der Browser bringt es an den Tag: Das CGI-Skript läuft mit der über Suexec eingestellten User- und Gruppen-ID.
Trotzdem schnell
Als Alternative zum alten CGI bietet es sich an, die Fast-CGI-Schnittstelle (FCGI) zu verwenden, mit der sich auch PHP-Skripte in die Suexec-Infrastruktur integrieren lassen. Das anscheinend von seinen Entwicklern aufgegebene Mod_fcgi wurde mittlerweile von dem weitgehend kompatiblen Mod_fcgid (das d am Ende beachten) abgelöst [2], das es ebenfalls für die meisten Distributionen als Binärmodul gibt.