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);
}
?>

Geef een reactie

You must be logged in to post a comment.