# Cartella .git pubblica: una fuga di dati sottovalutata

> La sua cartella .git è pubblica? Come verificarlo, bloccare l'accesso, modificare il deployment e trattare le credenziali presenti nella cronologia.

Fonte: https://phpsos.de/it/blog/git-ordner-oeffentlich/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**In breve:** una cartella .git pubblica nasce quando un sito viene distribuito con `git clone` o `git pull` direttamente nel webroot e il server web non blocca le cartelle nascoste. Si può allora richiamare l'intero codice sorgente con la cronologia delle versioni, comprese le credenziali committate in passato. Verifichi i suoi domini con una semplice chiamata, blocchi subito l'accesso, passi il deployment a pacchetti senza `.git` e sostituisca le credenziali presenti nella cronologia.

## Il codice sorgente da portare via

Git è lo strumento standard per il controllo di versione e per i piccoli team è ovvio usarlo anche per la distribuzione: collegarsi al server, `git pull`, fatto. Funziona in modo affidabile ed è rapido. Ha però un effetto collaterale che spesso nessuno nota.

Nella cartella del progetto c'è una cartella nascosta `.git`. Contiene non solo lo stato attuale, ma ogni file in ogni versione mai committata, oltre a messaggi di commit, nomi e indirizzi e-mail degli sviluppatori e riferimenti a server. Se questa cartella si trova nel webroot e il server web la fornisce, chiunque può richiamarla.

Per gli aggressori è un regalo. Con il codice sorgente si possono cercare le vulnerabilità in modo mirato, anziché indovinarle dall'esterno. E nella cronologia si trovano spesso cose che sembravano cancellate da tempo: una password del database dei primi tempi, una chiave API, un file di test con dati dei clienti.

## La sua cartella .git è pubblica? Come verificarlo

La verifica richiede pochi secondi e non modifica nulla. Per ogni dominio e sottodominio richiami un file che esiste in ogni repository Git:

```bash
# Atteso: 403 o 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/config
# Sul server: esistono cartelle .git sotto i webroot?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
```

Uno stato 200 significa: la cartella è raggiungibile. Faccia attenzione anche alle sottodirectory. A volte il repository non si trova nel webroot stesso, ma in una cartella di plugin o tema curata separatamente con Git.

Verifichi inoltre gli ambienti di staging e di test. Vengono aggiornati con Git più spesso della produzione e sono spesso raggiungibili con sottodomini indovinabili.

## Subito: bloccare l'accesso

Finché il deployment non è modificato, una regola nel server web blocca l'accesso alle cartelle del controllo di versione. Un blocco generale per i file nascosti, come descritto in [Proteggere correttamente credenziali e file .env](https://phpsos.de/it/blog/env-dateien-schuetzen/), lo copre. Chi vuole bloccare mirando solo al controllo di versione usa una regola più stretta:

```nginx
location ~ /\.(git|svn|hg)(/|$) {
    return 404;
}
```

```apache
RedirectMatch 404 /\.(git|svn|hg)(/|$)
```

Poi ripeta la verifica sopra, con una vera chiamata dall'esterno: un test di configurazione riuscito dice solo che la sintassi è corretta, non che la regola abbia effetto prima di altre regole per i file statici. Con pannelli come Plesk o cPanel inserisca la regola nelle direttive aggiuntive previste, affinché non vada persa alla prossima generazione della configurazione.

> **Agire subito:**
> Se la cartella era raggiungibile, tratti come note tutte le credenziali che sono mai state nel repository. Il solo blocco allora non basta, i valori vanno sostituiti.

## In modo duraturo: distribuire senza .git nel webroot

Il blocco è una protezione, non una soluzione. In modo duraturo il controllo di versione non appartiene al server di produzione. Strade collaudate, a seconda del suo ambiente:

| Procedimento | Come funziona | Adatto per |
|---|---|---|
| Pacchetto di build dalla CI | La pipeline costruisce un archivio senza `.git`, il server lo estrae in una nuova directory di release | Team con CI/CD |
| `git archive` | Genera un archivio di uno stato senza dati di versione | Piccoli progetti senza pipeline |
| `rsync` con esclusioni | Trasferisce solo i file necessari | Server classici |
| Immagine container | Il codice viene copiato nell'immagine durante la build, `.git` escluso con `.dockerignore` | Esercizio con container |

Una directory di release per versione con un collegamento simbolico allo stato attuale ha un altro vantaggio: in caso di problemi si può tornare indietro subito. Per le configurazioni con container, [CI/CD: ricostruire automaticamente le immagini PHP](https://phpsos.de/it/blog/php-images-in-ci-neu-bauen/) descrive come rendere riproducibili le build. Lì si dovrebbe anche verificare che `.git` non finisca nell'immagine.

```bash
# Esempio: generare un pacchetto di uno stato senza dati di versione
git archive --format=tar.gz -o release.tar.gz HEAD
```

## Altri file di progetto che non appartengono al webroot

La cartella `.git` è l'esempio più noto, ma non l'unico. Chi distribuisce intere directory di progetto porta nel webroot altri file che lì non hanno nulla da fare:

- Cartelle di ambienti di sviluppo come `.idea` o `.vscode`, in cui le estensioni per l'upload dei file salvano talvolta indirizzi dei server e credenziali.
- `composer.json` e `composer.lock`, che rivelano le versioni esatte di tutte le librerie e facilitano così la ricerca di vulnerabilità note.
- Configurazioni per test, strumenti di build e pipeline, che rivelano hostname e procedure interne.
- Residui di sistemi operativi come `.DS_Store`, che contengono gli elenchi dei file di intere directory.

La soluzione è la stessa della cartella `.git`: fornire solo ciò che deve essere pubblico, idealmente tramite una sottocartella propria come webroot. Chi comunque passa il deployment a pacchetti stabilisce subito un elenco di file esclusi e lo verifica a ogni nuovo strumento nel progetto.

## Se la cartella era aperta: verificare cronologia e log

Se risulta che la cartella `.git` era raggiungibile, proceda in quest'ordine:

1. **Bloccare l'accesso** e ripetere la verifica.
2. **Cercare nella cronologia** quali segreti siano mai stati committati: file di configurazione, `.env`, chiavi, dump del database.
3. **Sostituire le credenziali**, tutte quelle trovate nel passo 2, anche se oggi non compaiono più nel codice.
4. **Analizzare i log di accesso**, per vedere se file sotto `/.git/` siano stati richiamati con stato 200 e da quali indirizzi. Come si fa lo mostra [Analizzare i log del server web dopo un attacco](https://phpsos.de/it/ratgeber/logfiles-auswerten/).
5. **Verificare il codice sorgente in modo mirato**, perché gli aggressori ora lo conoscono. Le debolezze note andrebbero risolte con priorità.
6. **Chiarire la protezione dei dati**, se nella cronologia c'erano dati personali, ad esempio esportazioni di test. La valutazione spetta al suo responsabile della protezione dei dati.

Gli strumenti per cercare segreti nei repository appartengono poi stabilmente alla pipeline. OWASP raccomanda espressamente tali verifiche, come hook prima del commit e nella CI.

## Come aiuta concretamente PHP SOS?

- Verifichiamo tutti i suoi domini e sottodomini alla ricerca di cartelle del controllo di versione raggiungibili.
- Blocchiamo subito l'accesso e passiamo il deployment a pacchetti senza dati di versione.
- Cerchiamo segreti nella cronologia e accompagniamo la sostituzione degli accessi interessati.
- Analizziamo i log di accesso e documentiamo se e quando i dati sono stati richiamati.

Queste misure fanno parte del nostro [hardening del server per server web PHP](https://phpsos.de/it/leistungen/server-haertung/).


## Domande frequenti

**Come nasce una cartella .git pubblica?**  
Di solito da un deployment con git clone o git pull direttamente nel webroot. La cartella .git con l'intera cronologia delle versioni si trova allora accanto a index.php e, senza un blocco, il server web ne fornisce i file.

**Basta cancellare la cartella .git?**  
Per il futuro sì, per il passato no. Se la cartella era raggiungibile, il contenuto può essere già stato copiato. Le credenziali che in qualsiasi momento si trovavano nel repository andrebbero quindi sostituite.

**Serve rimuovere a posteriori le credenziali dalla cronologia di Git?**  
Evita che le nuove copie le contengano. Chi ha già scaricato il repository possiede ancora le vecchie versioni. Decisiva è quindi la sostituzione delle credenziali, non solo la riscrittura della cronologia.

**Riguarda anche altri sistemi di controllo di versione?**  
Sì. Anche cartelle come .svn o .hg contengono dati di progetto e non dovrebbero mai essere raggiungibili nel webroot. Un blocco generale per file e cartelle con il punto iniziale copre tutti questi casi.

## Fonti

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Documentazione di Nginx](https://nginx.org/en/docs/)
- [Apache HTTP Server: documentazione](https://httpd.apache.org/docs/)
