Sicurezza di siti e app IA

Audit del server online: come bloccare l'accesso a .env, .git e backup

8 min di lettura
Laptop su scrivania scura: browser con 403 Forbidden su https://example.com/.env e percorsi .git/backup bloccati
Windows macOS Linux
Immagine generata: Alex Lunalbi · Gemini · ai riparo

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 .htaccess o 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.

Browser con 403 Forbidden su airiparo.it/.git/HEAD: accesso al repository Git bloccato
Esempio di esito corretto: richiesta a /.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

  1. Accedi al pannello hosting → File Manager (o Gestione file).
  2. Entra in public_html / www / root del dominio.
  3. Attiva “mostra file nascosti” se non vedi .htaccess.
  4. Backup: scarica una copia sul PC (es. C:\Users\TUONOME\Desktop\htaccess-backup\.htaccess) prima di modificare.
  5. 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 .htaccess può 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 -Indexes su hosting condivisi
Su molti piani funziona; su alcuni l’hosting limita Options nel .htaccess. Se dopo il salvataggio ottieni 500, ripristina il backup e togli solo la riga Options -Indexes, poi chiedi al supporto se l’indexing è già disabilitato a livello di server (spesso lo è). Require all denied richiede Apache 2.4 (standard oggi); su stack rarissimi 2.2 andrebbe Deny from all dentro 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)

  1. Apri Windows Terminal o Prompt.
  2. Connettiti:
ssh utente@IP_DEL_SERVER
  1. 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

  1. Chiudi subito l’accesso (regole sopra) e sposta backup/dump fuori dalla document root (o cancellali se non servono).
  2. Se .env o un dump erano scaricabili, considera le credenziali compromesse: ruota password DB, chiavi API, secret di sessione.
  3. Assicurati che i deploy futuri non copino .git / .env nella root pubblica (deploy solo della cartella dist / 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.

Alex Lunalbi

Alex Lunalbi

Security & privacy

Dona su PayPal

Scrivo di sicurezza digitale pratica e codice IA. Su ai riparo ogni procedura è verificata su macchine reali.

Tag
  • sicurezza,
  • server,
  • audit,
  • hosting,
  • vibe coding