Files veilig uploaden
Inleiding
Files uploaden is een feature die vaak nodig is op een site en toch vaak problemen met zich meebrengt. Mensen lopen tegen schrijf/lees restricties aan en zetten uit paniek alle deuren open (het bekende CHMOD 777 verhaal). Niet doen, hieronder een korte uitleg waarom niet en hoe het wel zou moeten.
Basiskennis, de werking van een formulier
Als je dmv een html formulier een bestand upload dan blijft dat bestand slechts aanwezig totdat het script is afgelopen. Bij het versturen van het onderstaande formulier komt het bestand binnen op dezelfde pagina ($_SERVER[‘PHP_SELF’]) en wordt het bestand onder een tijdelijke naam even weggezet op de server.
001 002 003 004 005 006 007 008 009 010 011 012 |
<?php //hier staat je php script die iets met die file zal moeten gaan doen wil ie niet gedelete //worden na het uitvoeren van het (dmv php) opbouwen van deze pagina ?> <html> <body> <form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> <input type="hidden" name="MAX_FILE_SIZE" value="150000"> <input type="file" name="mijn_bestand"><br /> <input type="submit" value="Upload"> </body> </html> |
Het php script op deze pagina zal wat met de file moeten doen anders is na het doorlopen van het script de file weg. De file moet worden verplaatst van de tijdelijke locatie/bestandsnaam naar een definitieve locatie/bestandsnaam.
lees en schrijfrechten in linux
In Linux (hoogstwaarschijnlijk het besturingssysteem waarop je webserver draait) zijn mappen standaard beveiligd, niet iedereen mag er zomaar in schrijven/lezen/executen.
Er zijn 3 soorten gebruikers die op schrijf/lees/execute niveau 3 verschillende rechten kennen.
001 002 003 004 |
READ WRITE EXECUTE USER 1 2 4 GROUP 1 2 4 ALL 1 2 4 |
Wie zijn user/group/all? Wat zijn veilige instellingen? uitgebreid artikel over CHMOD
ftp
In eerste instantie gooi je de files van je website meestal met een ftp programma (zoals ws_ftp, flashfxp of bijv het gratis Total Commander) naar je webserver. Ook kun je via een dergelijk programma snel een directory stuctuur opzetten.
Handig en snel, ware het niet dat je via een FTPverbinding een andere USER en GROUP bent/hebt dan dat je de server benadert via php. Gevolg: Je hebt via php geen schrijfrechten in de mappen die je via je FTP programma gemaakt hebt. Je kunt dus niet via de php functie move_uploaded_file je bestand verplaatsen naar een andere map. Ook kun je in met de functie mkdir geen mappen maken.
Je hebt geen rechten, wat moet je nu doen? Veel scripts geven aan dat je de rechten van de directories moet verruimen (ofwel ze zeggen: zet je CHMOD hoger, bijvoorbeeld naar 777). Gevolg: ander users/groups mogen in je directory komen en je kunt aan de slag. MAAR heel rest van de wereld kan OOK uploaden/deleten in je directories. Foute boel dus.
ftp via php
Het alternatief is dat we via php een ftp connectie opzetten met de webserver, waarna we het bestand verplaatsen/wijzigen/deleten. Als we via een ftp connectie het bestand benaderen dan hebben we dezelfde USER/GROUP als dat we via het FTP programma zelf zouden doen.
voordelen van deze methode
- je voorkomt het probleem dat je directories hebt van verschillende USER/GROUPS. Als je de zaak wilt backuppen dan kun je dit makkelijk en snel via je FTP programma doen en loop je niet tegen mappen aan waar je volgens de rechten niet aan mag komen.
- Je hoeft je maprestricties niet te verruimen, de zaak blijft dus lekker veilig.
voorbeeld van de toepassing van een ftp connectie in php
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 |
<?php
//definieer constanten
define ('FTP_HOSTNAME','hier_de_hostname_van_je_ftp',true);
define ('FTP_USERNAME','inlog_naam',true);
define ('FTP_PASSWORD','wachtwoord',true);
define ('FTP_PATH','hoofd_path_binnen_ftp',true);
$userdir='userdir_waar_je_de_zaak_wilt_inzetten/'; //deze moet reeds zijn aangemaakt!
//start building html
?>
<html><body>
<?php
if (isset ($HTTP_POST_FILES['mijn_bestand'])){
//was a file uploaded?
if ($_FILES['mijn_bestand']['error']>0){
switch ($HTTP_POST_FILES['mijn_bestand']['error']){
case 1: echo 'Error, file exceeded upload_max_filesize'; break;
case 2: echo 'Error, file exceeded maximum file size (150 kb)',1); break;
case 3: echo 'Error, file only partially uploaded'; break;
case 4: echo 'Error, no file uploaded'; break;
}
}else{
//make sure file is no bigger then limit of 150 kb (150.000 bytes)
if ($_FILES['mijn_bestand']['size'] > 150000){
echo 'Error, filesize is '.$_FILES['mijn_bestand']['size'].' bytes, maximum is 150000 bytes (150 kB)';
}else{
ftp_file_copy($_FILES['mijn_bestand']['tmp_name'],FTP_PATH.$userdir.$_FILES['mijn_bestand']['name']);
if (is_file($userdir.$_FILES['mijn_bestand']['name']))
echo 'file is here';
else
echo 'file is not here';
}
}
}
//let op, de delete functie is nog niet veilig, iedereen die de url aanroept kan hier deleten
//bouw je eigen beveiliging in
if (isset ($_GET['del']) && $_GET['del']!=''){
if (is_file($userdir.'/'.$_GET['del']))
ftp_delete(FTP_PATH.$userdir.$_GET['del']);
}
?>
<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="150000">
<input type="file" name="mijn_bestand"><br />
<input type="submit" value="Upload">
<?php
if ($handle = opendir($userdir)) {
echo '<table cellspacing="0" cellpadding="3">
<tr><td>Filename</td><td>Width*Height</td><td>Preview</td><td>Delete</td></tr>';
$i=1;
while (false !== ($file = readdir($handle))) {
($i%2) ? $class='class="row1"' : $class='class="row2"';
if ($file!='.' && $file!='..' && $file!='Thumbs.db'){
echo '<tr '.$class.'><td>'.$file.'</td>';
echo '<td><a href="'.$_SERVER['PHP_SELF'].'?del='.$file.'" >delete</a></td></tr>';
}
$i++;
}
echo '</table>';
closedir($handle);
}
?>
|
Categories:
Tags: |