it-swarm-eu.dev

Rischi di un PHP modulo di caricamento dell'immagine

Il mio cliente desidera un sito di fotografia in cui gli utenti possano caricare le proprie foto in risposta a concorsi fotografici. Anche se tecnicamente questo non è un problema, voglio conoscere i rischi associati a consentire a qualsiasi utente di caricare qualsiasi immagine sul mio server. Ho la sensazione che i rischi siano alti ...

Stavo pensando di usare qualcosa del genere http://www.w3schools.com/php/php_file_upload.asp

Se consento agli utenti anonimi di caricare file, come posso proteggere la directory in cui verranno caricate le immagini (e i file potenzialmente dannosi)?

45
Starkers

La preoccupazione maggiore è ovviamente che gli utenti malintenzionati caricheranno cose che non sono immagini sul tuo server. In particolare, potrebbero caricare file eseguibili o script che tenteranno di indurre il server a eseguire.

Un modo per proteggerlo è assicurarsi che i file non siano eseguibili dopo aver move_uploaded_file In PHP. Questo è semplice come sando chmod() per impostare i permessi 644.

Nota che un utente può comunque caricare PHP o altri script e indurre Apache a eseguirli a seconda della configurazione.

Per evitarlo, chiama getimagesize() sui file dopo che sono stati caricati e determina quale tipo di file sono. Rinomina i file con un nome file univoco e usa la tua estensione . In questo modo, se un utente carica evil.jpg.php, Il tuo script lo salverà come 12345.jpg E non sarà eseguibile. Meglio ancora, il tuo script non lo toccherà nemmeno perché sarà un JPEG non valido.

Personalmente rinomino sempre le immagini caricate nel timestamp corrente da time() o in un UUID. Questo aiuta anche a prevenire nomi di file molto malvagi (come qualcuno che sta cercando di caricare un file che hanno chiamato ../../../../../../../../etc/passwd)

Come ulteriore protezione è possibile utilizzare ciò che a volte è noto come "Image Firewall". Fondamentalmente ciò comporta il salvataggio delle immagini caricate in una directory che è outside la radice del documento e la visualizzazione tramite uno script PHP che chiama readfile() per visualizzarli. Potrebbe essere molto impegnativo ma è l'opzione più sicura.

Una preoccupazione secondaria è che gli utenti caricano troppi file o file troppo grandi, consumando tutto lo spazio su disco disponibile o riempiendo la quota dell'utente di hosting. Questo può essere gestito all'interno del tuo software, inclusa la limitazione della dimensione dei singoli file, della quantità di dati che un utente può caricare, della dimensione totale di tutti i caricamenti, ecc. Assicurati che l'utente amministratore del sito web abbia un modo per gestire ed eliminare questi file.

Non non fare affidamento su nessuno dei dati in $_FILES. Molti siti ti dicono di controllare il tipo mime del file, da $_FILES[0]['type'] O controllando l'estensione del nome file. Non farlo . Tutto sotto $_FILES Ad eccezione di tmp_name può essere manipolato da un utente malintenzionato. Se sai che vuoi che le immagini chiamino solo getimagesize poiché legge effettivamente i dati delle immagini e saprà se il file è veramente un'immagine.

Non non fare affidamento sul controllo del referrer HTTP per qualsiasi sicurezza. Molti siti consigliano di verificare per assicurarsi che il referrer sia il proprio sito per assicurarsi che il file sia legittimo. Questo può essere facilmente simulato.

Per ulteriori informazioni, ecco alcuni buoni articoli:

77
Josh

Consultare https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#File_uploads per alcuni suggerimenti importanti.

getimagesize () può essere indotto a eseguire PHP.

http://www.php.net/manual/en/features.file-upload.php ha un commento utente di CertaiN che fornisce una migliore alternativa a finfo (FILEINFO_MIME_TYPE)

5
Rodney