Situazione attuale: PHP2Shell. Due vulnerabilità critiche di PHP (CVSS 9,2) consentono codice dannoso senza autenticazione. Patch dal 21/10/2026.Che cosa fare ora →

Proteggere correttamente credenziali e file .env

Come proteggere nei progetti PHP password del database, chiavi API e altri segreti: file .env fuori dal webroot, blocchi nel server web, permessi stretti e sostituzione ordinata dopo un incidente.

Stato 6 min di letturaSviluppo sicuro

In breve: il file .env si protegge facendo in modo che non si trovi affatto nella directory raggiungibile pubblicamente: il webroot punta a una sottocartella come public/, la configurazione sta un livello più in alto. In aggiunta il server web blocca tutti i file con il punto iniziale, il file è leggibile solo dal proprietario e dal processo PHP e non finisce mai nel repository Git. Dopo un'intrusione tutte le credenziali in esso contenute si considerano note e vanno sostituite.

Il file con le chiavi di casa

I progetti PHP moderni archiviano volentieri i propri segreti in un file chiamato .env: password del database, accesso al server di posta, chiavi API per servizi di pagamento e spedizione, la chiave con cui l'applicazione firma i cookie. Framework come Laravel e Symfony usano questo schema, e molti sviluppi propri lo hanno adottato.

L'idea è buona: configurazione e codice sono separati e ogni ambiente riceve valori propri. Diventa pericoloso quando il file finisce nella directory sbagliata. Se si trova nel webroot e il server web non lo blocca, basta una sola chiamata nel browser per leggere tutti gli accessi in un colpo.

A ciò si aggiungono varianti con altri nomi: .env.local, .env.production, config.local.php o file con credenziali per servizi di archiviazione. Ciò che qui è descritto per .env vale per tutti i file in cui compaiono segreti.

Tali file vengono cercati di continuo da scanner automatizzati. Non è una specialità di singoli aggressori, ma rumore di fondo di Internet, simile alle scansioni di massa alla ricerca di versioni PHP non aggiornate.

Dove dovrebbe stare il file .env

La misura più efficace è strutturale: il server web deve fornire solo la cartella che deve essere davvero pubblica. In Laravel e Symfony è la cartella public/. Tutto il resto, cioè codice, configurazione, log e .env, sta più in alto e non è affatto indirizzabile tramite HTTP.

/srv/www/shop/
├── .env              ← non raggiungibile
├── config/
├── src/
├── vendor/
└── public/           ← unica web root
    ├── index.php
    └── assets/

Nella pratica il webroot punta comunque spesso alla directory del progetto stessa, ad esempio perché un pannello di hosting lo impone o perché in un trasloco un percorso non è stato adattato. Verifichi quindi nella configurazione del server web o nel pannello dove puntino root o DocumentRoot.

Proteggere il file .env: il blocco nel server web come seconda linea

Se il webroot non si può modificare, o se vuole una protezione aggiuntiva, blocchi i file nascosti nel server web. La cartella .well-known deve restare raggiungibile, perché serve, tra l'altro, al rilascio dei certificati.

# Bloccare tutti i file e le cartelle con il punto iniziale, tranne .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
# Bloccare i file con il punto iniziale
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

Una risposta 404 anziché 403 non rivela che il file esiste. Se il blocco funzioni lo verifica dall'esterno:

# Atteso: 403 o 404, mai 200
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.example
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.bak

Le ultime due righe non sono un caso: copie come .env.bak o .env.old nascono durante i lavori di manutenzione e spesso vengono dimenticate. Altro su questi residui si trova in File di backup nel webroot.

Permessi, Git e gestione delle copie

Anche fuori dal webroot vale il principio dei privilegi minimi. Una ripartizione collaudata:

  1. Proprietario è l'utente di deploy, non il processo PHP.
  2. Gruppo è il gruppo del pool PHP-FPM, che può solo leggere; permessi 640.
  3. Nessun accesso in scrittura per il processo PHP. Un'applicazione non deve poter modificare le proprie credenziali.
  4. Nessun valore reale nel repository: si committa solo .env.example con segnaposto, il file vero sta in .gitignore.
  5. Valori separati per ambiente: sviluppo, staging e produzione usano accessi diversi, affinché una fuga in un ambiente di test non apra la produzione.
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Verificare se il file sia mai stato committato
git log --all --oneline -- .env

Faccia attenzione anche alle pagine di errore. Nella modalità debug i framework mostrano in parte variabili d'ambiente e valori di configurazione; su un sistema di produzione questa modalità deve essere disattivata. La verifichi dopo ogni deployment, perché un valore sbagliato nello stesso .env può riattivarla.

Se l'ultimo comando dà risultati, le credenziali sono nella cronologia di Git e si considerano rivelate, anche se oggi il file manca. Perché ciò sia particolarmente delicato se la cartella .git si trova sul server lo descrive Cartella .git pubblica: una fuga di dati sottovalutata. I fondamenti sui permessi li spiega la guida Permessi dei file sul server web.

Importante

I file di test con phpinfo() mostrano le variabili d'ambiente. Chi passa i segreti come variabili d'ambiente li rivela tramite un file di test dimenticato. Le informazioni di fondo si trovano in File phpinfo(): perché devono sparire.

Dopo un'intrusione: sostituire le credenziali

Nessun blocco protegge da un aggressore che esegue già codice sul server. Un processo PHP deve poter leggere la propria configurazione, quindi può farlo anche il codice iniettato nello stesso processo. Dopo PHP2Shell vale quindi: se un'intrusione non si può escludere, tutte le credenziali sul server vanno trattate come note.

Una sostituzione ordinata comprende password del database, accessi di posta e SMTP, chiavi API di servizi esterni, chiavi di firma dell'applicazione e accessi a servizi di archiviazione. Ordine e momento dovrebbero essere pianificati: chi sostituisce prima e poi bonifica il server rischia di consegnare subito all'aggressore anche i nuovi valori.

Il danno di una fuga si limita già prima facendo sì che ogni segreto possa fare solo ciò che serve. L'utente del database del sito non ha bisogno di diritti su altri database. Le chiavi API di servizi esterni presso molti fornitori si possono limitare a singole funzioni o indirizzi mittente, ad esempio creare spedizioni ma non disporre pagamenti. E ogni applicazione riceve accessi propri, anziché far condividere a più siti lo stesso account di posta o la stessa chiave. Allora una fuga riguarda un ambito chiaramente delimitato e la sostituzione resta gestibile.

Negli ambienti container il file .env non va né nell'immagine né in un registry raggiungibile pubblicamente. Lo escluda tramite .dockerignore e passi i segreti solo in fase di esecuzione, con i meccanismi della piattaforma.

A lungo termine vale la pena guardare agli archivi centrali di segreti, come li raccomanda OWASP: segreti in un unico luogo, con registro degli accessi, sostituzione regolare e validità il più breve possibile.

Come aiuta concretamente PHP SOS?

  • Verifichiamo dall'esterno se file di configurazione, copie e file nascosti dei suoi siti sono richiamabili.
  • Adattiamo webroot, blocchi del server web e permessi dei file in modo che i segreti non siano più raggiungibili via HTTP.
  • Verifichiamo repository e deployment alla ricerca di credenziali committate.
  • Dopo un incidente pianifichiamo e accompagniamo la sostituzione di tutti gli accessi interessati nell'ordine corretto.

Questi lavori fanno parte del nostro hardening del server per server web PHP.

Domande frequenti

Un file .env nel webroot è automaticamente pubblico?

Non automaticamente, ma spesso sì. Se sia richiamabile dipende dalla configurazione del server web. Molte configurazioni predefinite proteggono solo i file .htaccess, non altri file con il punto iniziale. Un test con curl fa chiarezza.

Le variabili d'ambiente sono più sicure di un file .env?

Non in linea di principio. OWASP segnala che le variabili d'ambiente sono leggibili da tutti i processi dell'utente e possono comparire nei log o negli snapshot di memoria. Evitano però un file nel webroot. Meglio gli archivi centrali di segreti, dove l'ambiente li supporta.

Che cosa fare se il file .env era richiamabile?

Considerare note tutte le credenziali in esso contenute e sostituirle: database, posta, API, servizi di pagamento, chiavi dell'applicazione. Poi verificare nei log di accesso se il file è stato richiamato e, in presenza di dati personali, coinvolgere il responsabile della protezione dei dati.

Il file .env va nel repository Git?

No. Nel repository va al massimo un modello senza valori reali, ad esempio .env.example. Il file vero viene escluso tramite .gitignore e reso disponibile separatamente sul server.

phpinfo() può rivelare delle credenziali?

Sì. phpinfo() mostra, tra l'altro, variabili d'ambiente e variabili del server. Se lì ci sono segreti, vengono emessi anch'essi. I file di test con phpinfo() non devono quindi mai stare su un sistema raggiungibile.

Fonti

Contatto immediato

Ogni ora conta. Ci scriva adesso.

Descriva brevemente sistema, versione di PHP e quanto osservato. Ci faremo sentire, chiariremo la situazione e lavoreremo da remoto fino alla chiusura e alla documentazione dell'incidente.

Aiuto immediato