Security: Files laten uploaden door gebruikers.

Het uploaden van bestanden is een van de minst veilige mogelijkheden die je aan jouw surfers kan aanbieden. Surfers krijgen immers de mogelijkheid om binaries, virussen en andere potentieel gevaarlijke bestanden te uploaden naar je server. Toch kan je er soms niet onderuit om deze upload functie aan te bieden. Gelukkig heeft PHP hiervoor een aantal opties om de risico's te beperken.

In php.ini bevinden zich 3 instellingen die te maken hebben met het uploaden van bestanden, deze hebben allen een standaardwaarde maar kunnen eventueel aangepast worden indien nodig:

file_uploads = ON
uploaden van files toestaan of niet

upload_tmp_dir =
Dit is de directory waar geŁploade bestanden tijdelijk worden opgeslaan. De uiteindelijke locatie van het bestand zal afhankelijk zijn van hoe je dit in de applicatie programmeert. Alle files komen echter eerst standaard in deze map terecht. De temp directory in php.ini is standaard leeg en kan men best ook zo laten omdat automatisch een path worden gekozen dat het best geschikt is.

upload_max_filesize = 2M
....
max_execution_time = 30 //Maximum hoeveelheid tijd dat een script krijgt om te beŽindigen
max_input_time = 60 //Maximum hoeveelheid tijd dat een script krijgt voor het parsen van zijn data
memory_limit = 8M //Maximum hoeveelheid geheugen dat een script mag verbruiken bij zijn uitvoering
post_max_size =8M //Maxixum grootte die een form bij 1 submit mag posten. (dit is dus de grootte van het max. te uploaden bestand + aantal bytes voor textbox, checkbox,... waardes)

Standaard zal de max. filesize op 2 megabyte staan, maar deze mag verhoogd worden. Hierbij wel opletten dat het script geen time-out veroorzaakt bij grote bestanden. Mensen met een trage connectie kunnen immers lange tijd nodig hebben om grote bestanden te uploaden. Verhoog dus de max_execution_time evenredig met de max. bestandsgrootte.

Ok, als deze instellingen in orde zijn, kan je starten met een formulier op te bouwen voor het uploaden van bestanden, hier een voorbeeld:

CODE
  1.  
  2. <form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
  3. <table>
  4.         <tr>
  5.                         <td>file name:</td>
  6.                         <td><input maxlength="30" class="css_textbox" name="tb_filename" type="text"/></td>
  7.         </tr>
  8.         <tr>
  9.                         <td>file description:</td>
  10.                         <td><input maxlength="100" class="css_textbox" name="tb_filedescription" type="text"/></td>
  11.         </tr>
  12.         <tr>
  13.                         <td>file path:</td>
  14.                         <td><input class="css_textbox" name="userfile" type="file" /></td>
  15.         </tr>
  16.         <tr>
  17.                         <td colspan="2" align="left"><input class="css_button" name="submit" type="submit" value="store image" /></td>
  18.         </tr>
  19. </table>
  20. </form>
  21.  


Het eerste wat opvalt is het enctype. Om alle file gegevens correct te verzenden moet deze waarde ingesteld zijn op 'multipart/form-data'.
De 2 eerste invoer velden zijn optionele naam en descriptie die je eventueel ook kan opslaan in je database.Het laatste invoerveld zal een textbox met 'bladeren' button tonen waarmee de gebruiker een bestand kan selecteren.
Als je wilt afwijken van de waarde die in php.ini staat ingesteld als de maximum grootte van een file, kan je een hidden field toevoegen aan het form:

CODE
  1.  
  2. <input type="hidden" name="MAX_FILE_SIZE" value="20000">
  3.  


Vertrouw hier echter niet volledig op want er zijn mogelijkheden die surfers in staat stellen toch grotere bestanden te uploaden. Vertrouw daarom op de waardes die ingesteld staan in php.ini.
Wanneer je form klaar is kan je starten met de afhandeling van een submit:

PHP
  1.  
  2. <?
  3. ....
  4. // Controleer of het 'userfile' ge-upload wordt met HTTP POST
  5. if (is_uploaded_file ($_FILES['userfile']['tmp_name']))        
  6. {
  7.         //$_FILES['userfile']['tmp_name'] bevat de volledige naam van het bestand
  8.                 //dat de gebruiker probeert te uploaden zoals het op zijn/haar pc staat.
  9.         //als de surfer voor of achteraan witte spaties toegevoegd heeft,
  10.                 //worden deze verwijderd met de trim() functie
  11.         $tmp = trim ($_FILES['userfile']['tmp_name']);
  12.  
  13.         //Zorg altijd dat de bestandsnaam een aanvaardbare lengte heeft die
  14.                 //geen problemen levert op de server.
  15.         //Kies daarom naam die de gebruiker ingeeft en doe hier enkele
  16.                 //controles op (geen speciale tekens, max lengte ...)
  17.         //OF je kan ook een aantal karakters van de bestandsnaam gebruiken,
  18.                 //doe hier wel controles of het bestand reeds bestaat op de server of niet:
  19.         ...
  20.         $finalname = substr($tmp, -10);
  21.         ...
  22.         //Haal alle spaties uit de bestandsnaam voor het geval jouw server
  23.                 //een ander systeem gebruikt voor het interpreteren van
  24.                 //bestandsnamen met spaties.
  25.         $finalname = ereg_replace(" ", "", $finalname);
  26.  
  27.         //Vervolgens doen we een test op het bestandstype, zodat het beperkt blijft tot de bestanden die je wilt
  28.                //, je kan hier erg ver in gaan met reguliere expressies.
  29.                //Ik controleer hier enkel of de bestandsnaam enkel      
  30.                //de karakters a...z, A...Z, 0...9 bevat en de extentie .txt heeft:
  31.         if ( (ereg(".txt", $filename)) && (validAZString($filename)) )
  32.         {
  33.                 //Stel het volledige path in waar het bestand zal komen te staan:
  34.                 $fullpath = "userfiles/" . $filename
  35.                 //Verplaats het bestand van de tijdelijke directory
  36.                                 //die php zelf heeft gekozen naar de juiste map op de server:
  37.                 if ( move_uploaded_file($_FILES['userfile']['tmp_name'], $fullpath) )
  38.                 {
  39.                         chmod ($fullpath, 0777); //Let op hier, hiermee heeft de surfer alle rechten op dit path,
  40.                                                 // stel dit in zoals het nodig is in jouw site.
  41.                                                 //Onderaan een link waar je de waarde voor chmod kan berekenen
  42.                         echo "file saved...";
  43.                 }
  44.                 else
  45.                 {
  46.                         echo "problems with saving file...";
  47.                 }
  48.         }
  49.         else
  50.         {
  51.                 echo "this is not a valid file...";
  52.         }
  53.  }
  54. ..
  55.  
  56.  
  57. ...
  58. function validAzString($x)
  59. {
  60.         if(ereg('[^[:space:]a-zA-Z0-9_.-]{1,}', $x))
  61.         {
  62.                 return false;
  63.         }
  64.         else
  65.         {
  66.                 return true;
  67.         }
  68. }
  69. ...
  70.  
  71.  
  72. ?>
  73.  


Bereken hier de chmod waardes voor je mappen.Dit artikel werd geschreven door MontyP op donderdag 23 februari 2006 om 18:32 en werd sindsdien 2088 keer gelezen.

  • Pagina
  • 1 van 1

Geen reacties gevonden
Er werden nog geen reacties bij dit artikel geplaatst.
  • Indien je denkt iets te kunnen toevoegen aan het artikel, kan je zelf een reactie schrijven via de koppeling Plaats een reactie bij dit artikel hieronder.
  • Indien je andere commentaar (iets wat niet meteen functioneel bijdraagt aan het artikel zelf) hebt, kan je een bedankje formuleren via de koppeling Plaats een bedankje bij dit artikel hieronder.