webForumDet fria alternativet

Säkerhet vid uppladdningsformulär

PHP

19 svar · 884 visningar · startad av rille31

Medlem sedan okt. 2004186 inlägg
Frågan#1

Har gjort ett formulär för uppladdning och skulle behöva lite tips angående säkerheten, vad ska man tänka på?

Hur ska man undvika att folk laddar upp körbara filer?

Medlem sedan juni 20006 031 inlägg
#2

Du får kolla vilken mimi-type filen har och godkänna vilka som ska kunna laddas upp.

$mime = $_FILES['userfile']['type'];
if($mime=="image/jpeg" || $mime=="image/pjpeg") {
     // bilden är en jpg och får laddas upp
     // kör kod här som sparar filen på servern
} else {
     echo "otillåten fil.";
}
Medlem sedan juni 20001 251 inlägg
#3

$_FILES['userfile']['type'] sätts av klienten, det är därför dumt att förlita sig på det värdet. För att läsa av filtyp på bilder kan man t.ex. använda sig av: http://se2.php.net/manual/en/function.getimagesize.php

Medlem sedan juni 20006 031 inlägg
#4

getimagesize funkar ju bara på bilder, och vi vet ju inte om han vill kunna ladda upp andra sorters filer också.
Vad menar du med att $_FILES['userfile']['type'] sätts av klienten?

Medlem sedan juni 20001 251 inlägg
#5

Pedda skrev:

getimagesize funkar ju bara på bilder, och vi vet ju inte om han vill kunna ladda upp andra sorters filer också.
Vad menar du med att $_FILES['userfile']['type'] sätts av klienten?

Det var bara ett exempel. Det finns andra sätt att ta fram övriga mime-types.

"$_FILES['userfile']['type']
The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted. "

Det var ett par "hackers" som utnyttjade detta för en tid sedan mot en rad svenska communityn. De laddade upp php-skript genom att manipulera fil-typen som webbläsaren sätter vid uppladdning.

Medlem sedan okt. 2004186 inlägg
#6

Pedda skrev:

getimagesize funkar ju bara på bilder, och vi vet ju inte om han vill kunna ladda upp andra sorters filer också.
Vad menar du med att $_FILES['userfile']['type'] sätts av klienten?

Hade faktiskt tänkt att tillåta txt, doc och pdf filer :)

Medlem sedan okt. 200612 inlägg
#7

$fil = explode (".", $fil); //Splittar upp filen som personen ska laddas upp.

if ($fil[1]=='txt' OR $fil[1]=='doc' OR $fil[1]=='pdf')
{
Fortsätt med koden som laddar upp bilden.
}else{
echo "Denna filtyp är ej tillåten";
exit();
}

Så skulle jag göra. men det verkar finnas simplare lösningar:P

Medlem sedan juni 20006 031 inlägg
#8

tha_neo skrev:

$fil = explode (".", $fil); //Splittar upp filen som personen ska laddas upp.

if ($fil[1]=='txt' OR $fil[1]=='doc' OR $fil[1]=='pdf')
{
Fortsätt med koden som laddar upp bilden.
}else{
echo "Denna filtyp är ej tillåten";
exit();
}

Så skulle jag göra. men det verkar finnas simplare lösningar:P

Det är ett sätt som jag inte rekommenderar ur säkerhetssynpunkt.
Om jag har en exe fil som jag döper till minfil.txt.exe så kommer jag att kunna ladda upp den utan några problem eftersom skriptet tror att det är en textfil.

Medlem sedan okt. 200612 inlägg
#9

det var iofs väldigt sant!:) men gör en counter o räkna hur många element som finns i den o sen kontrollera sista elementet?

Medlem sedan dec. 20025 483 inlägg
#10

Använd regex:

if (preg_match("/\.(?:txt|doc|pdf)$/i", $fil)){
  // ok!
}
Medlem sedan juni 20006 031 inlägg
#11

Problemet kvarstår ju dock om man döper om virus.exe till virus.txt så släpps den igenom.

Medlem sedan maj 2005704 inlägg
#12

Dock så går det väl inte att exekvera tex en exe eller php på en webbserver om filen har filändelsen .txt?
Döper du om en .php fil till .txt så tolkar inte servern den som php utan visar bara själva koden i din webbläsare.
Så huvudsaken är inte vad det är för mimetyp utan vilken filändelse den har.

Medlem sedan juni 20006 031 inlägg
#13

Nej, men jag förstår inte varför man ska ta några chanser.
Om jag t.ex vill godkänna Worddokument så är det väl bättre att kolla att mime är application/msword och inte släppa igenom mime application/octet-stream som bla exe-filer har?

Mime ändras ju inte även om man döper om filen till en annan filändelse.

Medlem sedan maj 2005704 inlägg
#14

Vad det är för mimetyp går att manipulera så därmed är den kontrollen inte speciellt intressant.
Och vilken skada skulle kunna uppstå pga av någon laddar upp en .exe omdöpt till .txt?

Men visst...bäst att ta det säkra före det osäkra och kolla både filändelse och MIME.

Medlem sedan juni 20006 031 inlägg
#15

Ok, visste inte att det gick att manipulera mime. Har inte hört talas om det innan.
När jag har testat att döpa om filer så har de haft kvar rätt mime, men det finns kanske något sätt att ändra det på.

Medlem sedan okt. 2004186 inlägg
#16

Ok, så det är alltså bäst att kolla både filändelse samt mime typ?

Först kolla filändelsen
Om det stämmer kollar man mimetypen
Om det stämmer laddas bilden upp

så scriptet blir ungefär så här (förutom lite error meddelanden man kan lägga till)

$fil = $_FILES['Filedata']['name'];
if (preg_match("/\.(?:txt|doc|pdf)$/i", $fil)){ 
  $mime = $_FILES['userfile']['type']; 
  if($mime=="image/jpeg" || $mime=="image/pjpeg") { 
     //move the uploaded file
     move_uploaded_file($_FILES['Filedata']['tmp_name'], "./files/".$_FILES['Filedata']['name']);
   }
}

Fast jag måste byta mimetypen till txt, doc och pdf.
Fast jag ingen aning om vad det är för mimetyp på dom filerna :(

Medlem sedan juni 20006 031 inlägg
#17

rille31 skrev:

Fast jag måste byta mimetypen till txt, doc och pdf.
Fast jag ingen aning om vad det är för mimetyp på dom filerna :(

En lista på mime types:
http://www.webmaster-toolkit.com/mime-types.shtml

Medlem sedan okt. 2004186 inlägg
#18

Pedda skrev:

En lista på mime types:
http://www.webmaster-toolkit.com/mime-types.shtml

Tackar

Edit

Fick det inte att funka riktigt, mime typen verkar inte stämma

$fil = $_FILES['Filedata']['name'];
if (preg_match("/\.(?:txt|doc|pdf)$/i", $fil)){ 
  //create the directory if doesn't exists (should have write permissons)
  //if(!is_dir("./files") mkdir("./files", 0755); 
  $mime = $_FILES['Filedata']['type']; 
  if($mime == "application/msword" || $mime == "text/plain" || $mime == "application/pdf") { 
    //move the uploaded file
	move_uploaded_file($_FILES['Filedata']['tmp_name'], "./files/".$_FILES['Filedata']['name']);
		}
}
Medlem sedan juni 20006 031 inlägg
#19

Testa att skriva ut mime för att se vad den heter.

Medlem sedan okt. 2004186 inlägg
#20

testade med ett html formulär och koden funkade finfint:)

dock så funkar inte mime delen när jag kör mitt flashformulär fast det funkar utan den delen, skumt

nu vet jag iallafall vary man ska leta efter fel :)

271 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
127 ms — deklarationer (db)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)