Permessi dei file WordPress: 644, 755 e proprietario
Permessi dei file WordPress: cosa significano 755 e 644, chi deve essere proprietario, come ripristinarli in sicurezza e perché 777 non risolve gli errori di upload.
Anche in: English Deutsch Français Español Polski Português Türkçe
Permessi dei file WordPress: l'impostazione sicura in un paragrafo
Per i permessi dei file WordPress, l'impostazione sicura è 755 per le directory, 644 per i file e un più restrittivo 640 o 600 per wp-config.php. Mai 777. Questi numeri, però, proteggono solo se i file appartengono all'utente giusto. Un 644 perfetto su file intestati all'account sbagliato blocca upload e aggiornamenti oppure, senza che nessuno se ne accorga, concede al web server più potere del necessario. Prima di modificare i permessi, quindi, leggere la sezione sul proprietario.
Proprietario, gruppo e altri: come leggere 755 e 644
Eseguendo ls -l nella root di WordPress si ottengono righe come queste:
drwxr-xr-x 5 deploy www-data 4096 Oct 30 09:12 wp-content
-rw-r--r-- 1 deploy www-data 405 Oct 30 09:12 index.php
-rw-r----- 1 deploy www-data 3214 Oct 30 09:12 wp-config.php
Il primo carattere indica il tipo (d per directory, - per file). Seguono tre gruppi di tre lettere: uno per il proprietario (deploy), uno per il gruppo (www-data) e uno per tutti gli altri. r sta per lettura (read), w per scrittura (write), x per esecuzione (execute). A ogni lettera corrisponde un valore: r = 4, w = 2, x = 1. Sommandoli per ciascun gruppo si ottiene la modalità ottale: rwxr-xr-x diventa quindi 7-5-5.
Su una directory, x significa «può entrare». Senza, PHP non riesce ad aprire i file al suo interno, anche se sono leggibili. Per questo le directory richiedono 755 e i file bastano a 644. In un'installazione WordPress normale nessun file ha bisogno del bit di esecuzione.
| Modalità | Lettere | Uso tipico |
|---|---|---|
| 755 | rwxr-xr-x | Directory |
| 644 | rw-r--r-- | File normali |
| 640 | rw-r----- | wp-config.php, utente PHP nel gruppo |
| 600 | rw------- | wp-config.php, utente PHP proprietario |
Il proprietario conta quanto la modalità
Per prima cosa bisogna capire con quale utente gira PHP. Sul proprio server si controllano i processi in esecuzione:
ps -eo user,comm | grep -E 'php-fpm|apache2|httpd' | sort | uniq
Con PHP-FPM il processo master gira come root, mentre i worker girano con l'utente del pool, definito nel relativo file di configurazione. Su Debian e Ubuntu di solito si trova in /etc/php/<versione>/fpm/pool.d/:
grep -R -E '^(user|group) *=' /etc/php/*/fpm/pool.d/
Queste impostazioni sono descritte nella documentazione di configurazione di PHP-FPM. Con Apache e mod_php, PHP gira direttamente come utente Apache: www-data su Debian/Ubuntu, apache sui sistemi basati su RHEL. In quel caso tutti i siti del server condividono la stessa identità. Un buon hosting condiviso isola invece i siti: il PHP di ogni account gira con l'utente di quell'account. Se non è possibile eseguire ps, si può consultare Strumenti > Salute del sito > Info > Permessi del filesystem, che mostra se WordPress può scrivere nella directory principale, in wp-content, negli upload, nei plugin e nei temi.
Una volta individuato l'utente PHP, si sceglie tra due modelli di proprietà.
Modello A: l'utente PHP possiede tutto. È tipico dell'hosting condiviso con account isolati, dove l'utente dell'account e l'utente PHP coincidono. Aggiornamenti dalla bacheca, installazione di plugin e upload funzionano senza problemi. Lo svantaggio è che qualsiasi codice eseguito come PHP può riscrivere ogni file, compresi core, plugin e wp-config.php.
Modello B: un utente di deploy possiede i file e PHP si limita a leggerli. I file appartengono a un utente come deploy:www-data, con 755/644. PHP legge tutto, ma scrive solo dove lo si consente: wp-content/uploads ed eventuali directory di cache. Gli aggiornamenti si fanno con WP-CLI o SFTP come utente di deploy, non dalla bacheca. Si limitano così i danni, a costo di un po' più di lavoro. Chi vuole anche bloccare definitivamente la bacheca può leggere DISALLOW_FILE_MODS e i suoi compromessi.
Il Modello B chiarisce un enigma frequente: WordPress che chiede le credenziali FTP quando si clicca su «Aggiorna». WordPress verifica se i file che crea avrebbero lo stesso proprietario dei propri file; in caso contrario, ripiega su FTP. Forzare FS_METHOD su direct nasconde il sintomo senza eliminare la causa. Conviene decidere quale modello si vuole e impostare di conseguenza il proprietario.
Come ripristinare i permessi dei file WordPress in sicurezza
Prima di tutto, un backup di file e database. Poi ci si sposta nella root di WordPress e si verifica di essere nel posto giusto:
cd /var/www/example.com/public
ls wp-config.php
Se ls non trova wp-config.php, fermarsi. (Alcune configurazioni tengono il file un livello sopra la web root, quindi conviene controllare la propria struttura.) Quindi si ripristinano le modalità:
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
Sui siti di grandi dimensioni la variante con + è molto più veloce, perché passa molti file a ogni chiamata di chmod:
find . -type d -exec chmod 755 {} +
find . -type f -exec chmod 644 {} +
Il proprietario va modificato solo su un server che si controlla. Per il Modello B il comando è questo:
sudo chown -R deploy:www-data /var/www/example.com/public
Il ripristino cancella anche le eccezioni descritte più avanti, che vanno quindi riapplicate subito. Poi si verifica il risultato con stat -c '%a %U:%G %n' wp-config.php wp-content/uploads, si carica un'immagine di prova e si aprono alcune pagine.
Eccezioni: wp-config.php, upload e .htaccess
wp-config.php contiene la password del database, quindi «altri» non deve avere alcun permesso. Si usa 600 se il proprietario del file è l'utente PHP (Modello A) e 640 se il proprietario è un utente di deploy e PHP legge il file tramite il gruppo (Modello B). Con 600 nel Modello B, PHP non riesce a leggere il file e il sito va offline. Per salt, impostazioni di debug e copie di backup dimenticate, vedere l'hardening di wp-config.php.
wp-content/uploads e le directory di cache devono essere scrivibili dall'utente PHP. Nel Modello B si rende l'utente PHP proprietario di quelle directory, oppure le si lascia al gruppo PHP con permesso di scrittura per il gruppo (775 per le directory, 664 per i file). Il permesso di scrittura va limitato a questi percorsi, non esteso a tutto wp-content.
Su Apache, .htaccess è un caso particolare. Se è scrivibile, WordPress aggiorna le regole di rewrite quando si salvano i permalink, e i plugin di cache o sicurezza aggiungono i propri blocchi. Se non lo è, WordPress mostra le regole da incollare a mano. Un .htaccess in sola lettura costa un po' di comodità, ma in cambio il codice eseguito come PHP non può aggiungervi un redirect o una riga auto_prepend_file.
Perché 777 non risolve mai un errore di upload
777 permette a ogni account e a ogni processo del server di scrivere sul file o sulla directory. Su un hosting condiviso possono esserci anche gli script compromessi di altri clienti. L'errore di upload può sparire, ma solo perché si è tolta la protezione, non perché se ne sia rimossa la causa. Le cause reali vanno controllate in quest'ordine:
- Proprietario sbagliato. Il messaggio «Impossibile creare la directory wp-content/uploads/… La directory superiore è scrivibile dal server?» indica quasi sempre che l'utente PHP non è proprietario di uploads o non può scriverci. Succede spesso dopo una migrazione o un ripristino eseguiti come root.
- Disco o quota esauriti. Sul proprio server si controlla
df -h, altrimenti la quota nel pannello dell'hosting. - Directory temporanea o limiti di percorso. «Manca una cartella temporanea» rimanda a
upload_tmp_dir. Anche una restrizioneopen_basedirche esclude il percorso temporaneo può bloccare gli upload. - Limiti di dimensione. «Il file caricato supera la direttiva upload_max_filesize» significa che bisogna aumentare
upload_max_filesizeepost_max_size, oppure caricare un file più piccolo.
Su un hosting condiviso di solito non si può eseguire chown in autonomia. Si chiede al fornitore di impostare sull'account il proprietario corretto: è una richiesta di routine.
Da cosa i permessi corretti non proteggono
I permessi limitano ciò che un utente può fare. Non servono a nulla contro il codice che è già in esecuzione come quell'utente. Se un plugin vulnerabile consente a un aggressore di eseguire PHP, il suo codice ha i diritti dell'utente PHP. Nel Modello A significa tutto. Nel Modello B significa comunque upload, directory di cache e qualsiasi altro percorso reso scrivibile. Per questo gli aggressori preferiscono uploads, come spiegato in web shell in wp-content/uploads.
Ripristinare i permessi dopo un attacco, inoltre, non elimina una backdoor: il file malevolo è ancora lì, solo con modalità in ordine. Prima si segue un piano di rimozione del malware, poi si sistemano i permessi nella fase di hardening. Ai sensi del GDPR, permessi corretti possono rientrare tra le misure tecniche che tutelano l'integrità e la riservatezza dei dati personali (art. 32, EUR-Lex), ma funzionano solo come parte di un insieme più ampio di misure.
Controllare i permessi con regolarità
I permessi tendono a derivare nel tempo. Le cause abituali sono migrazioni, ripristini di backup, cambi di hosting e una correzione veloce con sudo. Dopo ognuno di questi eventi, e comunque ogni qualche mese, conviene eseguire questi due controlli dalla root di WordPress:
find . -perm -o+w ! -type l
find . ! -user deploy
Il primo comando elenca tutto ciò che è scrivibile da chiunque (i link simbolici sono esclusi perché risultano sempre 777). Il secondo elenca i file il cui proprietario non è quello previsto. Nel Modello A si sostituisce deploy con l'utente PHP. Entrambi dovrebbero restituire un elenco vuoto, oppure solo percorsi che si è in grado di spiegare. La guida ai permessi dei file di WordPress.org descrive la stessa impostazione di base dal punto di vista del team del core.
Per tenere sotto controllo il quadro generale, il plugin Security Audit & Compliance di secaudit.eu esegue verifiche di hardening e di configurazione insieme al monitoraggio dell'integrità dei file, così i file modificati o nuovi emergono anche tra un controllo manuale e l'altro → secaudit.eu
FAQ
wp-config.php deve essere 400 o 440?
Va bene anche così, purché PHP riesca ancora a leggere il file: 400 se PHP è il proprietario, 440 se lo legge tramite il gruppo. Il rovescio della medaglia è che per modificare il file bisogna prima ripristinare la modalità. Il compromesso abituale è 600 o 640.
755/644 è sicuro su un hosting condiviso?
Sì, se il fornitore isola gli account in modo che il PHP giri con il proprio utente. Con 644 altri account potrebbero, in teoria, leggere i file. Un isolamento corretto lo impedisce: per questo l'impostazione dell'hosting conta più delle cifre.
Devo ripristinare i permessi dopo ogni aggiornamento?
No. WordPress crea i nuovi file con modalità adeguate. Meglio eseguire i controlli descritti sopra e ripristinare solo se emergono problemi.
Controlla il tuo sito
Security Audit & Compliance è il plugin WordPress di secaudit.eu: cerca malware, spam nascosto, file core modificati e codice vulnerabile, e collega i risultati all’art. 32 del GDPR, all’art. 21 della NIS2 e alla OWASP Top 10.
Scopri cosa controlla il plugin