Visualizzazione risultati 1 fino 11 di 11
Like Tree2Likes
  • 1 Post By mzanella
  • 1 Post By mzanella

Discussione: Sicurezza upload image

  1. #1
    sestuworld non è connesso Neofita
    Data registrazione
    09-01-2018
    Messaggi
    13

    Predefinito Sicurezza upload image

    Buongiorno a tutti.
    Sto lavorando a una funzione per controllare i file in ingresso tramite upload immagini e validarli.

    Per ora sono riuscito a controllare il mime, controllare che sia davvero un'immagine (con getfilesize) ed eliminare estensioni nocive.
    Il problema è che riesco a far caricare immagini con codice php all'interno delle informazioni.

    Prima di andare avanti vi posto lo script:
    Codice:
    //dati del form//
    $nome_file_temporaneo = $_FILES['file_inviato']['tmp_name'];
    $nome_file_vero = basename($_FILES['file_inviato']['name']);
    $dati_file = file_get_contents($nome_file_temporaneo);
    $imgsize2 = getimagesize($nome_file_temporaneo);
    echo 'filesize2?  ';print_r($imgsize2);echo '<br>';
    
    // Tutti i controlli : TYPE, MIME, ed ESTENSIONI INVALIDE
    $checkall = 0;
    echo '$checkall '.$checkall.'<br>';
    if (
        ($imgsize2[mime] == "image/jpg") || 
        ($imgsize2[mime] == "image/png") ||
        ($imgsize2[mime] == "image/jpeg")
        ) {
           echo 'OK 1<br>';
           $checkall = $checkall +1;
          } 
    else { echo'NO 1'; exit(); }
    
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    if (false === $ext = array_search(
                                      $finfo->file($_FILES['file_inviato']['tmp_name']),
                                      array(
                                           'jpg' => 'image/jpeg',
                                           'png' => 'image/png',
                                           ),
                                           true
                                           )
                                        ){
                                          echo 'NO 2<br>'; exit();
                                         }
    else  {
          echo 'OK 2<br>';
          $checkall = $checkall +1;
          }
          
    $blacklist = array(".php", ".phtml", ".php3", ".php4" , ".js" , ".json");
    foreach ($blacklist as $item) {
        if(preg_match("/$item\$/i", $nome_file_vero)) {
                                 echo "NO 3 <br>";
                                                exit;
                                                                      }
        else {
              echo 'OK 3 <br>';
              $checkall = $checkall +1;
              }                                                              
                                  }
     
    if (getimagesize($_FILES['file_inviato']['tmp_name']) == false) {
                                                                    echo'NO 4'; exit();
                                                                    } 
    else {
              echo 'OK 4 <br>';
              $checkall = $checkall +1;
              } 
    
    ?>
    In pratica, grazie a questo script evito file del tipo: nome.php.jpg, oppure file php mascherati da immagine nomescript.png (dentro c'è solo codice php) e file con estensioni non volute: php, html, js, eccetera.

    MA, come dicevo, permette ancora di fare upload di file immagini validi al 100%, ma con codice nelle informazioni.

    Adesso, volevo chiedervi (visto che non sono riuscito a trovare soluzioni) se c'è pericolo che si riesca a far eseguire gli script all'interno se io uso semplicemente:

    <img src="/../nomeimaggine.png">

    Grazie mille per eventuali risposte ;)

  2. #2
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    [...] controllare che sia davvero un'immagine (con getfilesize) [...]
    Dalla documentazione di getimagesize:
    Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead.
    Ciò detto, ci sono un paio di pagine interessanti che vale la pena leggere:
    File upload vulnerabilities : appending PHP code to an image
    e Is it possible to execute a php script in an image file?.

    La soluzione più sicura (oltre ai controlli su MIME type ed estensione) è convertire l'immagine usando PHP GD prima di salvarla. In questo modo hai la garanzia che l'immagine salvata nel tuo spazio web sia [generata tramite PHP GD, dunque sotto il tuo controllo, e quindi] priva di codice PHP al proprio interno.

    I suggerimenti che do più spesso:


  3. #3
    sestuworld non è connesso Neofita
    Data registrazione
    09-01-2018
    Messaggi
    13

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Dalla documentazione di getimagesize:


    Ciò detto, ci sono un paio di pagine interessanti che vale la pena leggere:
    File upload vulnerabilities : appending PHP code to an image
    e Is it possible to execute a php script in an image file?.

    La soluzione più sicura (oltre ai controlli su MIME type ed estensione) è convertire l'immagine usando PHP GD prima di salvarla. In questo modo hai la garanzia che l'immagine salvata nel tuo spazio web sia [generata tramite PHP GD, dunque sotto il tuo controllo, e quindi] priva di codice PHP al proprio interno.
    Intanto grazie della risposta!
    Ho usato GD (imagecreatefrompng() e imagepng()) ma dopo che ho fatto ciò non sò come trattare il file risultante :\

  4. #4
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Chiamando imagepng con due parametri, il file immagine verrà salvato nel percorso indicato dal secondo parametro. A quel punto hai un file immagine pronto e pulito, non dovresti avere bisogno di ulteriori azioni (e, se ne avessi bisogno, puoi applicarle come faresti ad un qualunque file immagine).

    I suggerimenti che do più spesso:


  5. #5
    sestuworld non è connesso Neofita
    Data registrazione
    09-01-2018
    Messaggi
    13

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Chiamando imagepng con due parametri, il file immagine verrà salvato nel percorso indicato dal secondo parametro. A quel punto hai un file immagine pronto e pulito, non dovresti avere bisogno di ulteriori azioni (e, se ne avessi bisogno, puoi applicarle come faresti ad un qualunque file immagine).
    Allora.
    Adesso ho cancellato lo script (erano comunque 3 righe) perchè on andava, ma comunque era qualcosa del tipo:
    $imgname = $_FILE['upload']['tmp_name'];
    $im = @imagecreatefromjpeg($imgname);
    imagejpeg($im , 'img/');
    imagedestroy($im);

    ma non scriveva nulla nella directory...
    Quindi lo avevo eliminato.

  6. #6
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Certo che non scriveva, non gli hai indicato il percorso del file di destinazione :
    Codice PHP:
    imagejpeg($im , 'img/nomefile.jpg');

  7. #7
    Guest

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Certo che non scriveva, non gli hai indicato il percorso del file di destinazione :
    Codice PHP:
    imagejpeg($im , 'img/nomefile.jpg');
    Il percorso è 'img/'. Ok non ho scritto il nome del file, ma ho rimediato e ho copiato la tua riga di codice: nulla.

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Bene, debug time!

    Abilita la stampa di tutti gli errori con
    Codice PHP:
    error_reporting(E_ALL);
    rimuovi l'operatore di soppressione degli errori:
    Codice PHP:
    // $im = @imagecreatefromjpeg($imgname);
    $im = imagecreatefromjpeg($imgname);
    E vediamo che succede. Potrebbe anche essere un banale problema di permessi.
    testwp85 likes this.

    I suggerimenti che do più spesso:


  9. #9
    Guest

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Bene, debug time!

    Abilita la stampa di tutti gli errori con
    Codice PHP:
    error_reporting(E_ALL);
    rimuovi l'operatore di soppressione degli errori:
    Codice PHP:
    // $im = @imagecreatefromjpeg($imgname);
    $im = imagecreatefromjpeg($imgname);
    E vediamo che succede. Potrebbe anche essere un banale problema di permessi.
    Risolto grazie a error_reporting(E_ALL);
    Non conoscevo questa funzione ed è davvero fighissima, mostra proprio tutto.
    Comunque era una stupidata: sto lavorando a più form contemporaneamente e avevo scambiato $_FILES['upload']['tmp_name'] con $_FILES['file inviato']['tmp_name'] e quindi ovviamente mi dava argomento NULL.

    Grazie infinite per l'aiuto!!!

    Domandina: una volta fatta questa procedura, cioè distruggo la vecchia immagine e cambio pure il nome mettendone uno random, l'upload è sicuro o ci sono ancora rogne?

  10. #10
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Credo che già così sia più sicuro della maggior parte dei siti.

    L'unico possibile problema e miglioramento che mi viene in mente è questo: supponiamo che un attaccante trovi il modo di aggirare il tuo script e caricare un file qualsiasi nella tua cartella img/. A quel punto può eseguire codice PHP arbitrario.
    La soluzione consiste nel rendere la cartella img/ inaccessibile dall'esterno, usando .htaccess:
    Codice:
    order deny,allow
    deny from all
    Così facendo, però, anche le immagini valide diventeranno inaccessibili: occorre creare un proxy che permetta di recuperarle. Si tratta di una pagina PHP che intercetterà tutte le richieste di un'immagine, controllerà se l'immagine richiesta è valida, nel senso che è stata sottoposta al tuo script e ha superato i controlli (puoi memorizzare quest'informazione in una base di dati durante il caricamento) e, in caso positivo, la mostra (impostando gli header corretti in modo da avere il MIME type giusto).
    sestuworld likes this.

  11. #11
    sestuworld non è connesso Neofita
    Data registrazione
    09-01-2018
    Messaggi
    13

    Predefinito

    Citazione Originalmente inviato da mzanella Visualizza messaggio
    Credo che già così sia più sicuro della maggior parte dei siti.

    L'unico possibile problema e miglioramento che mi viene in mente è questo: supponiamo che un attaccante trovi il modo di aggirare il tuo script e caricare un file qualsiasi nella tua cartella img/. A quel punto può eseguire codice PHP arbitrario.
    La soluzione consiste nel rendere la cartella img/ inaccessibile dall'esterno, usando .htaccess:
    Codice:
    order deny,allow
    deny from all
    Così facendo, però, anche le immagini valide diventeranno inaccessibili: occorre creare un proxy che permetta di recuperarle. Si tratta di una pagina PHP che intercetterà tutte le richieste di un'immagine, controllerà se l'immagine richiesta è valida, nel senso che è stata sottoposta al tuo script e ha superato i controlli (puoi memorizzare quest'informazione in una base di dati durante il caricamento) e, in caso positivo, la mostra (impostando gli header corretti in modo da avere il MIME type giusto).
    Al mio stato attuale non sono ancora in grado di affrontare cose così complesse, anche perchè mi sono avvicinato da poco nel mondo del "security".
    Ad ogni modo terrò presente questo consiglio per un futuro e ne farò tesoro!

    Grazie davvero infinite per l'aiuto

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •