[PHP] upload di file in cartella e sua sicurezza

  • Creatore Discussione Creatore Discussione VAik
  • Data di inizio Data di inizio
Eccomi...

Prove effettuate su 3 internet browser differenti "Firefox", "Chromium" e "Opera" tutti aggiornati all'ultima versione disponibile.

Le prove le ho effettuate su 11 test (nello stesso ordine) incrociando alcuni file e le proprie estensioni tra reali e FAKE.

Il risultato è che ci sono alcune differenze tra i vari browser anche se poche a dir la verità ma, secondo me importanti dati i risultati ottenuti.

Vi posto la tabella riassuntiva.
(click sull'immagine per ingrandirla).

tabella.png
 
Mi sa che se non sarà risolvibile, opterò per una soluzione più semplice, accettando solo jpg, png, stl e igs e magari con due script differenti e isolati richiamati da due pulsanti separati, uno per gli sketch (jpg, png) e l'altro per i file 3D (.stl, igs). Peccato però per i 3dm
 
ciao
vedo dalla tabella che hai fatto che in funzione del browser i vari finfo possono essere diversi
dai un occhio qui
http://php.net/manual/en/function.get-browser.php
e in funzione del bw fai un array diverso
qui l'esempio citato nel manuale
PHP:
<?php
echo $_SERVER['HTTP_USER_AGENT'] . "\n\n";
$browser = get_browser(null, true);
print_r($browser);
?>
quindi (schematizzo)
PHP:
switch($browser){
    case "MOZZILLA": $allowed_type = array( adatti a mozzilla);
    break;
    case: "IE":  $allowed_type = array( adatti a ie);
    break;
    //ec...
    default: echo "browser sconosciuto";
    brea;
}
 
Ho usato l'ultima funzione che ha passato Marino51.
Ora guardo e cerco di capire quello che hai appena postato tu.
 
ciao
scusa volevo indicare quello che hai nella colonna browser dove es per il primo cubo.stl hai esempio per
firefox = application/vista
e per
cromiunu =application/octet-stream
 
Dunque dovrei inserire la pare di codice schematizzata e inserire tutti i browser (almeno i più utilizzati)?
Quindi:
Firefox
Chrome
IE Explorer
Opera
e
Safari
almeno per coprire buona parte degli utenti, che tra l'altro molti usano Mac per la grafica, quindi quasi sempre Safari (che io non ho).
 
Allora forse è meglio limitare alle 4 estensioni che citavo prima in due sezioni separate per limitare rischi.
 
l'obiettivo è la sicurezza, non la si ottiene certo usando le informazioni che provengono dal browser perché facilmente camuffabili,
ci sono articoli in quantità sull'argomento
la via migliore è sicuramente utilizzare le analisi di php che identificano i contenuti,
dalla tabella pubblicata, nelle relative colonne, l'informazione è totalmente assente,
ciò mi fa pensare che per php 7 sia necessario approfondire il funzionamento di finfo, probabile che sia cambiato qualcosa rispetto alle versioni precedenti, per esempio alla riga 4, un file jpg, non viene riconosciuto, assurdo
 
Si infatti come dicevo qualche post fa, con la versione 7.0 di php sembra abbiano lavorato molto sul versante della sicurezza, ma sinceramente non sono così esperto da capire cosa abbiano modificato.
 
per cortesia, sostituisci queste righe, senza altre modifiche e riprova 1 solo "assurdo"
PHP:
    $file_name = $_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 = $_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
may be ....
 
ok attendo con ansia, ma il neurone ancora attivo mi ha ricordato gli unix trascorsi, dove i nomi dei file con maiuscole avevano un senso, a differenza di Windows, quindi niente di più deleterio di uno string to lower !
 
E non solo, anche gli spazi nei nomi dei file non esistevano e ancora oggi danno alcune noie:)
 
ho eliminato i controlli non necessari, aggiunto il controllo sugli spazi (che volendo si potrà disattivare)
meglio fare i nuovi test con,
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 = $_FILES["fileToUpload"]["name"];             // nome originale del file ( Linux Unix : attenzione maiuscole e minuscole )
    $file_type = strtolower($_FILES['fileToUpload']['type']); // mime type dal browser
    $file_size = $_FILES['fileToUpload']['size'] / 1024;      // dimensione in kB
    $file_temp = $_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 />";

    // evito nomi di files con spazi intercalati
    if ( substr_count($file_name, ' ') )
    {
        echo "ERRORE : Il nome del file intercalato da spazi non &egrave; accettato. Rinomina il tuo file!<br /><br />";
        return false;
    }

    // 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;
    }
    $mime_type = strtolower($mime_type);     // per avere facilità nella gestione dell'array "allowed_type" ammesso ci siano maiuscole
    echo "MIME TYPE : ".$mime_type."<br />";

    // controllo se è accettabile
    if ( !in_array($mime_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
    if ( !move_uploaded_file($file_temp, $file) )
    {
        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;
}
 
non devi più aggiornare la tabella, che è servita per capire ...
prova qualche immagine e vedi che il mime type ricavato da php sia corretto
nell'ultima versione, solo lui determina il caricamento

poi con tempo e pazienza ti conviene fare altre prove, per essere certo del funzionamento

rimane aperto (jpg.txt)
 
ciao
un'osservazione, ho provato in locale a caricare un file dwg (autocad) e usando
PHP:
$mime_type_tmp = mime_content_type($_FILES["fileToUpload"]["tmp_name"]);
il var_dump restituisce
string(13) "image/vnd.dwg"
con i tre bw che ho (fire,ie e chrome) e non application/acad
quindi ribadisco sarebbero da fare diverse prove per vedere quale è l'effettiva risposta e che questa non cambi col tipo di bw
inoltre forse sarebbe da controllare contemporaneamente sia il mime che l'estenzione con
PHP:
    $mime=array('image/vnd.dwg','image/png');//e tutti quelli necessari
    $tipo=array('dwg','png');
    if(in_array($mime_type_tmp, $mime) && in_array($est, $tipo)){
        echo "$nome_file tipo consentito<br>";
    }else{
        echo "$nome_file tipo NON consentito<br>";
    }
 
quindi ribadisco sarebbero da fare diverse prove per vedere quale è l'effettiva risposta e che questa non cambi col tipo di bw, inoltre forse sarebbe da controllare contemporaneamente sia il mime che l'estenzione con
le informazioni provenienti dal browser sono facilmente camuffabili,
l'obiettivo è di non usarle, ma di ottenere la stessa valutazione dalle funzioni php
PHP:
        $mime_type = ( new finfo(FILEINFO_MIME_TYPE) )->buffer( file_get_contents($file_temp) );

        $mime_type = mime_content_type($file_temp);

come detto, lavorando su un sistema Linux, occorre tenere in considerazione i nomi dei path e files con maiuscole e minuscole che hanno un senso a differenza di Windows (da qui i campi vuoti riportati in tabella)

aspettiamo la prova, per vedere se le funzioni php restituiscono il valore "atteso", se ciò fosse, il problema dovrebbe essere risolto con informazioni "interne" e non "esterne"

un riassunto
http://www.acunetix.com/websitesecurity/upload-forms-threat/
 
Ultima modifica:

Discussioni simili