Audit del server online: come bloccare l'accesso a .env, .git e backup
Il tuo codice locale è sicuro, ma il server potrebbe mostrare i file nascosti a chiunque. Come testare e chiudere le falle su Apache e Nginx.
Hai appena sistemato il codice in locale: niente chiavi API in chiaro, .env fuori da Git, cronologia pulita. Poi fai il deploy sull’hosting o sul VPS.
Tutto sembra a posto, finché qualcuno non apre https://tuosito.com/.env e scarica le password del database.
È l’errore tipico di chi (spesso con l’IA) cura solo l’app e dimentica l’infrastruttura. C’è differenza tra un segreto nel repository e un segreto servito via HTTP. In questa guida verifichi se il server sta regalando file sensibili e chiudi le porte su Apache (hosting condiviso / Aruba) e su Nginx.
ℹ️ Nota / Prerequisito operativo
Ti servono: il dominio (o staging) online, un browser, e accesso al File Manager/FTP (Apache) oppure SSH al VPS (Nginx). Fai sempre backup di.htaccesso della config Nginx prima di modificare.
La caccia ai segreti nel codice locale resta una lettura opzionale nell’audit di sicurezza gratuito: qui parto dal server già pubblicato.
Il paradosso del .env sicuro a metà
In sviluppo tieni i segreti in .env e lo metti in .gitignore così non finisce su GitHub. Il repo è a posto.
Quando però pubblichi con FTP, File Manager o un rsync dell’intera cartella, quel .env può finire dentro la document root (public_html, www, htdocs). Se Apache/Nginx non negano i file “nascosti” (nome che inizia con .), li trattano come testo normale e li servono a chi ne conosce l’URL.
Stesso discorso per .git/: se la cartella del repository è nella root pubblica, path come /.git/HEAD possono rivelare che il repo è scaricabile (e con tool dedicati spesso si ricostruisce l’intero sorgente).
Passaggio 1 — Checklist URL da provare a mano
Apri una finestra InPrivate / Incognito, vai sul tuo dominio HTTPS e prova questi percorsi (sostituisci tuosito.com):
| Percorso da testare | Rischio | Cosa rivela se accessibile |
|---|---|---|
| /.env Config d'ambiente | Critico | Password DB, chiavi API (Stripe, OpenAI, ecc.), segreti di sessione. |
| /.git/HEAD Repo Git esposto | Critico | Conferma che esiste una cartella .git raggiungibile; spesso prelude al download del sorgente. |
/backup.zip (anche .sql, .bak, dump con nomi ovvi)
Copie di sicurezza
|
Critico | Archivi o dump lasciati nella root da backup manuali o plugin mal configurati. |
| /cartella-senza-index/ Directory listing | Medio | Pagina tipo Index of / con elenco cliccabile dei file se manca un index. |
Esito atteso dopo le chiusure: 403 o 404 (o redirect verso una pagina di errore), non download del file né testo in chiaro né listing.
/.git/HEAD su airiparo.it che risponde 403 Forbidden — niente download né listing del repository.Altri path utili da provare a mano (stesso metodo): /.env.local, /.env.production, /config.php.bak, /wp-config.php.bak, /.DS_Store, /storage/logs/laravel.log (se usi stack che li lasciano in path web). Adatta i nomi al tuo progetto.
Passaggio 2 — Chiudere le falle su Apache (hosting condiviso / Aruba)
Su Aruba, SiteGround, Hostinger e simili il web server è quasi sempre Apache. Non tocchi i file di sistema: lavori sul .htaccess nella document root.
Windows — dove modificare .htaccess
- Accedi al pannello hosting → File Manager (o Gestione file).
- Entra in
public_html/www/ root del dominio. - Attiva “mostra file nascosti” se non vedi
.htaccess. - Backup: scarica una copia sul PC (es.
C:\Users\TUONOME\Desktop\htaccess-backup\.htaccess) prima di modificare. - Alternativa: FileZilla / WinSCP in FTP/SFTP, stessa cartella, scarica → modifica con Blocco note o VS Code → ricarica.
macOS / Linux
Stesso flusso File Manager, oppure SFTP. Backup locale tipico: /Users/tuonome/Desktop/htaccess-backup/ (Mac) o /home/tuonome/... (Linux).
🚨 Avviso critico — Errore 500
Un typo in.htaccesspuò far cadere tutto il sito in 500 Internal Server Error. Tieni il backup a portata di mano e ripristinalo subito se succede.
Aggiungi in cima al .htaccess (dopo aver salvato il backup):
# 1. Blocca file/cartelle nascoste (es. .env, .git) ma LASCIA /.well-known/
# (serve a Let's Encrypt / ACME e ad altri challenge automatici)
RedirectMatch 404 /\.(?!well-known)(.*)$
# 2. Disabilita il directory listing
Options -Indexes
# 3. Blocca download diretti di estensioni tipicamente pericolose in root
# (se servi ZIP legittimi da un path pubblico, togli "zip" o restringi la regola)
Require all denied
Salva, poi ritesta https://tuosito.com/.env e https://tuosito.com/.git/HEAD: dovresti vedere 404 o 403, non il contenuto del file.
💡 Consiglio pratico — 404 vs 403
Nei miei test preferisco rispondere 404 sui path nascosti: non conferma all’attaccante che il file esiste. Un 403 dice «c’è, ma non te lo do». Entrambe le risposte sono meglio del download in chiaro.
ℹ️ Nota —
Options -Indexessu hosting condivisi
Su molti piani funziona; su alcuni l’hosting limitaOptionsnel.htaccess. Se dopo il salvataggio ottieni 500, ripristina il backup e togli solo la rigaOptions -Indexes, poi chiedi al supporto se l’indexing è già disabilitato a livello di server (spesso lo è).Require all deniedrichiede Apache 2.4 (standard oggi); su stack rarissimi 2.2 andrebbeDeny from alldentro un<FilesMatch>legacy.
Verifica anche che https://tuosito.com/.well-known/ non sia stato bloccato per errore (rinnovo certificati).
Passaggio 3 — Chiudere le falle su Nginx (VPS)
Su VPS (Hetzner, DigitalOcean, ecc.) con Nginx, il .htaccess non viene letto. Modifica il blocco server del sito, di solito in /etc/nginx/sites-available/tuosito (il nome del file dipende dalla tua configurazione).
Da Windows (SSH)
- Apri Windows Terminal o Prompt.
- Connettiti:
ssh utente@IP_DEL_SERVER
- Backup e modifica:
sudo cp /etc/nginx/sites-available/tuosito /etc/nginx/sites-available/tuosito.bak
sudo nano /etc/nginx/sites-available/tuosito
Da macOS / Linux
Stessi comandi ssh, cp e nano (o l’editor che preferisci).
Dentro server { ... } aggiungi:
# Directory listing spento
autoindex off;
# Blocca file/cartelle nascoste, eccezione per ACME / .well-known
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
# Blocca estensioni tipiche di dump/backup/script (adatta se servi zip pubblici)
location ~* \.(sql|log|sh|bak|tar\.gz)$ {
deny all;
}
Poi, ancora sul VPS:
sudo nginx -t
Se vedi syntax is ok / test is successful:
sudo systemctl reload nginx
Se nginx -t fallisce, non fare reload: correggi o ripristina il .bak.
Ritesta dal browser gli stessi URL del Passaggio 1.
Il directory listing, in breve
Se visiti una cartella senza index.html / index.php (es. /assets/img/) e compare Index of /, il server sta elencando i file. È informazione gratis per chi mappa il sito: script non linkati, vecchie copie, documenti.
Options -Indexes (Apache) e autoindex off; (Nginx) spegnono questo comportamento. Dopo la modifica, quella URL dovrebbe dare 403/404 (o la tua pagina di errore), non l’elenco.
Cosa fare se hai già trovato un file esposto
- Chiudi subito l’accesso (regole sopra) e sposta backup/dump fuori dalla document root (o cancellali se non servono).
- Se
.envo un dump erano scaricabili, considera le credenziali compromesse: ruota password DB, chiavi API, secret di sessione. - Assicurati che i deploy futuri non copino
.git/.envnella root pubblica (deploy solo della cartelladist/public, o esclusioni rsync/FTP).
Domande Frequenti (FAQ)
Perché un file .env o una cartella .git possono finire scaricabili sul server?
In locale restano “nascosti” al file manager; sul web server la document root è pubblica. Se carichi tutto il progetto (FTP, zip, rsync senza esclusioni) o lasci directory listing attivo, chiunque può richiedere https://tuodominio/.env o .git/config come una pagina qualsiasi.
Come testo se .env, .git o un backup sono esposti?
Dal browser (meglio in finestra privata) prova URL tipici: /.env, /.git/HEAD, /.git/config, /backup.zip, /db.sql, cartelle senza index. Se scarichi contenuto o vedi testo di configurazione, la falla è reale. Annota cosa hai trovato prima di chiudere gli accessi.
Come blocco questi path su Apache (hosting condiviso / Aruba)?
Nella document root usa un .htaccess con Require all denied (o Deny from all su Apache 2.2) per .env, .git e pattern di backup, più Options -Indexes. Dopo il salvataggio ritesta gli stessi URL: devono dare 403/404, non il file.
Come faccio lo stesso blocco su Nginx?
Nella server (o in un location dedicato) rifiuti i path sensibili con return 404; / deny all; e tieni autoindex off;. Ricarica Nginx (nginx -t poi reload) e ripeti i test dal browser.
Cosa faccio se ho già trovato un file esposto con credenziali?
Chiudi subito l’accesso, sposta o cancella i file dalla root pubblica, e ruota password DB, chiavi API e secret di sessione: considera tutto ciò che era scaricabile come compromesso. Nei deploy futuri pubblica solo dist/public, senza .git né .env.
Dopo questo audit
Con .env, .git e listing sotto controllo hai chiuso un buco tipico dei siti vibe-coded messi online “alla svelta”. Il passo successivo, se non l’hai già fatto, è verificare gli header di sicurezza (CSP, HSTS, X-Frame-Options) — guida opzionale: configurare CSP, HSTS e X-Frame-Options.
Due minuti di regole sul server non sostituiscono un codice pulito, ma evitano che un repository “pulito” venga vanificato da un file servito in chiaro.