PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PHP Upload nur jpg und gif erlauben !?!


Natheedo
15.06.2006, 18:28:52
Hallo,

ich hab hier ein kleines Privates Upload Skript das ich für paar Sachen auf meinem Webserver nutze, das auch soweit für meine Ansprüche gerecht ist - Nur sind mir in den letzten Tagen vermehrt Dateien aufgefallen die ich nicht hochgeladen habe - Besonders eine "cookie_overflow.php" ...

Das bereitet mir jetzt allmählich Kopfschmerzen, das ich an das Sicherheitsrisiko nicht eher gedacht hab.

Darum ist die Frage, wie ich mein Upoadscript so ergänze (hab vom php selber schreiben leider keine Ahnung) das man lediglich .jpg und .gif. Dateien damit hochladen kann?

Hier das Script :


<?php

## pfad von dieser datei aus wo das hochgeladen werden soll
$dir = "../pics/vorlagenpics/bildupload";
$url = "http://www.DOMAIN.de";

if($_POST['uppen']){
if(!empty($_FILES['file']['name'])){


// Tmp_name
$tempname = $_FILES['file']['tmp_name'];
$tempname2 = $_FILES['file2']['tmp_name'];
$tempname3 = $_FILES['file3']['tmp_name'];

// Namen der dateien
$name = str_replace(" ","_",$_FILES['file']['name']);
$name2 = str_replace(" ","_",$_FILES['file2']['name']);
$name3 = str_replace(" ","_",$_FILES['file3']['name']);

// typen der dateien
$type = $_FILES['file']['type'];
$type2 = $_FILES['file2']['type'];
$type3 = $_FILES['file3']['type'];

// groeße der dateien
$size = $_FILES['file']['size'];
$size2 = $_FILES['file2']['size'];
$size3 = $_FILES['file3']['size'];

// Dateien kopieren
@copy("$tempname", "$dir/$name");
@copy("$tempname2", "$dir/$name2");
@copy("$tempname3", "$dir/$name3");

// Ueberpruefung
$f1 = file_exists($dir."/".$name);
$f2 = file_exists($dir."/".$name2);
$f3 = file_exists($dir."/".$name3);

if($f1) {
$output = $url."/pics/vorlagenpics/bildupload/".$name;
$ausgabe = htmlentities(stripslashes($output));
}else echo "Upload von Datei 1 fehlgeschlagen!<br>";

if($f2){
$output2 = $url."/pics/vorlagenpics/bildupload/".$name2;
$ausgabe2 = htmlentities(stripslashes($output2));
}else echo "Upload von Datei 2 fehlgeschlagen!<br>";

if($f3){
$output3 = $url."/pics/vorlagenpics/bildupload/".$name3;
$ausgabe3 = htmlentities(stripslashes($output3));
}else echo "Upload von Datei 3 fehlgeschlagen!<br>";

}else echo "Datei muss gewählt werden<br>";



}

#echo "<form enctype=\"multipart/form-data\" action=\"?do=up\" method=\"post\">";
if(isset($output) || isset($output2) || isset($output3)){
if(!empty($name))
echo "<input type=\"text\" size=\"80\" name=\"file\" value=\"$ausgabe\">&nbsp;<img src=\"pics/haken.gif\" border=\"0\" alt=\"\"><br>";
if(!empty($name2))
echo "<input type=\"text\" size=\"80\" name=\"file2\" value=\"$ausgabe2\">&nbsp;<img src=\"pics/haken.gif\" border=\"0\" alt=\"\"><br>";
if(!empty($name3))
echo "<input type=\"text\" size=\"80\" name=\"file3\" value=\"$ausgabe3\">&nbsp;<img src=\"pics/haken.gif\" border=\"0\" alt=\"\"><br>";
}else{
echo "<input type=\"file\" size=\"80\" name=\"file\"><br>";
echo "<input type=\"file\" size=\"80\" name=\"file2\"><br>";
echo "<input type=\"file\" size=\"80\" name=\"file3\"><br>";
}
echo "<br><input type=\"submit\" name = \"uppen\" value=\"Hochladen\"> <span class=\"rot\"> &lt;&mdash; Bild auswählen dann auf hochladen klicken!</span>";

?>


Wäre vielleicht bitte jemand so nett und könnte mir da auf die Sprünge helfen?

Ich hab schon folgendes versucht :


// Tmp_name
$tempname = $_FILES['file']['tmp_name'];
if(strtolower(substr($tempname, -4)) == ".gif" || strtolower(substr($tempname, -4)) == ".jpg")
{
echo "Dateiendung erlaubt...";
} else {
echo "Dateiendung nicht erlaubt...";
}
$tempname2 = $_FILES['file2']['tmp_name'];
if(strtolower(substr($tempname2, -4)) == ".gif" || strtolower(substr($tempname2, -4)) == ".jpg")
{
echo "Dateiendung erlaubt...";
} else {
echo "Dateiendung nicht erlaubt...";
}
$tempname3 = $_FILES['file3']['tmp_name'];
if(strtolower(substr($tempname3, -4)) == ".gif" || strtolower(substr($tempname3, -4)) == ".jpg")
{
echo "Dateiendung erlaubt...";
} else {
echo "Dateiendung nicht erlaubt...";
}


Allerdings bringt er mir jetzt 3 mal "Dateiendung nicht erlaubt..." und ladet auch nix hoch !?!

Hm ... Irgendwas schein ich verkehrt gemacht zu haben!

Danke !

Natheedo

Morrandir
15.06.2006, 20:27:36
Also mal zwei Ansätze... mal ohne dein ganzes Script durchzusehen... schein kompliziert zu sein... nur mal rein auf deinen Frage antwortend...

Erster Ansatz: dir fällt auf dass da Dateien rumschwirren, die nicht von dir sind... ganz schlecht... so sachen wie cookie_overflow und so weiter können Sachen sein, die richtig schaden anrichten können.... schon mal dran gedacht n Passwort zu verwenden um Dinge hochladen zu dürfen... wenn dir jemand schaden will, dann braucht er blos ne rekursive funktion schreiben in der n paar mal das Stichwort unlink() fällt und schon is Essig mit Homepage...

Zweiter Ansatz: Ich bin mir nicht sicher, ob $_FILES['file']['type'] wirklich auch den richtigen Mimetype zurück gibt, wenn die PHP getarnt ist... (dass müsstest du aber selber mal testen)... ich meine, wenn ich z.B. eine PHP-Datei erstelle die so in etwa lautet:

<?php
header ("Content-type: image/png");

/* Und ab hier kann ich wieder machen was ich will */
?>

da ist jetzt dir Frage, was der Browser feststellt, (wenn er überhaupt den Mimetype mitliefert, dass ist ja nicht gesagt (bei manchen Browsern)), weil die Datei ja eigentlich nicht geparst wird beim Upload, aber wer weis... vielleicht langt es auch die Datei umzubenennen (würd mich auch mal interessieren)...
Auf jeden Fall ist mir die Funktion:

/* (PHP 4 >= 4.3.0, PHP 5) */
exif_imagetype -- Determine the type of an image

aufgefallen (kannste ja mal in der Referenze nachlesen.... vielleicht hilft dir des weiter

Natheedo
15.06.2006, 20:49:36
Jup das dachte ich mir schon wegen den Dateien ... Wie gesagt hätte mir auch nie sowas träumen lassen!

Werde mal deinen Rat befolgen und mir die Funktion genauer angucken, vielleicht bekomm ich es ja gebacken.

Danke !

Natheedo

Morrandir
15.06.2006, 20:51:00
Ansonsten wenn das nur ein Wartungsscript für dich ist, dann schmeiß es doch einfach in nen eigenen Ordner und schütz dem mit .htaccess... dann biste eigentlich sicher.

Serp
16.06.2006, 01:19:25
Also wenn du im Header nen anderen MIME-Type setzt, dann scheint das auch beispielsweise ein JPG zu sein. Das hat dann auch nix mit irgendwelchen Fehlern zu tun, sondern das ist durchaus das gewünschte Verhalten. Dennoch kann man damit Sachen ausfiltern.

Dazu überprüfst du einfach erst mal, ob $type gleich image/jpeg, image/gif oder irgend n anderes Bild ist, das du zulassen möchtest. Wenn nicht, dann wird das Script beendet. Danach prüfst du zur Sicherheit noch, ob die Dateiendung irgendeine ist, die durch den PHP-Parser ausgeführt werden könnte - um "getarnte" Scripte zu entlarfen.

Codemäßig sieht das so aus:


if($type != 'image/gif' && $type != 'image/jpeg' && $type != 'image/png' && $type != 'image/bmp') die('Du Sack!');
if($type2 != 'image/gif' && $type2 != 'image/jpeg' && $type2 != 'image/png' && $type2 != 'image/bmp') die('Du Sack!');
if($type3 != 'image/gif' && $type3 != 'image/jpeg' && $type3 != 'image/png' && $type != 'image/bmp') die('Du Sack!');
if(substr($type, -4) == '.php') die('Arschloch');
if(substr($type2, -4) == '.php') die('Arschloch');
if(substr($type3, -4) == '.php') die('Arschloch');


Den Teil dann einfach vor den Teil, in dem die Bilder kopiert werden, ins Script schreiben. Möglicherweise willst du zuvor aber noch leichte Modifikationen an den Meldungen vornehmen... ;)

Und was du auch noch machen solltest: @copy durch move_uploaded_file ersetzen...

Natheedo
18.06.2006, 22:45:54
Ich danke euch, hab das nun mit den prüfenden MIME Types probiert und es klappt ! Zusätzlich noch .htaccess drauf und gut :)

Sollte sollte zumindest schonmal einen Grossteil fern halten.

Also vielen Dank nochmal an alle !

Natheedo