Anzeige
Tutorialbeschreibung

Sicheres Datei Upload

Sicheres Datei Upload

 

In diesem Workshop will ich euch zeigen, wie man ein sicheres Upload-System erstellt. Die Betonung liegt dabei auf SICHER. Ein einfaches Upload-Script kann ich in 2 Minuten erstellen. Aber es darf den Server und die Daten nicht schaden können. Wie das geht seht ihr hier.


Es sei noch kurz erwähnt das ich hier nicht jeden Kleinkram beschreibe. Ich setzte ein gewisses Grund-Know-How einfach vor raus. Da dieses Tutorial sonst nie enden würde.

Am Anfang steht natürlich das HTML-Gerüst

<form method="POST" action="<?php echo $PHPSELF; ?>" enctype="multipart/form-data">
<p>Datei upload:<br>
<input type="file" name="datei" size="30"><br>
<input type="submit" name="Upload" value="Upload" />
</form>

Wichtig hierbei ist der Zusatz >>enctype="multipart/form-data"<< Dieser sorgt dafür das der Browser weiß das Daten übertragen werden können.

Bevor wir überhaupt anfangen können muss noch 1 gesagt werden: Ich übernehme keine Verantwortung über dieses Script. Es ist zwar nach bestem Wissen und Gewissen erstellt worden, aber ich bin nicht für Folgeschäden haftbar zu machen. Das Nutzten dieses Scripts erfolgt auf eigener Gefahr. Außerdem muss das Script Schreibrechte in dem Ordner haben um die Daten speichern zu können CHMOD 777


Die wichtigste Variable die wir heute nutzen werden ist Variable $_FILES. Hierzu füge ich kurz eine Auszug aus dem PHP-Manuel ein:

$_FILES['userfile']['name']
Der ursprüngliche Dateiname auf der Client Maschine.
$_FILES['userfile']['type']
Der Mime-Type der Datei, falls der Browser diese Information zur Verfügung gestellt hat. Ein Beispiel wäre "image/gif".
$_FILES['userfile']['size']
Die Größe der hochgeladenen Datei in Bytes.
$_FILES['userfile']['tmp_name']
Der temporäre Dateiname, unter dem die hochgeladene Datei auf dem Server gespeichert wurde.
$_FILES['userfile']['error']
Der Fehlercode im Zusammenhang mit dem hochladen der Datei. ['error'] wurde in PHP 4.2.0 eingeführt.

Kommen wir nun zum eigentlichen Quellcode. Ich werde ihn immer weiter ergänzen.

Als erstes müssen wir überprüfen ob eine Datei via Browser übertragen wurde. Dazu prüfen wir die Variable $_FILES mit dem Befehl isset(); Diese gibt im Erfolgsfall true aus

<?php
if (isset($_FILES['datei']))
{

}
?>

Nachdem bestätigt wurde das eine Datei hoch geladen wurde, sollte man überprüfen ob die Dateiendung erlaubt ist. Dazu nutzt man am besten die MIME-Typ's (http://de.selfhtml.org/diverses/mimetypen.htm). Die MIME-Werte lassen sich sehr einfach ermitteln, dazu braucht man nur die Variable: $_FILES['datei']['type'];
Das bauen wir nun in als switch ein (Hier sind jetzt nur Bilder erlaubt).

<?php
if (isset($_FILES['datei']))
{
switch($_FILES['datei']['type'])
{
case "image/gif" : $error = false;
$endung = "gif";
break;
case "image/jpeg" : $error = false;
$endung = "jpg";
break;
case "image/png" : $error = false;
$endung = "png";
break;
default : $error = true;
break;
}

}
?>

Wir sollten noch prüfen ob vielleicht nicht schon eine Datei mit dem selben Namen gibt. Dafür nutzen wir die Funktion file_exists(); Sollte der Wert 1 sein so setzten wir $error ebenfalls auf 1 damit die Datei nicht hoch geladen wird und so vorhandene Daten überschreibt:


<?php
if (isset($_FILES['datei']))
{
switch($_FILES['datei']['type'])
{
case "image/gif" : $error = false;
break;
case "image/jpeg" : $error = false;
break;
case "image/png" : $error = false;
break;
default : $error = true;
break;
}

if(file_exists(htmlspecialchars(basename($_FILES['datei']['name'] ))))
$error = true;
}
?>

Sollte $error = true also 1 sein so kann man später eine entsprechende Fehlermeldung ausgeben. Ist der $error = 0 geht es weiter.

Jetzt kommt noch ein wichtiger Sicherheitspunkt: Wir verwenden für den Upload NICHT copy() sondern move_uploaded_file(). Wieso sagt uns das Handbuch das ich hier kurz Zitieren möchte:
"Diese Funktion prüft, ob die mit filename bezeichnete Datei eine gültige Upload-Datei ist (d.h., dass sie mittels PHP's HTTP POST Upload-Mechanismus upgeloaded wurde). Ist die Datei gültig, wird sie zum in destination bezeichneten Dateinamen verschoben.
Wenn filename keine gültige Datei ist, wird keine Aktion ausgeführt, und move_uploaded_file() gibt FALSE zurück.
Wenn filename eine gültige Datei ist, jedoch aus irgendeinem Grund nicht verschoben werden kann, wird keine Aktion ausgeführt, und move_uploaded_file() gibt FALSE zurück. Zusätzlich wird eine Warnung ausgegeben."

Sie ist damit sicherer als copy();. Wir müssen hier 2 Werte übergeben.
1.Den Dateinamen im TMP Verzeichnis
2.Den Dateinamen auf dem Server.
Der erste Wert lässt sich mit >>$_FILES['datei']['tmp_name']<< füllen. Beim 2 Wert ist wieder Sicherheit angesagt:
Um dafür zu sorgen das der Name keinen schadhaften Code hat wandeln wir jeden Code mit htmlspecialchars() um. Des weiteren gibt es Browser die übergeben den gesamten Pfad mit. Das wollen wir natrülich nicht, deshalb reinigen wir den Dateiname mit basename(); Der gibt nur noch den Namen aus. Zusammen gesetzt sieht es dann so aus: htmlspecialchars(basename($_FILES['datei']['name'] ))
Damit sieht unser jetziger Quelltext so aus:

<?php
if (isset($_FILES['datei']))
{
switch($_FILES['datei']['type'])
{
case "image/gif" : $error = false;
$endung = "gif";
break;
case "image/jpeg" : $error = false;
$endung = "jpg";
break;
case "image/png" : $error = false;
$endung = "png";
break;
default : $error = true;
break;
}

if(file_exists(htmlspecialchars(basename($_FILES['datei']['name'] ))))
$error = true;

if(!$error)
{
if(move_uploaded_file($_FILES['datei']['tmp_name'], htmlspecialchars(basename($_FILES['datei']['name'] ))))
echo "<br /><font color=green><b>Die Datei (".htmlspecialchars(basename($_FILES['datei']['name'] )).") wurde erfolgreich hochgeladen</b></font><br />";
else
echo "<br /><font color=red><b>Es gab einen Fehler beim Hochladen der Datei: (".htmlspecialchars(basename($_FILES['datei']['name'] )).")</b></font><br />";
}
else
echo "<br /><font color=red><b>Die Datei (".htmlspecialchars(basename($_FILES['datei']['name'] )).") entspricht nicht den Normen bzw. ist schon vorhanden!<br /> Erlaubt sind nur: gif, jpg, jpeg, jpe oder png</font></b><br />"
;

}
?>

So jetzt fehlt nur noch, das wir HTML und PHP zusammen setzten. Das Fertige Ergebnis sieht dan so aus:

<html>

<head>
<title>UPLOAD</title>
</head>

<body>

<?php
if (isset($_FILES['datei']))
{
switch($_FILES['datei']['type'])
{
case "image/gif" : $error = false;
break;
case "image/jpeg" : $error = false;
break;
case "image/png" : $error = false;
break;
default : $error = true;
break;
}

if(file_exists(htmlspecialchars(basename($_FILES['datei']['name'] ))))
$error = true;


if(!$error)
{
if(move_uploaded_file($_FILES['datei']['tmp_name'], htmlspecialchars(basename($_FILES['datei']['name'] ))))
echo "<br /><font color=green><b>Die Datei (".htmlspecialchars(basename($_FILES['datei']['name'] )).") wurde erfolgreich hochgeladen</b></font><br />";
else
echo "<br /><font color=red><b>Es gab einen Fehler beim Hochladen der Datei: (".htmlspecialchars(basename($_FILES['datei']['name'] )).")</b></font><br />";
}
else
echo "<br /><font color=red><b>Die Datei (".htmlspecialchars(basename($_FILES['datei']['name'] )).") entspricht nicht den Normen bzw. ist schon vorhanden!<br /> Erlaubt sind nur: gif, jpg, jpeg, jpe oder png</font></b><br />";
}
?>
Hier haben Sie die Möglichkeit ein Bild hochzuladen. Es sind nur Grafiken erlaubt die das Format: gif, jpg, jpeg, jpe oder png haben!
<form method="POST" action="<?php echo $PHPSELF; ?>" enctype="multipart/form-data">
<p>Datei upload:<br>
<input type="file" name="datei" size="30"><br>
<input type="submit" name="Upload" value="Upload" />
</form>

</body>

</html>

So und jetzt viel Spaß!


DVD-Werbung
Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von I3uLL3t
  • 21.10.2011 - 00:12

Sehr gelungen vielen vielen dank...sowas suche ich schon lange :)

Portrait von Susan99
  • 02.03.2010 - 12:32

Gutes Tutorial, schön beschrieben. Vielen Dank!
LG Susan

Portrait von Cokxxie
  • 25.02.2010 - 11:45

Ein sehr schönes Tutorial. Danke. Es ist jedoch noch ausbaufähig ;D

Portrait von geminixxl
  • 19.01.2010 - 21:54

Schönes Tutorial. Danke dafür;)

Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 27.09.2009 - 11:25

Gutes Tutorial, genau das richtige für mich.

Portrait von Nemesis_Steelfeather
  • 21.06.2009 - 11:05

Hat mir sehr weitergeholfen, auch wenns immer noch nicht ganz das ist was ich suche

Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 14.10.2008 - 12:47

ne frage?

hast du nen fertigen
.html skript
mit dem ich nur .rar oder .zip
dateien hochladen kann?

(bin an einer homepage dran)

mfg
septec

Portrait von Sling
  • 17.03.2008 - 18:29

Hallo sehr gutes Script funktioniert auch super nur das mit dem uploaden in ein bestimmtes verzeichnis scheint nicht zu gehen kannst du da noch was erklären bzw sagen wo ich das verzeichniss eintragen muss?

Portrait von Schrottie
  • 21.03.2008 - 12:25

Hi,<br>
du must folgende Zeile deinen Wünschen anpassen:<br>
if(move_uploaded_file($_FILES['datei']['tmp_name'], htmlspecialchars(basename($_FILES['datei']['name'] ))))<br>
<br>
und zwar: <br>
if(move_uploaded_file($_FILES['datei']['tmp_name'],<b>"ORDNERNAME/".</b>htmlspecialchars(basename($_FILES['datei']['name'] ))))

Portrait von Duffman15
  • 08.01.2008 - 18:15

Geiles Tut, danke vielmals :)
Aber kann ich da jetzt einfach mit

imagesx($_FILES['datei']['name']);

Die Breite ermitteln? :S

Portrait von Schrottie
  • 10.06.2007 - 22:06

Ändere:<br>
if(move_uploaded_file($_FILES['datei']['tmp_name'],<br>
<br>
in<br>
<br>
if(<b>"bilder/".</b>move_uploaded_file($_FILES['datei']['tmp_name'],<br>
<br>
Schrottie

Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 10.06.2007 - 21:13

kann es einer bitte umprggen das es in den ordner bilder geht?

Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 10.06.2007 - 12:17

sehr gutes tut kann ich gebrauchen, nur wohin gehen die datein? In welchen ordner? Freue mich auf antwort^^

Portrait von Schrottie
  • 10.06.2007 - 12:24

Die Datei wird in den selben Ordner gespeichert, wo die Datei liegt

Portrait von Newbie123
  • 23.05.2007 - 13:56

Sehr schön! Aber oben schreibst du $_FILES['userfile']['size'] warum verwendest du diesen wert dann nicht ? Was ist daran sicherer als bei anderen? Trozdem schönes Script :)
Eine Frage kann man anstatt htmlspecialchars auch strip_tags verwenden?

PS: 5 Sternchen

Portrait von Schrottie
  • 13.12.2006 - 15:18

Ja funktioniert. Da Globale Variablen benutzt werden.

Portrait von pcgamer2005
Portrait von erti
  • 13.12.2006 - 14:40

Hmmm, also bei mir wär dieses Script mindester Standard, aber kann natürlich sein, dass fertige Scripte im Netz net mal das haben..
Hab schon lang kein fertiges Script mehr verwendet...

Portrait von Stefan
  • 11.12.2006 - 20:34

Ich finde es auch gut. Geht das Script eigentlich auch wenn die globalen Variablen aus gestellt sind und SafeMode = On?

Portrait von erti
  • 13.12.2006 - 14:38

Soweit ich das sehe, müsste auch mit Safemode=on und Globals=off funktionieren!<br>
Kann aber sein, dass ich irgendwo was übersehen hab, aber das glaub ich eher nicht!

x
×
×