TU Chemmnitz

Universitätsrechenzentrum

TU Chemnitz > URZ > Zeitung > Ausgabe 4/2004

Sicheres Programmieren mit PHP (Teil 3)

In den ersten beiden Ausgaben der "Mitteilungen des URZ" 2004 haben wir bereits Hinweise zur sicherheitsbewussten PHP-Programmierung gegeben. In diesem Artikel soll nun die Upload-Funktion von PHP beleuchtet werden.

An dieser Stelle möchten wir die kleine Artikelserie (nachzulesen unter http://www.tu-chemnitz.de/urz/www/php/secure.html) fortsetzen. Denn "Sicheres Programmieren mit PHP" ist weiterhin ein brisantes Thema. So gab es am 5.10.2004 eine Warnung vom DFN-CERT (http://cert.uni-stuttgart.de/archive/win-sec-ssc/2004/10/msg00015.html), in der eine massive Ausnutzung von Lücken in unsicher programmierten PHP-Skripten beschrieben wird. Und es waren auch WWW-Seiten im Campusnetz betroffen!

Auch bei diesem Angriff war das "blinde Vertrauen" in Daten von externer Quelle (hier in der HTTP-Anforderung) die Schwachstelle. Da bekanntlich Wiederholung die Mutter der Weisheit ist, stelle ich den Merksatz aus dem letzten Artikel nochmals voran:

Tipp! Vertrauen Sie keinen Werten, die über Browsereingaben, den URL oder Cookies in das PHP-Skript gelangen. Alle externen Parameter, selbst wenn sie aus versteckten Feldern oder Auswahlmenüs kommen, müssen einer Plausibilitätsprüfung unterworfen werden, bevor sie im Programm verwendet werden.

Diese Tests und Überprüfungen sind mitunter aufwändig - Sicherheit hat ihren Preis! Im Folgenden wollen wir uns eine weitere, aus Sicht der Sicherheit kritische "Einfallsmöglichkeit" für externe Daten näher ansehen.

Datei-Upload

PHP bietet Funktionen, mit denen sich ziemlich einfach ein Datei-Upload (Hochladen von Dateien) vom WWW-Browser auf den WWW-Server realisieren lässt. Eine Erklärung des nötigen HTML-Formulars und der PHP-Anweisungen finden Sie in der PHP-Dokumentation (http://www.tu-chemnitz.de/docs/php/features.file-upload.html).

Hier folgt nur eine kritischer Ausschnitt - ein rudimentäres HTML-Formular und das Kopieren einer hochgeladenen Datei aus dem temporärem Bereich in das vorgesehene Verzeichnis.

<form enctype="multipart/form-data" action="..." method="post">
  <input name="datei" type="file" />
  <input type="submit" value="Datei hochladen" />
</form>

<?php
$upload_verzeichnis = '/afs/tu-chemnitz.de/.../upload';

# Name für Upload-Element im Formular heißt 'datei'
if (isset($_FILES['datei']['name'])) {
    $dateiname = $_FILES['datei']['name'];
# Dateinamen prüfen: Nur Buchstaben, Punkt, Unter- und Bindestrich erlaubt:
  if (ereg('^[a-zA-Z0-9._-]*$', $dateiname)) {

  # WICHTIG: Prüfen, ob Datei schon existiert, um Überschreiben zu verhindern!
    if (file_exists("$upload_verzeichnis/$dateiname")) {
      echo "Datei " . htmlspecialchars($dateiname) . " existiert schon!";
    } else {
      if (move_uploaded_file($_FILES['datei']['tmp_name'],
                             "$upload_verzeichnis/$dateiname")) {
        echo "Ok";
      } else {
        echo "Fehler: " . $_FILES['userfile']['error'];
      }
    }
  } else {
    echo "Fehler: Ungültiger Dateiname " . htmlspecialchars($dateiname);
  }
}
?>

Trotz dieser Vorsichtsmaßnahmen bietet ein solches Verfahren natürlich ein "Einfallstor", über das auch unliebsame Dateien, etwa Schadprogramme, in unser System gelangen können. Deshalb sind gründliche Überlegungen und sorgfältige Progammierung hinsichtlich der Sicherheit erforderlich.

Bieten Sie eine solche Upload-Möglichkeit möglichst nicht öffentlich für jedermann an, sondern erlauben Sie das nur über eine Authentisierung für Berechtigte. Hinweise zum Zugriffsschutz über Anweisungen in der Datei .htaccess finden Sie unter Apache: Zugriffskontrolle (http://www.tu-chemnitz.de/urz/www/access.html).

Es ist besonders auf das Verzeichnis zu achten, in das die hochgeladene Datei geschrieben werden soll. Da dieses Verzeichnis für den betreffenden WWW-Server schreibbar sein muss, ist hier besondere Sorgfalt nötig:

Außerdem müssen Sie sicherstellen, dass Dateien dieses Upload-Verzeichnisses nicht direkt via WWW-Browser lesbar sind:

    # Direkten Zugriff auf alle Dateien unterbinden
      order deny,allow
      deny from all
      php_flag engine off
      RemoveHandler .cgi

Sie sehen also auch hier, dass Sicherheit ihren Preis hat - die Konfiguration ist ziemlich komplex. Deshalb beraten wir Sie gern bei der Planung Ihrer WWW-Projekte. Ein nachträgliches Ändern bestehender Projekte zur Erhöhung der Sicherheit ist dagegen meist sehr schwierig und aufwändig.

Wenn Sie eine Upload-Fähigkeit für Ihr HOME-Verzeichnis brauchen (oder für andere Verzeichnisse, für die Sie eine Schreibberechtigung haben), können Sie auf eine fertige Lösung zurückgreifen: Benutzen Sie den Web-basierten Datei-Manager WFM des Login-Servers: https://login.tu-chemnitz.de/wfm/


Frank Richter, Oktober 2004