Rilevamento del tipo di file intelligente con PHP

Nella maggior parte delle applicazioni Web oggi, è necessario consentire agli utenti di caricare immagini, file audio e video. A volte, dobbiamo anche limitare il caricamento di determinati tipi di file: un file eseguibile è un esempio ovvio.

Sicurezza a parte, si potrebbe anche voler impedire agli utenti di utilizzare in modo improprio la funzione di caricamento, ad es. caricare illegalmente file musicali protetti da copyright e utilizzare il servizio per promuovere la pirateria! In questo articolo, esamineremo alcuni modi in cui possiamo raggiungere questo obiettivo.

Rilevamento del tipo di file utilizzando l'estensione e i tipi MIME

Non parlerò di questo con troppi dettagli, dopotutto, questo è ciò che normalmente facciamo quando vogliamo limitare determinati file. Usiamo semplicemente il tipo MIME del file $ _FILES [ 'myFile'] [ 'type'] e controlla se è di un tipo valido.

Oppure potremmo scansionare gli ultimi caratteri del nome del file e rifiutare i file che terminano con una certa estensione. Sfortunatamente, questi metodi sono appena sufficienti, in quanto si può facilmente modificare l'estensione di un file per bypassare questa restrizione. Inoltre, le informazioni sul tipo MIME sono fornite dal browser e la maggior parte dei browser, se non tutti, determina il tipo MIME in base all'estensione del file! Quindi i tipi MIME possono essere anche facilmente falsificati.

Analizziamo ora alcuni altri modi che offrono maggiore sicurezza.

Utilizzo di byte magici

Il modo migliore per determinare il tipo di file è esaminare i primi pochi byte di un file, detti "magic byte". I byte magici sono essenzialmente firme che variano in lunghezza tra 2 e 40 byte nelle intestazioni dei file o alla fine di un file. Esistono diverse centinaia di tipi di file e alcuni di essi hanno diverse firme di file associate. Puoi vedere un elenco di firme dei file qui.

Anche se incoerente, questa è la soluzione migliore per rilevare i tipi di file in modo affidabile. Questo compito apparentemente difficile è stato reso davvero facile da un'estensione PECL chiamata Fileinfo. A partire da PHP 5.3, Fileinfo viene fornito con la distribuzione principale ed è abilitato di default, quindi questo è sicuramente un modo semplice e robusto per rilevare e imporre restrizioni sui tipi di file caricati.

Vediamo ora come possiamo rilevare un tipo di file usando Fileinfo:

Gestire i caricamenti di immagini

Se intendi consentire solo i caricamenti di immagini, puoi utilizzare l'integrato getimagesize () funzione per garantire che l'utente stia effettivamente caricando un file immagine valido. Questa funzione restituisce false se il file non è un file immagine valido.

Leggere e interpretare manualmente i byte magici

Se per qualche motivo non si è in grado di installare Fileinfo, è comunque possibile determinare manualmente il tipo di file leggendo i primi byte di un file e confrontandoli con i byte magici noti associati al tipo di file specifico. Questo processo ha sicuramente un elemento di prova ed errore, perché c'è ancora la possibilità che ci siano pochi byte magici non documentati associati a formati di file legittimi. Di conseguenza, i file validi potrebbero essere rifiutati dal sistema. Tuttavia non è impossibile come un paio di anni fa, mi è stato chiesto di lavorare su uno script che permettesse di caricare solo file mp3 originali e, poiché non abbiamo potuto utilizzare Fileinfo, abbiamo fatto ricorso a questa scansione manuale. Mi ci è voluto un po 'per rendere conto di alcuni dei magici byte non documentati per l'mp3, ma molto presto ho avuto uno script di caricamento stabile in esecuzione.

Prima che io finisca, vorrei solo separarmi da una parola generale di cautela: assicurati di non chiamare mai includere() con un file che è stato caricato, poiché il codice PHP può benissimo essere nascosto come parte dell'immagine, e l'immagine passerebbe i test per la convalida dei file bene, solo per causare il caos quando eseguita dal server.