Hauptmenü

Untermenü

Sicher programmieren - Dateiuploads Teil 2

1. Die Abschnitte

2. Dateiprüfung

Im vorherigen Abschnitt habt ihr sicher schon gelernt, dass man Daten nicht trauen soll, die man per Upload auf einen Server hochladen kann. Das holen wir jetzt nach, aber mal wieder sehr schlampig. Ruft dazu wieder mal den Unterordner upload im Browser auf. Diesmal laden wir allerdings die Datei hack.jpg im Ordner data hoch.

3. Die Verarbeitung

Diesmal beschreiten wir in der index.php einen anderen Weg. Sobald ein JPEG-Bild hochgeladen wird, speichern wir es in unserer Datenbank ab. Dann holen wir uns die ID des Eintrags und leiten auf die list_jpg.php weiter.


...
else if ('.jpg' == substr ($name, - 4))
{
  $bindata file_get_contents ($file);
  $query   'INSERT INTO bild (daten, name) 
              VALUES (\''.$bindata.'\',\''.$name.'\')';
  $result  mysql_query ($query);
  if ($result)
  {
    $id mysql_insert_id();  
    header ('location: list_jpg.php?id='.$id);
  }
}        

4. Die Angriffsmöglichkeit

... hängt nun von eurem Browser ab. Nehmt zuerst mal den Firefox, Safari und Opera. Beim ersten erscheint der Link der Seite und beim zweitem eine Art von Bildhinweis. Und nun kommt mal wieder unser Sorgenkind aus Redmond. Denn der interpretiert das "Bild" ein wenig anders. Auch wenn wir in der list_jpg.php den korrekten Header senden. Im IE 8 wurde diese Lücke mittlerweile geschlossen.


...
header('Content-Type: image/jpeg');
echo $pic['daten'];

Und, schon gemerkt, was passiert? Es erscheint auf einmal eine Alert-Box!

5. Der Hack

Öffnet die hack.jpg mal in einem Texteditor. Und dann seht ihr folgenden Code:


<script type="text/javascript">alert ("Jau");</script>


Wir haben kein Bild hochgeladen, sondern eine Textdatei mit JavaScript-Code! Den interpretiert sowohl der Internet Explorer 6 als auch 7. Und das ist noch längst nicht alles. Es gibt doch tatsächlich noch mehr Möglichkeiten, um diesem Sicherheitsmonster Code unterzujubeln.

Gegenmaßnahme

Hier sollte man zumindest mittels der PHP-Funktion getimagesize prüfen, ob es sich überhaupt um ein Bild handelt. Denn in obigem Fall bekommt ihr keine Werte zurückgeliefert.

zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt