Indice dei contenuti
Il problema
Abbiamo da poco terminato l'installazione di un sito in PHP (WordPress, Joomla, phpBB, etc.) e stiamo lavorando sui vostri contenuti, quando improvvisamente ci accorgiamo che qualsiasi file inviato tramite upload con gli strumenti di CMS del sito - sia esso una immagine, un video, un pdf da rendere scaricabile agli utenti, etc. - non viene visualizzato o reso disponibile. Nel caso delle immagini, al loro posto compare la classica icona che indica la presenza di un errore; nel caso di qualsiasi altro file, il link rimanda a un errore 500 - Internal Server Error.
Per la precisione, guardando nell'Event Viewer (registro eventi), ci accorgiamo che si tratta di un errore 500.19 - The requested page cannot be accessed because the related configuration data for the page is invalid, il che significa che il nostro server IIS non è stato configurato correttamente.
Il problema è che, per lo meno ad una prima analisi, tutto sembra essere stato impostato nel modo giusto. Il sito consente la navigazione anonima in tutte le pagine e cartelle interessate ed anche le autorizzazioni d'accesso dei file e nelle cartelle sono configurati in modo corretto: tanto l'utente IUSR quanto l'utente IIS_IUSRS risultano infatti correttamente configurati sulle cartelle che contengono le immagini e/o i file che abbiamo inviato tramite upload e che non riusciamo a visualizzare. Al tempo stesso, però, notiamo che i suddetti file non possiedono le autorizzazioni di accesso relative ai suddetti utenti, nonostante queste siano presenti nelle cartelle in cui si trovano: il tutto a dispetto di qualsiasi ereditarietà.
Come mai avviene un problema del genere? E soprattutto, come risolvere?
La spiegazione
Per comprendere le cause del problema è necessario mettere a fuoco il funzionamento di un file upload tramite l'interprete di comandi PHP. In estrema sintesi, tutti i file che inviamo tramite uno script PHP vengono memorizzati temporaneamente all'interno di una cartella apposita presente nel filesystem del Web Server e specificata nel file i configurazione php.ini alla voce upload_tmp_dir . Questa cartella, per impostazione predefinita, è solitamente C:\Windows\Temp e al suo interno "transitano" tutti i file inviati al server tramite PHP prima di essere spostati, al completamento dell'upload, nella cartella di destinazione vera e propria.
Il punto è che la cartella C:\Windows\Temp è solitamente dotata di permessi particolari che consentono all'utente anonimo di IIS (e/o all'utenza dell'Application Pool relativo al sito web) di scrivere, ma non di leggere il proprio contenuto. Questo significa che il file inviato tramite upload viene regolarmente accettato, ma anche che assumerà - per un normale discorso di ereditarietà - un set di permessi inadatto alla sua stessa visualizzazione. Quando, al termine dell'upload, il sistema provvederà a spostarlo nella cartella di destinazione, il file porterà con sé i permessi restrittivi ereditati dalla cartella C:\Windows\Temp che ne impediranno la visualizzazione, provocando l'errore 500.19.
Il workaround
Una volta identificato il problema, la soluzione sembra a portata di mano: è infatti sufficiente impostare sulla cartella C:\Windows\Temp i permessi di lettura ed esecuzione agli utenti IUSR e IIS_IUSRS. In questo modo il file porterà con sé tutti i permessi necessari per la visualizzazione dei suddetti file.
Nonostante l'indubbia efficacia, questo workaround non costituisce a nostro avviso la soluzione ottimale per via delle inevitabili implicazioni di sicurezza legate all'apertura in esecuzione agli utenti anonimi di IIS della cartella C:\Windows\Temp : una cartella particolarmente delicata, in quanto spesso utilizzata dal sistema operativo per immagazzinare temporaneamente eseguibili e script relativi a programmi di installazione, software updates e altri dati rilevanti.
La soluzione
Una risoluzione senz'altro più robusta ed efficace alla problematica in oggetto è la creazione di una cartella apposita da far utilizzare a PHP in luogo di C:\Windows\Temp . A scanso di equivoci, onde evitare di portarsi dietro autorizzazioni scomode o inopportune, consigliamo di creare questa cartella in un folder non controllato dal sistema come ad esempio C:\php\upload_dir\ . Una volta creata, non dovremo fare altro che impostare i permessi di lettura ed esecuzione agli utenti IUSR e IIS_IUSRS e, ovviamente, modificare il file php.ini di conseguenza.
Il risultato che andremo ad ottenere sarà del tutto identico a quello descritto nel workaround di cui sopra senza però alcun impatto sulla sicurezza del nostro sistema.
Felice sviluppo!