Upload di un file in PHP5

I form per l’upload dei file sono molto semplici dal punto di vista del codice html/php, ma non altrettanto semplici dal punto di vista della sicurezza. È sufficiente un controllo in meno e un pizzico di superficialità per permettere a chiunque di saturare la banda offerta dal nostro sistema di Hosting, oppure lo spazio su disco che abbiamo a disposizione.
Ecco un esempio di form per l’upload di files:

<html>   

 <head>   

 <title>File upload</title>   

 </head>   

 <body>   

 <?php   

 //Setup   

 $UPLOAD_DIR = "./uploads/";   

 //Codice   

 if(isset($_FILES['filename']))   

 { 
    	$file = $_FILES['filename']; 
if($file['error'] == UPLOAD_ERR_OK and is_uploaded_file($file['tmp_name']) 
{ 
if ($file["size"] > 0) { 
 	if (move_uploaded_file($file['tmp_name'], $UPLOAD_DIR.$file['name'])) { 
 		echo "<p><b>Upload:</b> Operazione effettuata con successo!</p>"; 	} else { 
                echo "<p><b>Upload:</b> Si è verificato un errore</p>"; 
        } 
 		} else { 
         		echo "<p><b>Upload:</b> Si è verificato un errore</p>"; 
 		}   

 	}   

 }   

?>   

 <h3>Carica un file</h3>   

 <form method="post" action="upload.php" enctype="multipart/form-data">   

 <input type="file" name="filename">   

 	<br />   

 	<input type="submit" value="Upload">   

 </form>   

 </body>   

</html>

In questo modo abbiamo effettuato diversi controlli sul file da uploadare:

  • Esistenza della variabile HTTP
  • Dimensione
  • Successo della funzione move_uploaded_file()

Ma non abbiamo ancora posto dei limiti alla dimensione del file!, per risolvere il problema possiamo prendere due strade:

Possiamo modificare il file di configurazione di php, in aprticolare la voce upload_max_filesize e settare alla destra dell’uguale un valore che fa al caso nostro.

Oppure possiamo utilizzare la funzione ini_set nel seguente modo : ini_set(‘upload_max_filesize’,$size), dove $size è una stringa che identifica la dimensione massima del file

Naturalmente eistono altri controlli da fare sul file che si sta caricando, in particolare, la variabile $file è un array associativo dotato dei seguenti attributi:

  • name: Il nome che il file aveva nella macchina utente
  • tmp_name: Il nome del file nel server
  • type: Il tipo MIME del file
  • error: Vale 0 se l’upload ha avuto esito positivo, altrimenti 1
  • size: Dimensioni in byte del file

Potete verificare la struttura dell’oggetto $file con le seguenti righe di codice:

<?php 
var_dump($_FILES["filename"]); 
?>

Per questo articolo è tutto😀, se avete consigli per aumentare la sicurezza delgi upload (sono sicuro che ne avete😉 non dovete far altro che postare!

10 risposte a “Upload di un file in PHP5

  1. Alcuni consigli ignorabili…

    * L’upload dovrebbe essere sempre protetto da un sistema di autenticazione o almeno da un captcha.

    Questo impedisce agli spammers di caricare files a go-go.

    * Tutto ciò che è in $_FILES arriva dall’esterno e, per definizione, NON è affidabile.

    Particolarmente infido è il campo ‘type’, spesso usato da chi è alle prime armi per eseguire controlli sul tipo di file inviato. In realtà sarebbe meglio non esistesse: il controllo del tipo di file deve essere eseguito nel server sul file stesso, usando per esempio getimagesize() per le immagini.

    * Non usare $_FILES[…][‘name’] per nominare il file

    Sempre a causa di quanto sopra, evitare di usare questo campo per dare il nome al file uploadato: nell’esempio sopra riportato se passo ‘../index.php’ (e ci sono i permessi sballati, come nell’80% delle istallazioni Windows) inietto php a ufo. Personalmente consiglio di creare un nome temporaneo. Se proprio si vuole usare il campo ‘name’, occorre almeno validarlo per bene.

    * Usare

    In realtà questo non apporta niente alla sicurezza, ma consente (se il browser lo supporta) di evitare alla fonte di uploadare un file troppo grande (non comincia nemmeno l’upload):

    http://www.php.net/manual/it/features.file-upload.php

  2. consigli tutt’altro che ignorabili…

    Personalmente, dopo aver avuto a che fare con gli infidi CSRF e bot che inviano montagne di richieste, penso che i captchas siano fondamentali…. o quasi, dipende dall’applicazione che si vuole difendere.

    Un altra cosa che non posso non confermare è l’importanza del controllo del tipo:
    di recente mi è capitato di trovare diversi siti di image hosting (purtroppo nella stragrande maggioranza dei casi italiani) che permettevano l’upload di script php semplicemente “facendo credere” al browser che si sta uploadando una jpg, perchè ne abbiamo modificato l’estensione.

    per gli stessi motivi è da evitare $_FILES[][‘nome’] perchè si da troppa libertà all’utente, che per chi si diletta con la sicurezza delle web app, altro non è che il potenziale nemico ^^

    Grazie mille a Nicola per le puntualizzazioni

  3. Ciao!

    cambiando l’estensione però non è più possibile eseguire lo script. Cioè se io uno script .php lo carico come .jpg e poi vado a quell’indirizzo almeno su FF non viene eseguito.

  4. Dipende anche dal server HTTP in cui gira il sito, in particolare la mistificazione di un jpg è utile nel caso si voglia inserire del Javascript:

    Php viene eseguito lato server, mentre la jpg viene fornita nell’html quindi è nsa sotituzione incompatibile. Al contrario javascript e jpg, (con una enorme dose di approssimazione) vengono processati nello stesso momento, quindi la cosa diventa fattibile

  5. Inutile notare che la pagina è stata rimossaaa

    ahuhauahuah, pensate quante grane ha quest’uomo…. il suo filtro antispam sarà incandescente xD xD

  6. Ciao dopo varie rierche in internet non riesco a trovare una soluzione…ho un form dove chiedo di caricare un file tramite un normale campo upload file.
    Vorrei che l’utente fosse obbligato a caricare questo file ma vorrei semplicemente che il controllo sul form verificasse se l’utente ha caricato qualcosa non mi interessa tutto il controllo del caricamento del file sul server..solo obbligarlo a fare sfoglia e a prendere un file.
    grazie ciao
    Graziano

  7. CIao.

    Tecnocamente, dal lato client, non puoi obbligare l’utente a fare un upload. Al massimo puoi inserire una funzione javascript che si attiva quando viene cliccato il pulsante di invio del form: se il campo in cui l’utente dovrebbe inserire l’indirizzo del file da caricare è vuoto allora visualizza un messaggio di errore

    la funzione controlla sarebbe più o meno cos’ definita

    function controlla()
    {
    if (document.mioform.miofile == “”)
    {
    alert(“Attenzione: Devi inserire un file da caricare”);
    }
    else {
    document.mioform.submit();
    }

    }

    Però attenzione: questo controllo può essere raggirato semplicemente modificando la pagina html di partenza, quindi se ti ritrovi davanti ad una applicazione in cui è importante la sicurezza, ti consiglio altre vie🙂

    Spero di esserti stato utile😉

  8. Scusate una domanda, non sono molto esperto di php. Qualcuno potrebbe aiutarmi in un problema?
    vorrei reperire il link della cartella in cui è finito il file, per salvarlo in una variabile ed usarla per secondi fini.
    Secondo voi questo potrebbe funzionare?

    $link = $UPLOAD_DIR.$file[‘name’];

    Grazie

  9. Ciao!

    Ecco un esempio fresco fresco di php.net:

    $uploaddir = ‘/var/www/uploads/’;
    $uploadfile = $uploaddir . basename($_FILES[‘userfile’][‘name’]);

    In questo modo (avendo modificato a dovere $uploaddir ti ritroverai all’interno della variabile $uploadfile il path del file che hai caricato.

    Mi permetto di ricordarti, visto che sei alle prime armi, di fare attenzione alla validazione dei file, per quesitoni di sicurezza🙂

  10. Hello, I wish for to subscribe for this webpage
    to take most up-to-date updates, thus where can i do it please assist.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...