[PHP] upload di file in cartella e sua sicurezza

  • Creatore Discussione Creatore Discussione VAik
  • Data di inizio Data di inizio
Attivandola dovrò decommentare le righe che ora sono commentate e commentare queste?
 
PHP:
con "mime_content_type",

    // $mime_type = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) ); // extension=php_fileinfo.dll in php.ini

    $mime_type = mime_content_type($file_temp);

    echo "MIME TYPE : ".$mime_type."<br />";

    $file_type = $mime_type;

con "finfo",

    $mime_type = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) ); // extension=php_fileinfo.dll in php.ini

    // $mime_type = mime_content_type($file_temp);

    echo "MIME TYPE : ".$mime_type."<br />";

    $file_type = $mime_type;

puoi eliminare l'echo commentato che non serve
 
Ragazzi, scuste se vi rompo ancora, non so cosa sia successo, ma lo script non funziona più. Qualsiasi cosa tento di uploadre mi dice che il tipo non è corretto.
Upload : cubo.stl
Type : application/sla
Size (kB) : 0.66796875
Stored in : /tmp/phpywa0zd
target folder : models/
target file : models/cubo.stl
MIME TYPE :
ERRORE : Il file non è del tipo corretto.

riposto tutto il codice attuale così da capire meglio ciò che sto usando.
PHP:
<?php
if(isset($_POST['submit']))
{
    $uploadOk = GestisciUpload(); // $uploadOk = 1 : OK

    // qui va gestito il comportamento successivo
}
else
{
    // questa parte serve solo per provare lo script
    DisplayForm();
}


function GestisciUpload($target_dir = "models/")
{
    $allowed_type = array(
        'application/acad',
        'application/dxf',
        'application/iges',
        'application/sla',
        'application/vnd.ms-pki.stl',
        'application/x-navistyle',
        'image/gif',
        'image/jpeg',
        'image/pjpeg',
        'image/png',
        'image/vnd.dwg',
        'image/x-dwg',
        'model/iges',
        'x-world/x-3dmf',
    );
    $UploadErrors = array(
        'There is no error, the file uploaded with success',
        'The uploaded file exceeds the upload_max_filesize directive in php.ini',
        'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
        'The uploaded file was only partially uploaded',
        'No file was uploaded',
        'Missing a temporary folder',
        'Failed to write file to disk',
        'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help',
    );

    $err = $_FILES['fileToUpload']['error'];
    if ($err > 0 )
    {
        echo "ERRORE : ".( $err < 8 ? $UploadErrors[$err] : $err )."<br /><br />";
        return 0;
    }

    // controllo se esiste la cartella di destinazione
    if ( !is_dir($target_dir) )
    {
        echo "ERRORE : La cartella di destinazione non esiste<br /><br />";
        return 0;
    }

    $file_name = strtolower(basename($_FILES["fileToUpload"]["name"]));     // nome originale del file
    $file_type = strtolower($_FILES['fileToUpload']['type']);               // tipo
    $file_size = $_FILES['fileToUpload']['size'] / 1024;                    // dimensione in kB
    $file_temp = strtolower($_FILES['fileToUpload']['tmp_name']);           // path e nome assegnato dall'upload

    $file_path = $target_dir;
    $file      = $file_path.$file_name;

    // visualizzazioni da eliminare (commentare) in produzione
    echo "Upload : "        .$file_name    ."<br />";
    echo "Type : "        .$file_type    ."<br />";
    echo "Size (kB) : "        .$file_size    ."<br />";
    echo "Stored in : "        .$file_temp    ."<br />";
    echo "target folder : "    .$file_path    ."<br />";
    echo "target file : "    .$file        ."<br />";

    // $mime_type = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) ); // extension=php_fileinfo.dll in php.ini
    // echo "MIME TYPE : "        .$mime_type    ."<br />";
   
    $mime_type = mime_content_type($file_temp);
    echo "MIME TYPE : ".$mime_type."<br />";
$file_type = $mime_type;
    // controllo se è accettabile
    if ( !in_array($file_type, $allowed_type) )
    {
        echo "ERRORE : Il file non &egrave; del tipo corretto.<br /><br />";
        return 0;
    }

    // controllo la dimensione
    if ($file_size == 0)
    {
        echo "ERRORE : Il file &egrave; vuoto.<br /><br />";
        return 0;
    }
    if ($file_size > 5000)
    {
        echo "ERRORE : Il file ha una dimensione troppo grande. Carica un file che non superi i 5 Mb.<br /><br />";
        return 0;
    }

    // controllo se esiste lo stesso nome
    if ( file_exists($file) )
    {
        echo "ERRORE : Il nome scelto per il file esiste gi&agrave;. Rinomina il tuo file!<br /><br />";
        return 0;
    }

    // sposto il file nella destinazione (copia e cancellazione, move non funziona)
    // $err = copy($file_temp, $file);
    // unlink($file_temp);

    $err = move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $file);
    if ( !$err ) {
        echo "ERRORE : Lo spostamento del file nella destinazione non &egrave; riuscito"."<br /><br />";
        return 0;
    }

    // controllo se il file é arrivato a destinazione
    if (!file_exists($file))
    {
        echo "ERRORE : Il file non &egrave; arrivato a destinazione<br /><br />";
        return 0;
    }

    // non ho altro da fare
    echo "Il file -- ".$file_name." -- &egrave; stato caricato correttamente.";
    return 1;
}

function DisplayForm()
{
?>
<!DOCTYPE html>
<form action="" method="post" enctype="multipart/form-data">
    File da caricare : <input type="file" name="fileToUpload" id="fileToUpload" />
    <br /> <br />
    <input name="submit" type="submit" id="submit" value="Submit">
    <br /> <br />
</form>
</html>
<?PHP
}
?>
 
Ho provato anche ad attivare il fileinfo nel php.ini modificandolo da così:
;extension=php_fileinfo.dll
a così:
extension=php_fileinfo.dll
poi ho modificato lo script così:
PHP:
 // extension=php_fileinfo.dll in php.ini
    // echo "MIME TYPE : "        .$mime_type    ."<br />";
  
   // $mime_type = mime_content_type($file_temp);
   echo "MIME TYPE : ".$mime_type."<br />";
   $file_type = $mime_type;
riavviato apache ma il risultato è lo stesso.
 
visto che ho aggiunto i controlli sulle funzioni "mime", usa quest'ultima stesura (garantito ultima, non farò altre variazioni)
sostituisci tutta la funzione e non modificare nulla,
lo script trova da solo quale funzione usare
PHP:
function GestisciUpload($file_path = "models/")
{
    $allowed_type = array
    (
        'application/acad',
        'application/dxf',
        'application/iges',
        'application/sla',
        'application/vnd.ms-pki.stl',
        'application/x-navistyle',
        'image/gif',
        'image/jpeg',
        'image/pjpeg',
        'image/png',
        'image/vnd.dwg',
        'image/x-dwg',
        'model/iges',
        'x-world/x-3dmf',
    );

    $UploadErrors = array
    (
        'There is no error, the file uploaded with success',
        'The uploaded file exceeds the upload_max_filesize directive in php.ini',
        'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
        'The uploaded file was only partially uploaded',
        'No file was uploaded',
        'Missing a temporary folder',
        'Failed to write file to disk',
        'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help',
    );

    $err = $_FILES['fileToUpload']['error'];
    if ($err > 0 )
    {
        echo "ERRORE : ".( $err < 8 ? $UploadErrors[$err] : $err )."<br /><br />";
        return false;
    }

    // controllo se esiste la cartella di destinazione
    if ( !is_dir($file_path) )
    {
        echo "ERRORE : La cartella di destinazione non esiste<br /><br />";
        return false;
    }

    $file_name = strtolower(basename($_FILES["fileToUpload"]["name"])); // nome originale del file
    $file_type = strtolower($_FILES['fileToUpload']['type']);           // tipo
    $file_size = $_FILES['fileToUpload']['size'] / 1024;                // dimensione in kB
    $file_temp = strtolower($_FILES['fileToUpload']['tmp_name']);       // file temporaneo, path e nome assegnato dall'upload
    $file      = $file_path.$file_name;                                 // path di destinazione e nome originale del file

    // visualizzazioni da eliminare (commentare) in produzione
    echo "Upload : "        .$file_name."<br />";
    echo "Type : "          .$file_type."<br />";
    echo "Size (kB) : "     .$file_size."<br />";
    echo "Stored in : "     .$file_temp."<br />";
    echo "target folder : " .$file_path."<br />";
    echo "target file : "   .$file     ."<br />";

    // controllo se posso ottenere "mime_type"
    if ( class_exists('finfo') )
    {
        $mime_type = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) );
    }
    else if ( function_exists('mime_content_type') )
    {
        $mime_type = mime_content_type($file_temp);
    }
    else
    {
        echo "ERRORE : non posso ottenere 'mime_type' mancano gli strumenti php<br /><br />";
        return false;
    }
    echo "MIME TYPE : ".$mime_type."<br />";

    $file_type = $mime_type;

    // controllo se è accettabile
    if ( !in_array($file_type, $allowed_type) )
    {
        echo "ERRORE : Il file non &egrave; del tipo corretto.<br /><br />";
        return false;
    }

    // controllo la dimensione
    if ($file_size == 0)
    {
        echo "ERRORE : Il file &egrave; vuoto.<br /><br />";
        return false;
    }
    if ($file_size > 5000)
    {
        echo "ERRORE : Il file ha una dimensione troppo grande. Carica un file che non superi i 5 Mb.<br /><br />";
        return false;
    }

    // controllo se esiste lo stesso nome
    if ( file_exists($file) )
    {
        echo "ERRORE : Il nome scelto per il file esiste gi&agrave;. Rinomina il tuo file!<br /><br />";
        return false;
    }

    // sposto il file nella destinazione
    $err = move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $file);
    if ( !$err )
    {
        echo "ERRORE : Lo spostamento del file nella destinazione non &egrave; riuscito"."<br /><br />";
        return false;
    }

    // controllo se il file é arrivato a destinazione
    if (!file_exists($file))
    {
        echo "ERRORE : Il file non &egrave; arrivato a destinazione<br /><br />";
        return false;
    }

    // non ho altro da fare
    echo "Il file -- ".$file_name." -- &egrave; stato caricato correttamente.";
    return true;
}
 
Fatto.
risultato:
Upload : cubo.stl
Type : application/sla
Size (kB) : 0.66796875
Stored in : /tmp/phptmnj7q
target folder : models/
target file : models/cubo.stl
MIME TYPE : application/x-empty
ERRORE : Il file non è del tipo corretto.
stessa cosa

Ma è assurdo!
Ieri sera funzionava e stamattina più niente.
 
il fileinfo è abilitato. Ho tolto il ";" all'inizio riga del php.ini, anche se in realtà dicono che di default è già abilitato, comunque in tutti e due i casi il risultato è sempre che non trova più il mime type
MIME TYPE : application/x-empty
 
da quanto hai postato si vede che il browser invia il tipo, "application/sla" mentre php sembra non identificarlo "application/x-empty"

se concordi, possiamo verificare prima quanto restituisce php e in caso negativo usare il tipo inviato dal browser
 
guarda cosa succede se rinomino un png in txt ... viene accettato ma caricato come txt
Upload : png.txt
Type : text/plain
Size (kB) : 42.76953125
Stored in : c:\windows\temp\phpeab.tmp
target folder : C:/Web_Sites/__Test/PHP/TEST/_xnotar/
target file : C:/Web_Sites/__Test/PHP/TEST/_xnotar/png.txt
MIME TYPE 1 : image/png
MIME TYPE 2 : image/png

Il file -- png.txt -- è stato caricato correttamente.
 
Questo capitava prima della modifica di ieri, poi dopo la modifica andava tutto bene. Ora non accetta più nulla, se torno alla versione vecchia funziona ancora ma con il problema che hai appena postato.
 
sostituisci questo blocco, (fai riferimento alla prima e all'ultima istruzione
PHP:
    echo "target file : "   .$file     ."<br />";

    // controllo se posso ottenere "mime_type"
    if ( class_exists('finfo') )
    {
        $mime_type_1 = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) );
        echo "MIME TYPE 1 : ".$mime_type_1."<br />";
    }
    if ( function_exists('mime_content_type') )
    {
        $mime_type_2 = mime_content_type($file_temp);
        echo "MIME TYPE 2 : ".$mime_type_2."<br />";
    }
    if ( empty($mime_type_1) and empty($mime_type_2) )
    {
        echo "ATTENZIONE : non posso ottenere 'mime_type' mancano gli strumenti php<br /><br />";
    }

    // controllo se è accettabile
    if ( !in_array($mime_type_1, $allowed_type) and !in_array($mime_type_2, $allowed_type) and !in_array($file_type, $allowed_type) )
    {
        echo "ERRORE : Il file non &egrave; del tipo corretto.<br /><br />";
        return false;
    }

    // controllo la dimensione
 
così l'ha caricato
Upload : cubo.stl
Type : application/sla
Size (kB) : 0.66796875
Stored in : /tmp/phpxnx9s5
target folder : models/
target file : models/cubo.stl
target file : models/cubo.stl
MIME TYPE 1 : application/x-empty
MIME TYPE 2 :
Il file -- cubo.stl -- è stato caricato correttamente.
però ha caricato anche come .jpg un file che in realtà è in php
Upload : test2.jpg
Type : image/jpeg
Size (kB) : 0.81640625
Stored in : /tmp/phpb9izo1
target folder : models/
target file : models/test2.jpg
target file : models/test2.jpg
MIME TYPE 1 : application/x-empty
MIME TYPE 2 :
Il file -- test2.jpg -- è stato caricato correttamente.
mi sa che non se ne esce da questo vicolo cieco:confused:
 
c'è incoerenza tra il browser e php,
tra l'altro che browser stai usando ? perché IE11 riesce a riconoscere il php camuffato, mentre il tuo browser sembra consideri l'estensione e nulla più
ti chiederei di fare una tabellina con i vari file da caricare (estensione) e i 3 tipi che vengono riportati in modo da avere un quadro completo, perché, noto che per alcuni va bene il valore dal browser per altri da php, potremmo cercare di forzare il legame,
vediamo fino a dove si riesce ad arrivare con la sicurezza
aspetto
 
forse stai usando anche una versione php vecchia (ipotesi) perché le funzioni php sembrano non restituire i valori,
la mia 5.4.9 capisce che il png o jpg camuffati sono degli script php
Cattura.PNG
 
se fai i controlli ... usa la nuova, dovrebbe rifiutare le immagini tarocche
PHP:
function GestisciUpload($file_path = "models/")
{
    $allowed_type = array
    (
        'application/acad',
        'application/dxf',
        'application/iges',
        'application/sla',
        'application/vnd.ms-pki.stl',
        'application/x-navistyle',
        'image/gif',
        'image/jpeg',
        'image/pjpeg',
        'image/png',
        'image/vnd.dwg',
        'image/x-dwg',
        'model/iges',
        'x-world/x-3dmf',
    );

    $UploadErrors = array
    (
        'There is no error, the file uploaded with success',
        'The uploaded file exceeds the upload_max_filesize directive in php.ini',
        'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
        'The uploaded file was only partially uploaded',
        'No file was uploaded',
        'Missing a temporary folder',
        'Failed to write file to disk',
        'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help',
    );

    $err = $_FILES['fileToUpload']['error'];
    if ($err > 0 )
    {
        echo "ERRORE : ".( $err < 8 ? $UploadErrors[$err] : $err )."<br /><br />";
        return false;
    }

    // controllo se esiste la cartella di destinazione
    if ( !is_dir($file_path) )
    {
        echo "ERRORE : La cartella di destinazione non esiste<br /><br />";
        return false;
    }

    $file_name = strtolower(basename($_FILES["fileToUpload"]["name"])); // nome originale del file
    $file_type = strtolower($_FILES['fileToUpload']['type']);           // tipo
    $file_size = $_FILES['fileToUpload']['size'] / 1024;                // dimensione in kB
    $file_temp = strtolower($_FILES['fileToUpload']['tmp_name']);       // file temporaneo, path e nome assegnato dall'upload
    $file      = $file_path.$file_name;                                 // path di destinazione e nome originale del file

    // visualizzazioni da eliminare (commentare) in produzione
    echo "Upload : "        .$file_name."<br />";
    echo "Type : "          .$file_type."<br />";
    echo "Size (kB) : "     .$file_size."<br />";
    echo "Stored in : "     .$file_temp."<br />";
    echo "target folder : " .$file_path."<br />";
    echo "target file : "   .$file     ."<br />";

    // Check if image file is a true image or fake image
    if (strpos($file_type, 'image') !== false)
    {
        $file_info = getimagesize($file_temp);
        if( empty($file_info) )
        {
            echo "ERRORE : Il file non contiene l'immagine attesa<br /><br />";
            return false;
        }
        echo "MIME TYPE 3 : ".$file_info['mime']."<br />";
    }

    // controllo se posso ottenere "mime_type"
    if ( class_exists('finfo') )
    {
        $mime_type_1 = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) );
        echo "MIME TYPE 1 : ".$mime_type_1."<br />";
    }
    if ( function_exists('mime_content_type') )
    {
        $mime_type_2 = mime_content_type($file_temp);
        echo "MIME TYPE 2 : ".$mime_type_2."<br />";
    }
    if ( empty($mime_type_1) and empty($mime_type_2) )
    {
        echo "ATTENZIONE : non posso ottenere 'mime_type' mancano gli strumenti php<br /><br />";
    }

    // controllo se è accettabile
    if ( !in_array($mime_type_1, $allowed_type) and !in_array($mime_type_2, $allowed_type) and !in_array($file_type, $allowed_type) )
    {
        echo "ERRORE : Il file non &egrave; del tipo corretto.<br /><br />";
        return false;
    }

    // controllo la dimensione
    if ($file_size == 0)
    {
        echo "ERRORE : Il file &egrave; vuoto.<br /><br />";
        return false;
    }
    if ($file_size > 5000)
    {
        echo "ERRORE : Il file ha una dimensione troppo grande. Carica un file che non superi i 5 Mb.<br /><br />";
        return false;
    }

    // controllo se esiste lo stesso nome
    if ( file_exists($file) )
    {
        echo "ERRORE : Il nome scelto per il file esiste gi&agrave;. Rinomina il tuo file!<br /><br />";
        return false;
    }

    // sposto il file nella destinazione
    $err = move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $file);
    if ( !$err )
    {
        echo "ERRORE : Lo spostamento del file nella destinazione non &egrave; riuscito"."<br /><br />";
        return false;
    }

    // controllo se il file é arrivato a destinazione
    if (!file_exists($file))
    {
        echo "ERRORE : Il file non &egrave; arrivato a destinazione<br /><br />";
        return false;
    }

    // non ho altro da fare
    echo "Il file -- ".$file_name." -- &egrave; stato caricato correttamente.";
    return true;
}
 
Ho pensato anch'io al browser. Sto usando Firefox 50.1.0 ma ora ho provato anche con Chromium (Chrome per Linux) e con Opera, il risultato non cambia.
Adesso faccio la tabella che mi hai suggerito. Mi ci vorrà un po' di tempo, appena fatta la posto.
 

Discussioni simili