Trenutno stanje: PHP2Shell. Dvije kritične PHP ranjivosti (CVSS 9.2) omogućuju zlonamjerni kod bez prijave. Zakrpe od 21. 10. 2026.Što sada učiniti →

Javni .git direktorij: podcijenjeno curenje podataka

Zašto webroot isporučen putem Gita može otkriti cijeli izvorni kod zajedno s poviješću, kako to provjeriti, odmah blokirati i trajno izgraditi isporuku bez .git direktorija.

Stanje 5 min čitanjaSiguran razvoj

Ukratko: Javni .git direktorij nastaje kad se web-stranica isporučuje pomoću git clone ili git pull izravno u webroot, a web-poslužitelj ne blokira skrivene direktorije. Tada se može dohvatiti cijeli izvorni kod zajedno s poviješću verzija, uključujući ranije unesene pristupne podatke. Svoje domene provjerite jednostavnim pozivom, odmah blokirajte pristup, isporuku prebacite na pakete bez .git i zamijenite pristupne podatke iz povijesti.

Izvorni kod za ponijeti

Git je standardni alat za upravljanje verzijama, a malim je timovima prirodno da se njime i isporučuje: spojiti se na poslužitelj, git pull, gotovo. To radi pouzdano i brzo. Ima ipak nuspojavu koju često nitko ne primijeti.

U direktoriju projekta leži skriveni direktorij .git. On ne sadrži samo trenutačno stanje, nego svaku datoteku u svakoj verziji koja je ikada unesena, uz to poruke commitova, imena i adrese e-pošte razvojnih inženjera te reference na poslužitelje. Ako taj direktorij leži u webrootu i web-poslužitelj ga isporučuje, svatko ga može dohvatiti.

Za napadače je to dar. S izvornim kodom ranjivosti se mogu ciljano tražiti umjesto da ih se pogađa izvana. A u povijesti se često nalaze stvari koje su se činile davno obrisanima: lozinka baze podataka iz početnog razdoblja, API ključ, testna datoteka s podacima kupaca.

Je li Vaš .git direktorij javan? Kako to provjeriti

Provjera traje sekunde i ništa ne mijenja. Za svaku domenu i poddomenu pozovite datoteku koja postoji u svakom Git repozitoriju:

# Očekuje se: 403 ili 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
# Na poslužitelju: postoje li .git direktoriji ispod webroota?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null

Status 200 znači: direktorij je dostupan. Obratite pažnju i na poddirektorije. Ponekad repozitorij ne leži u samom webrootu, nego u direktoriju dodatka ili teme koji se zasebno održava putem Gita.

Provjerite i staging i testna okruženja. Ona se putem Gita ažuriraju češće od produkcije i često su dostupna na poddomenama koje se mogu pogoditi.

Odmah: blokirati pristup

Dok isporuka nije preuređena, pravilo u web-poslužitelju blokira pristup direktorijima sustava za verzioniranje. Opća blokada skrivenih datoteka, kako je opisano u članku Ispravno zaštititi pristupne podatke i .env datoteke, to također pokriva. Tko želi ciljano blokirati samo sustav za verzioniranje, koristi uže pravilo:

location ~ /\.(git|svn|hg)(/|$) {
    return 404;
}
RedirectMatch 404 /\.(git|svn|hg)(/|$)

Zatim ponovite gornju provjeru, i to pravim pozivom izvana: uspješan test konfiguracije govori samo da je sintaksa ispravna, a ne da pravilo djeluje prije drugih pravila za statične datoteke. Kod panela poput Plesk-a ili cPanela pravilo upišite u predviđene dodatne direktive, kako se ne bi izgubilo pri sljedećem generiranju konfiguracije.

Djelujte odmah

Ako je direktorij bio dostupan, sve pristupne podatke koji su ikada bili u repozitoriju tretirajte kao poznate. Sama blokada tada nije dovoljna, vrijednosti se moraju zamijeniti.

Trajno: isporučivati bez .git u webrootu

Blokada je zaštita, a ne rješenje. Trajno sustav za verzioniranje ne pripada na produkcijski poslužitelj. Dokazani putevi, ovisno o Vašem okruženju:

Postupak Kako radi Prikladno za
Build paket iz CI-ja pipeline gradi arhivu bez .git, poslužitelj je raspakira u novi direktorij izdanja timovi s CI/CD-om
git archive stvara arhivu stanja bez podataka o verzijama mali projekti bez pipelinea
rsync s isključenjima prenosi samo potrebne datoteke klasični poslužitelji
Container image kod se pri gradnji kopira u image, .git isključen pomoću .dockerignore rad s containerima

Direktorij izdanja po verziji sa simboličkom vezom na aktualno stanje ima još jednu prednost: pri problemima možete odmah vratiti staro. Za container postavke članak CI/CD: automatski ponovno graditi PHP imageove opisuje kako buildovi postaju ponovljivi. Tamo treba provjeriti i da .git ne dospije u image.

# Primjer: izraditi paket stanja bez podataka o verzijama
git archive --format=tar.gz -o release.tar.gz HEAD

Daljnje datoteke projekta koje ne pripadaju u webroot

Direktorij .git najpoznatiji je primjer, ali ne i jedini. Tko isporučuje cijele direktorije projekta, u webroot donosi i druge datoteke koje tamo nemaju što tražiti:

  • Direktoriji razvojnih okruženja poput .idea ili .vscode, u kojima proširenja za upload datoteka ponekad spremaju adrese poslužitelja i pristupne podatke.
  • composer.json i composer.lock, koji otkrivaju točne verzije svih biblioteka i time olakšavaju potragu za poznatim ranjivostima.
  • Konfiguracije za testove, alate za build i pipelineove, koje otkrivaju interne nazive hostova i postupke.
  • Ostaci operacijskih sustava poput .DS_Store, koji sadrže popise datoteka cijelih direktorija.

Rješenje je isto kao kod direktorija .git: isporučivati samo ono što mora biti javno, idealno preko vlastitog poddirektorija kao webroota. Tko isporuku ionako prebacuje na pakete, odmah utvrđuje popis isključenih datoteka i provjerava ga uz svaki novi alat u projektu.

Ako je direktorij bio otvoren: provjeriti povijest i zapisnike

Ako se pokaže da je direktorij .git bio dostupan, postupajte ovim redom:

  1. Blokirati pristup i ponoviti provjeru.
  2. Pretražiti povijest koje su tajne ikada unesene: konfiguracijske datoteke, .env, ključevi, dumpovi baza podataka.
  3. Zamijeniti pristupne podatke, i to sve koje ste našli u koraku 2, čak i ako danas više nisu u kodu.
  4. Analizirati pristupne zapisnike jesu li datoteke pod /.git/ dohvaćane sa statusom 200 i s kojih adresa. Kako to ide, pokazuje Analizirati zapisnike web-poslužitelja nakon napada.
  5. Ciljano provjeriti izvorni kod, jer ga napadači sada poznaju. Poznate slabosti treba prioritetno otkloniti.
  6. Razjasniti zaštitu podataka, ako su u povijesti bili osobni podaci, primjerice testni izvozi. Procjenu preuzima Vaš službenik za zaštitu podataka.

Alati za traženje tajni u repozitorijima nakon toga trajno pripadaju u pipeline. OWASP takve provjere izričito preporučuje, kao hook prije unosa i u CI-ju.

Kako PHP SOS konkretno pomaže?

  • Provjeravamo sve Vaše domene i poddomene u potrazi za dostupnim direktorijima sustava za verzioniranje.
  • Pristup blokiramo odmah i isporuku prebacujemo na pakete bez podataka o verzijama.
  • Pretražujemo povijest u potrazi za tajnama i pratimo zamjenu pogođenih pristupa.
  • Analiziramo pristupne zapisnike i dokumentiramo jesu li i kada podaci dohvaćani.

Ove mjere dio su našeg ojačavanja poslužitelja za PHP web-poslužitelje.

Česta pitanja

Kako nastaje javni .git direktorij?

Najčešće isporukom putem git clone ili git pull izravno u webrootu. Direktorij .git s cijelom poviješću verzija tada leži pokraj index.php, a bez blokade web-poslužitelj isporučuje njegove datoteke.

Je li dovoljno obrisati .git direktorij?

Za budućnost da, za prošlost ne. Ako je direktorij bio dostupan, sadržaj je možda već kopiran. Pristupne podatke koji su ikada bili u repozitoriju zato biste trebali zamijeniti.

Pomaže li naknadno ukloniti pristupne podatke iz Git povijesti?

Sprječava da nove kopije sadrže te podatke. Tko je repozitorij već dohvatio, i dalje posjeduje stara stanja. Odlučujuća je stoga zamjena pristupnih podataka, a ne samo prepisivanje povijesti.

Pogađa li to i druge sustave za verzioniranje?

Da. I direktoriji poput .svn ili .hg sadrže podatke projekta i nikad ne bi smjeli biti dostupni u webrootu. Opća blokada datoteka i direktorija s točkom na početku pokriva sve te slučajeve.

Izvori

Hitni kontakt

Svaki sat se računa. Pišite nam odmah.

Ukratko opišite sustav, verziju PHP-a i opažanje. Javit ćemo Vam se, razjasniti situaciju i raditi na daljinu dok incident nije zaključen i dokumentiran.

Hitna pomoć