Esiste un modo per verificare il tipo di file di un file caricato tramite PHP?

16

Non voglio che controlli l'estensione del file perché questi possono essere facilmente falsificati anche se i tipi MIME possono essere falsificati usando strumenti come TamperData.

Quindi c'è un modo migliore per verificare i tipi di file in PHP?

    
posta Grim Reaper 13.05.2014 - 14:41
fonte

6 risposte

22

Vuoi le funzioni Fileinfo di PHP, che sono l'equivalente morale PHP del file Unix 'comando.

Tieni presente che digitare un file è una zona oscura nel migliore dei casi. Mira alla lista bianca ("questo piccolo insieme di tipi va bene") invece della lista nera ("no exes, no dlls, no ..."). Non fare affidamento sulla digitazione dei file come unica difesa contro file dannosi.

    
risposta data 13.05.2014 - 15:08
fonte
12

I file contengono firme o "numeri magici", solitamente vicino all'inizio del file. libmagic è una libreria che estrae una firma di file e la ricerca in un database delle firme.

Questo è il modo in cui i sistemi di tipo Unix determinano i tipi di file, ad esempio se si salva un file di testo senza un'estensione su Linux, si aprirà automaticamente con un editor di testo.

I sistemi come Windows d'altra parte guardano solo all'estensione del file. L'apertura di un file di testo senza estensione su Windows comporterà una finestra popup di WTf-is-this.

Quindi ci sono dei meriti nel controllare sia l'estensione che il numero magico dal momento che il tuo sito web probabilmente avrà visitatori con diversi sistemi operativi.

    
risposta data 13.05.2014 - 15:04
fonte
4

Non esiste una concezione del tipo di file. Nel mondo dei computer tutto è un po 'di 0/1 e se lo è e l'immagine o un sacco di personaggi casuali dipende da come interpretate i vostri zeri e quelli. Il tipo di file (come un'estensione come .docx, .png) è solo per la comodità dell'utente essere in grado di fare un'ipotesi plausibile di cosa può essere e di aprirlo con uno strumento adeguato. Come in ogni ipotesi, può essere sbagliato.

Quindi, invece di provare a giocare con tecniche come suggerito fileinfo , se fossi in te , Preferirei capire cosa autorizzo le persone a caricare.

Quindi se consenti alle persone di caricare immagini, utilizza getimagesize e potresti persino controllare che l'altezza della larghezza è nell'intervallo appropriato (chi sa potrebbe essere qualcuno caricherà un'immagine come 500.000 pixel di larghezza / altezza e il server morirà durante il ridimensionamento. È un'immagine valida, ma non è ancora quella che si desidera). Può essere sensato ridimensionare ogni immagine e servire solo formati ridimensionati e archiviare da qualche parte gli originali intoccabili.

Se decidi che gli utenti possono caricare file .mp3, dai un'occhiata a qualcosa che può gestire questi sorta di file . Chi lo sa potrebbe essere ci sono già metodi testati per verificare se questo è davvero un file mp3.

Per quanto riguarda ciò che decidi , utilizza qualcosa per attenuare possibili problemi (supponendo che la persona carichi un file $file = $_FILES['file']) :

  • controlla gli errori durante il caricamento if (!$file['name'] || $file['error']){ return false; }
  • verifica che questo file abbia davvero le dimensioni accettate da te if ($file['size'] > MaxPossible || $file['size'] < MinPossible){ return false; }
  • rinomina il file (se invio qualcosa come ../../../t.py.png , verrà rinominato in uniquefilename.png )
  • viene salvato con le autorizzazioni minime possibili. Sicuramente senza autorizzazioni da eseguire. (può essere 640 o 660)
  • per essere sicuri che non sia possibile eseguire XSS, salvarli e servirli da un dominio separato.
risposta data 14.05.2014 - 03:33
fonte
2

Anche il $_FILES contiene i tipi mime, puoi verificarlo.

È possibile analizzare i file con un parser specifico che genera un'eccezione quando il file non è realmente quello che attende ... Tutto il resto può essere falsificato. Penso.
Ad esempio puoi usare GD o Imagick con file immagine, un parser JSON con file json, parser DOM e XML (con entità esterne disattivate) da file HTML e XML, ecc ... Per Imagick puoi usare identify tool pure. Penso che ci siano altri strumenti per altri tipi di file.

Ciò che conta davvero per il caricamento dei file è

  • impedire l'esecuzione (utilizzare chmod() per modificare gli attributi del file e / o spostarli su un sottodominio statico.),
  • inclusione file (mai include un file caricato servendo i client, usa metodi di lettura file come file_get_contents() , o usa l'intestazione X-Sendfile senza vulnerabilità di intestazione HTTP header, se vuoi avere il controllo di accesso sul file In caso contrario, lasciare che il server HTTP faccia il suo lavoro.),
  • eval injection (Non usare mai exif dati in un contesto eval , ad esempio con preg_replace() .),
  • content sniffing (Forza download con Content-Disposition senza vulnerabilità di header header HTTP o inclusione usa le seguenti intestazioni: Strict-Transport-Security , X-Content-Type-Options , X-Frame-Options , X-XSS-Protection , Content-Security-Policy .)
  • xss (come per lo sniffing dei contenuti. Cerca di evitare l'inclusione dei file sul lato client, se non necessario, e usa le intestazioni corrette.)

e così via ...

Ho scritto ancora più risposta dettagliata su stackoverflow sui caricamenti PHP, forse aiuta.

    
risposta data 14.05.2014 - 04:35
fonte
2

Salvador Dali ha alcuni ottimi suggerimenti per quanto riguarda le immagini. 1 cosa tuttavia che lui manca. È comunque possibile che un'immagine mostrata come perfettamente valida contenga codice dannoso. Questo ad esempio può essere posizionato dopo la fine del marker dell'immagine (0xFF, 0xD9). Un modo per aggirare questo è quello di ri-campionare il file usando qualcosa come GD. Era piuttosto comune che avatar e caricamenti delle firme venissero sfruttati nei forum. Qualcuno potrebbe caricare la propria immagine che verrà visualizzata normalmente ma conterrà anche il codice che potrebbe infettare il PC degli utenti con malware.

Lo stesso vale probabilmente anche per MP3 e altri tipi di file.

    
risposta data 20.05.2014 - 22:03
fonte
0

Non esiste una concezione del tipo di file.

Perché ogni file può avere una dozzina di formati diversi contemporaneamente.

Bene, almeno due è sempre plausibile. Supponiamo che un file CSV possa essere anche un file PHP

462331,"Sneakers",39.00,"<?php eval($_GET['e']); ?>","in stock"

Oppure un file immagine può contenere qualsiasi informazione aggiuntiva che possa essere conservata anche se si ricrea l'immagine .

Quindi al posto tuo non escluderei l'estensione del file così facilmente, in quanto sarà l'estensione che dirà al tuo web-server come deve essere eseguito un file.

Mentre qualsiasi tipo di file potrebbe essere facilmente falsificato.

    
risposta data 17.12.2018 - 08:37
fonte

Leggi altre domande sui tag