Sven Rautenberg: Ausführen von PHP verhindern...

Beitrag lesen

Moin!

Muss nicht der Server diese Datei mit irgendeinem MIME-Typ verwalten?

Nein. Unix beispielsweise kennt erst einmal nur Dateien. "Alles ist Datei" - selbst Festplattenpartitionen, serielle Schnittstellen oder TCP-Sockets.

Mime-Typen sind ein über dieses Grundgerüst drübergelegter Layer, der jeder Datei einen Mime-Typ, und dann jedem Mime-Typ eine typische Verarbeitungsform zuordnet. Wobei die Zuordnung eines Mime-Typs sehr häufig auf der Dateiendung basiert, dies aber nicht so sein muß - man kann den Mime-Typ auch unabhängig in Dateimetadaten speichern, dazu muß das Dateisystem sowas aber unterstützen.

In der realen Welt werden Mime-Typen tatsächlich nur für den Datenaustausch zwischen Systemen verwendet, die internen Betriebssystemvorgänge interessieren sich dafür herzlich wenig. Es wird beispielsweise nicht verhindert, dass ich ein JPG mit einem Texteditor öffne. Wobei: Das Verhindern kann ja auch gegen die Userinteressen laufen, manchmal will man genau das ja tun.

Ich überlege, inwieweit ich eine hochgeladene Datei darauf prüfen kann, ob sie "erlaubt" sein soll, oder nicht...

Diese Prüfung ist schwierig, und erfordert zuallererst mal eine Festlegung, welche Dateien denn als "erlaubt" gelten sollen.

Die Prüfung wird sich dann daran machen, das erlaubte Dateiformat in der Datei zu finden, und bei Abweichungen die Erlaubnis zu verweigern. Was darauf hinausläuft, dass man alle erlaubten Dateiformate kennen muß.

PHP hat mit getimagesize() eine Funktion, die schon sehr viele Bilddateiformate kennt und daraus die Größeninformation gewinnen kann. Falsches Format = keine Bildinformation = vermutlich kein Bild = keine Erlaubnis.

Bei Word-Dateien wird's schon schwieriger: Kennst du alle möglichen Dateiformate von Word?

Also wird man normalerweise einfach "alle Binärdateien" zulassen und durch Programmierung versuchen zu verhindern, dass man auf dem Server mit den Dateien außer Hoch- und Runterladen was anderes machen kann - "als Programm ausführen" beispielsweise wäre extrem böse.

Dasselbe gilt für "Textdateien", die im Prinzip nur eine unbedeutende Sonderform von "Binärdatei" sind. Zu verhindern, dass jemand eine Textdatei mit PHP-Code hochlädt und den Code dann (anstatt eines Downloads) ausführt, ist sehr wichtig.

Wäre denn mit is_executable() oder filetype() eine verlässliche Prüfung zu realisieren?

is_executable() liefert dir, ob die Datei im Unix-Dateisystem das X-Flag gesetzt hat. Ob Unix die Datei ausführen kann, ist damit nicht gesagt - auch fehlerhafte Programme haben das Flag gesetzt, und ebenso alle Dateien, die einem globalen CHMOD 777 zum Opfer fallen, weil sonst FTP oder Dateizugriff nicht richtig geht.

filetype() liefert für alle regulären Dateien das Ergebnis "file". Unterscheidet also auch nach nichts relevantem.

Hat Tom aber schon beides erwähnt.

Im Prinzip kann man sagen: Ob eine Datei erlaubt sein soll, oder nicht, muß man durch Validierung der Eingabe feststellen, genau so, wie man es bei Formularfeldern auch tun muß. Das Problem ist dabei nur, dass Formularfelder wesentlich einfachere Formate haben, Dateien hingegen ziemlich komplex sein können.

Und wenn man die vom User übermittelten Daten nicht komplett verifizieren kann, dann muß man eben dafür sorgen, dass sie keinen Schaden anrichten können, eingebauter Code also nie zur Ausführung gelangt. Das gilt für Dateien (hier: hochgeladene PHP-Skripte) genauso, wie für Formularfelder (Stichwort: SQL-Injection - das ist auch ausführbarer Code, nur kürzer und in einem Formularfeld).

Die Prinzipien sind, egal ob Datei oder Formularfeld, identisch.

- Sven Rautenberg

--
My sssignature, my preciousssss!