Pe scurt: Un director .git public apare când un site este distribuit prin git clone sau git pull direct în webroot, iar serverul web nu blochează directoarele ascunse. Atunci se poate prelua întregul cod sursă împreună cu istoricul versiunilor, inclusiv datele de acces incluse mai demult în depozit. Verificați-vă domeniile cu un simplu apel, blocați imediat accesul, treceți deployment-ul la pachete fără .git și înlocuiți datele de acces din istoric.
Codul sursă de luat acasă
Git este instrumentul standard pentru controlul versiunilor, iar pentru echipele mici este firesc să fie folosit și la distribuire: conectare la server, git pull, gata. Funcționează fiabil și este rapid. Are însă un efect secundar pe care adesea nu-l observă nimeni.
În directorul proiectului se află un director ascuns .git. Acesta conține nu doar starea actuală, ci fiecare fișier în fiecare versiune care a fost vreodată inclusă, plus mesajele de commit, numele și adresele de e-mail ale dezvoltatorilor și trimiteri către servere. Dacă acest director se află în webroot și serverul web îl livrează, oricine îl poate prelua.
Pentru atacatori este un cadou. Cu codul sursă se pot căuta vulnerabilități în mod țintit, în loc să fie ghicite din exterior. Iar în istoric se găsesc adesea lucruri care păreau demult șterse: o parolă de bază de date din perioada de început, o cheie API, un fișier de test cu date ale clienților.
Este directorul dumneavoastră .git public? Cum verificați
Verificarea durează secunde și nu modifică nimic. Apelați pentru fiecare domeniu și subdomeniu un fișier care există în orice depozit Git:
# Așteptat: 403 sau 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
# Pe server: există directoare .git sub webroot-uri?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
Un status 200 înseamnă: directorul este accesibil. Fiți atenți și la subdirectoare. Uneori depozitul nu se află în webroot însuși, ci într-un director de plugin sau de temă, întreținut separat prin Git.
Verificați în plus mediile de staging și de test. Ele sunt actualizate mai des prin Git decât producția și sunt adesea accesibile sub subdomenii ușor de ghicit.
Imediat: blocarea accesului
Până la schimbarea deployment-ului, o regulă în serverul web blochează accesul la directoarele sistemelor de control al versiunilor. O blocare generală pentru fișierele ascunse, așa cum este descrisă în Protejarea corectă a datelor de acces și a fișierelor .env, acoperă și acest caz. Cine vrea să blocheze țintit doar controlul versiunilor folosește o regulă mai îngustă:
location ~ /\.(git|svn|hg)(/|$) {
return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)
Apoi repetați verificarea de mai sus, și anume cu un apel real din exterior: un test de configurare reușit spune doar că sintaxa este corectă, nu că regula acționează înaintea altor reguli pentru fișiere statice. La panouri precum Plesk sau cPanel, înscrieți regula în directivele suplimentare prevăzute pentru aceasta, pentru ca ea să nu se piardă la următoarea generare a configurării.
Dacă directorul a fost accesibil, tratați toate datele de acces care au fost vreodată în depozit drept cunoscute. Blocarea singură nu este atunci suficientă, valorile trebuie înlocuite.
Durabil: distribuire fără .git în webroot
Blocarea este o securizare, nu o soluție. Durabil, controlul versiunilor nu aparține pe serverul de producție. Căi dovedite, în funcție de mediul dumneavoastră:
| Procedeu | Cum funcționează | Potrivit pentru |
|---|---|---|
| Pachet de build din CI | Pipeline-ul construiește o arhivă fără .git, serverul o dezarhivează într-un director de release nou |
Echipe cu CI/CD |
git archive |
Generează o arhivă a unei stări, fără date de versiune | Proiecte mici fără pipeline |
rsync cu excluderi |
Transferă doar fișierele necesare | Servere clasice |
| Imagine de container | Codul este copiat în imagine la build, .git exclus prin .dockerignore |
Operare cu containere |
Un director de release pentru fiecare versiune, cu un link simbolic spre starea curentă, are un alt avantaj: la probleme puteți reveni imediat. Pentru configurațiile cu containere, CI/CD: reconstruirea automată a imaginilor PHP descrie cum devin build-urile reproductibile. Acolo ar trebui verificat și că .git nu ajunge în imagine.
# Exemplu: generați un pachet al unei stări, fără date de versiune
git archive --format=tar.gz -o release.tar.gz HEAD
Alte fișiere de proiect care nu aparțin în webroot
Directorul .git este exemplul cel mai cunoscut, dar nu singurul. Cine distribuie directoare întregi de proiect aduce în webroot alte fișiere care nu au ce căuta acolo:
- Directoare ale mediilor de dezvoltare, precum
.ideasau.vscode, în care extensiile pentru încărcarea fișierelor stochează uneori adrese de server și date de acces. composer.jsonșicomposer.lock, care trădează versiunile exacte ale tuturor bibliotecilor și ușurează astfel căutarea vulnerabilităților cunoscute.- Configurări pentru teste, instrumente de build și pipeline-uri, care dezvăluie nume de host interne și procese.
- Resturi ale sistemelor de operare precum
.DS_Store, care conțin liste de fișiere ale unor directoare întregi.
Soluția este aceeași ca la directorul .git: livrați doar ce trebuie să fie public, ideal printr-un subdirector propriu ca webroot. Cine oricum trece deployment-ul la pachete stabilește pe loc o listă de fișiere excluse și o verifică la fiecare instrument nou din proiect.
Dacă directorul a fost deschis: verificarea istoricului și a jurnalelor
Dacă se dovedește că directorul .git a fost accesibil, procedați în această ordine:
- Blocați accesul și repetați verificarea.
- Căutați în istoric ce secrete au fost vreodată incluse: fișiere de configurare,
.env, chei, dump-uri de baze de date. - Înlocuiți datele de acces, și anume toate cele găsite la pasul 2, chiar dacă astăzi nu mai apar în cod.
- Analizați jurnalele de acces pentru a vedea dacă fișiere de sub
/.git/au fost accesate cu status 200 și de la ce adrese. Cum se face arată Analiza jurnalelor serverului web după un atac. - Verificați țintit codul sursă, deoarece atacatorii îl cunosc acum. Slăbiciunile cunoscute ar trebui remediate prioritar.
- Clarificați protecția datelor, dacă în istoric au existat date cu caracter personal, de exemplu exporturi de test. Evaluarea o preia responsabilul dumneavoastră cu protecția datelor.
Instrumentele pentru căutarea secretelor în depozite aparțin după aceea durabil în pipeline. OWASP recomandă explicit asemenea verificări, ca hook înainte de includere și în CI.
Cum ajută PHP SOS concret?
- Verificăm toate domeniile și subdomeniile dumneavoastră pentru directoare accesibile ale controlului versiunilor.
- Blocăm imediat accesul și trecem deployment-ul la pachete fără date de versiune.
- Căutăm în istoric secrete și însoțim înlocuirea accesărilor afectate.
- Analizăm jurnalele de acces și documentăm dacă și când au fost preluate date.
Aceste măsuri fac parte din întărirea serverului pentru servere web PHP oferită de noi.
Întrebări frecvente
Cum apare un director .git public?
De regulă printr-un deployment cu git clone sau git pull direct în webroot. Directorul .git cu întreg istoricul versiunilor se află atunci lângă index.php, iar fără blocare serverul web livrează fișierele sale.
Este suficient să șterg directorul .git?
Pentru viitor, da, pentru trecut, nu. Dacă directorul a fost accesibil, conținutul poate fi deja copiat. Datele de acces care au apărut vreodată în depozit ar trebui de aceea înlocuite.
Ajută eliminarea ulterioară a datelor de acces din istoricul Git?
Împiedică noile copii să le conțină. Cine a preluat deja depozitul deține în continuare stările vechi. Hotărâtoare este de aceea înlocuirea datelor de acces, nu doar rescrierea istoricului.
Privește acest lucru și alte sisteme de control al versiunilor?
Da. Și directoare precum .svn sau .hg conțin date ale proiectului și nu ar trebui să fie niciodată accesibile în webroot. O blocare generală pentru fișierele și directoarele cu punct la început acoperă toate aceste cazuri.