Die besseren Webspace-Angebote enthalten das Recht, PHP-Skripte auszuführen. Die Benutzer dürfen somit eigene Server-Applikationen starten - und riskieren meist mehr, als der Admin ahnt. Immerhin ist das Risiko bei PHP kleiner als bei CGI-Skripten. Bei Letzteren laufen auf dem Server beliebige Programme (siehe Kasten "CGI und PHP"). Bei PHP läuft nur ein Interpreter, der einen vorgegebenen Befehlssatz versteht. Er kontrolliert, welche Befehle das Skript ausführt, in welchem Kontext sie laufen und welche Aktionen erlaubt sind.
CGI und PHP
|
|
CGI-Skripte werden meist von Interpretern wie Perl oder Python ausgeführt und damit oft mit PHP verwechselt, dennoch handelt es sich um etwas grundlegend anderes: CGIs laufen als normale Programme im Userspace des Servers und haben damit - anders als PHP - alle Möglichkeiten eines User-Prozesses.
CGI-Skripte haben zu viele Rechte
Eingeschlossen darin sind Zugriffe auf Hardware und das Dateisystem (so weit die Rechte reichen), Einblicke in Systemvariablen, Prozesslisten, Userlisten und vieles mehr. Wer es seinen Usern also erlaubt, beliebige CGIs zu starten, muss ihnen entsprechend vertrauen (Abbildung 1).
Abbildung 1: CGI-Programme haben freie Hand auf dem Server, sie arbeiten als eigener Prozess. PHP-Skripte laufen hingegen gekapselt und abgesichert im PHP-Interpreter als Teil des Apache-Daemon.
Gefahr durch lokale Angreifer
Linux-Umgebungen sind auf einen sicheren Multiuser-Betrieb ausgelegt. Doch ist bei Sicherheitsfehlern zwischen lokalen und aus der Ferne nutzbaren Lücken zu unterscheiden. Ein lokaler Angreifer gefährdet ein System weitaus schneller als ein Außenseiter - ein CGI-Skript hat aber das Risikopotenzial eines lokalen Saboteurs. Zudem sind Webserver schwerer über Dateirechte abzusichern als normale Arbeitsrechner.
Die übers Web veröffentlichten Files brauchen zumindest Leserechte für die User-ID des Webservers und für den Benutzer, der die Seiten erstellt. Schon dieser Lesezugriff kann sich in Multiuser-Umgebungen problematisch auswirken, denn niemand möchte, dass fremde User die eigenen Datenbank-Kennwörter lesen. Sind Schreibzugriffe auf den Webspace nötig, etwa für Gästebücher oder Bildergalerien, empfehlen manche Anleitungen gar ein unsinniges »chmod 777«. Entsprechend offen sind viele Verzeichnisse.
Schutz der Benutzer voreinander
Ein Schutz der Daten zwischen den Anwendern untereinander ist mit üblichen Einstellungen bei CGIs kaum möglich. Mit zusätzlichem Aufwand könnte der Admin immerhin dafür sorgen, dass ein kluger FTP-Server jeden »chmod 777« untersagt. Auch der CGI-Wrapper von Apache bringt etwas mehr Sicherheit: Er sorgt dafür, dass die CGI-Programme unter der User-ID ihres Besitzers laufen und nicht mit den Rechten des Apache-Daemon.
Bei PHP hat der Admin bedeutend mehr Einfluss. Mit der im Artikel vorgestellten Option »open_basedir« prüft der PHP-Interpreter zusätzlich zu den normalen Dateirechten, auf welche Verzeichnisse ein Skript zugreifen darf.
|
Lückenprüfer
Als Testprogramm eignet sich ein Dateimanager (Listing 1). Hochgeladen auf einen ungesicherten Webspace bietet er bequemen Zugriff auf die komplette Festplatte bis zur obersten Ebene - so weit es die Rechte des PHP-Interpreters gestatten. Da der Interpreter im Kontext des Apache-Webservers läuft, sind Einblicke in »/etc/passwd« ebenso möglich wie der Zugriff auf Webverzeichnisse anderer Nutzer inklusive der darin liegenden ».htpasswd«-Dateien.
Listing 1: Filebrowser
|
01 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
02 <html><head><title>
03 Filebrowser v1.0 -- Peer Heinlein
04 </title></head>
05 <body>
06 <?
07 if(isset($_GET['path'])) {
08 // Variable einlesen (register_globals=off)
09 $path = $_GET['path'];
10
11 // Wenn Datei, dann Inhalt zeigen
12 if(is_file($path)) {
13 $file = fopen($path,"r");
14 print "<pre>";
15 while (!feof($file)) {
16 $zeile = fgets($file, 4096);
17 print htmlentities($zeile,ENT_QUOTES);
18 }
19 print "</pre></body></html>";
20 fclose($file);
21 exit;
22 }
23
24 // Wenn Pfad, dann Verzeichnislisting
25 print "<pre><b>Inhalt von $path</b>
";
26 $dir = opendir($path);
27 while($file = readdir($dir)) {
28 $filepath = $path . "/" . $file;
29 if(is_dir($filepath))
30 print "[DIR ] ";
31 elseif(is_file($filepath))
32 print "[FILE] ";
33 elseif(is_link($filepath))
34 print "[LINK] ";
35 else
36 print " ";
37
38 if($file == ".")
39 print "<a href="" . $_SERVER['PHP_SELF']
40 . "?path=$path">.</a>
";
41 elseif($file == "..") {
42 if(substr($path,0,strrpos($path,"/")) == "") {
43 print "<a href=""
44 . $_SERVER['PHP_SELF']
45 . "?path=/">..</a>
";
46 } else {
47 print "<a href=""
48 . $_SERVER['PHP_SELF']
49 . "?path="
50 . substr($path,0,strrpos($path,"/"))
51 . "">..</a>
";
52 }
53 }
54 else {
55 print "<a href=""
56 . $_SERVER['PHP_SELF']
57 . "?path="
58 . (($path == "/") ? "" : $path)
59 . "/" . rawurlencode($file)
60 . "">$file</a>";
61
62 // Dateieigenschaften auflisten
63 $mode = (is_writeable($filepath)) ?
64 ", mode: writeable " : "";
65 $stat = stat($filepath);
66 $uid = $stat[4];
67 $gid = $stat[5];
68 $size = $stat[7];
69 print " [ uid: $uid, gid: $gid, size: $size $mode]";
70 }
71 }
72 closedir($dir);
73 print "</pre>";
74 } else {
75 ?>
76 <form action="" method="get">
77 Verzeichnis?
78 <input type="text" name="path">
79
80 <input type="submit" value="anzeigen">
81 </form>
82 <?
83 }
84 ?>
85 </body>
86 </html>
|
Interessante Verzeichnisse
Auch das »/tmp«-Verzeichnis ist interessant, oft finden sich hier vergessene Dateien des Administrators mit Dateilisten, Nutzerverzeichnissen, einem Datenbankdump und anderen internen Informationen. Ein mögliches Ergebnis zeigt Abbildung 2.
Abbildung 2: Ein PHP-Skript hat auf ungesicherten Servern ziemlich freien Zugang zum System. Der einfache PHP-Dateimanager aus Listing 1 genügt, um sich im Rechner umzusehen.
Die PHP-Dokumentation[1] enthält neben Beschreibungen zu allen Parametern und Funktionen auch eigene Kapitel zu Sicherheitsfragen[2]. Von Marc Heuse stammt einen älteres, aber sehr lesenswertes Howto zur Installation eines sicheren Webservers[3], das einen guten Überblick vermittelt. Wer sich erstmals mit der Frage beschäftigt, wie PHP abzusichern ist, stolpert in »php.ini« schnell über den viel versprechend klingenden Parameter »safe_mode«.
Mit dieser Einstellung nimmt PHP einige zusätzliche Sicherheitsprüfungen vor. Unter anderem prüft der Interpreter beim Zugriff auf Dateien, ob die User-ID der Datei gleich der User-ID des aufrufenden Skripts ist. So verhindert PHP, dass ein Nutzer fremde Dateien liest, auch wenn ihm das Dateisystem Leserecht gibt.
« Zurück
1
2
3
4
5
6
7
...
9
Weiter »